kwin/clients/nitrogen/nitrogensizegrip.cpp

256 lines
7.1 KiB
C++
Raw Normal View History

//////////////////////////////////////////////////////////////////////////////
// nitrogensizegrip.cpp
// -------------------
//
// Copyright (c) 2009, 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <QPainter>
#include <QPolygon>
#include <QTimer>
#include <kdeversion.h>
#include "nitrogenbutton.h"
#include "nitrogenclient.h"
#include "nitrogensizegrip.h"
#include "x11util.h"
#include <QX11Info>
#include <X11/Xlib.h>
namespace Nitrogen
{
//_____________________________________________
NitrogenSizeGrip::NitrogenSizeGrip( NitrogenClient* client ):
QWidget( client->widget() ),
client_( client ),
decoration_offset_( false )
{
// cursor
setCursor( Qt::SizeFDiagCursor );
setAutoFillBackground( true );
// size
setFixedSize( QSize( GRIP_SIZE, GRIP_SIZE ) );
// mask
QPolygon p;
p << QPoint( 0, GRIP_SIZE )
<< QPoint( GRIP_SIZE, 0 )
<< QPoint( GRIP_SIZE, GRIP_SIZE )
<< QPoint( 0, GRIP_SIZE );
setMask( QRegion( p ) );
// embed
embed();
updateBackgroundColor();
updatePosition();
// event filter
client->widget()->installEventFilter( this );
// show
show();
}
//_____________________________________________
NitrogenSizeGrip::~NitrogenSizeGrip( void )
{}
//_____________________________________________
void NitrogenSizeGrip::updateBackgroundColor( void )
{
QPalette palette = client().widget()->palette();
// active color
palette.setCurrentColorGroup( client().isActive() ? QPalette::Active:QPalette::Inactive );
// get relevant colors
QColor base( client().configuration().overwriteColors() ?
palette.button().color().darker(250) :
client().options()->color( NitrogenClient::ColorTitleBar, client().isActive() ) );
palette.setColor( backgroundRole(), base );
setPalette( palette );
XMapRaised( QX11Info::display(), winId() );
}
//_____________________________________________
void NitrogenSizeGrip::embed( void )
{
WId window_id = client().windowId();
assert( window_id );
WId current = window_id;
while( true )
{
WId root, parent = 0;
WId *children = 0L;
uint child_count = 0;
XQueryTree(QX11Info::display(), current, &root, &parent, &children, &child_count);
if( parent && parent != root && parent != current ) current = parent;
else break;
}
// if the current window is the window_id
// (i.e. if the client is top-level)
// the decoration_offset_ flag is set to true, meaning that decoration borders
// are taken into account when placing the widget.
decoration_offset_ = ( current == window_id );
// reparent
XReparentWindow( QX11Info::display(), winId(), current, 0, 0 );
}
//_____________________________________________
bool NitrogenSizeGrip::eventFilter( QObject* object, QEvent* event )
{
if( object != client().widget() ) return false;
if ( event->type() == QEvent::Resize) updatePosition();
return false;
}
//_____________________________________________
void NitrogenSizeGrip::paintEvent( QPaintEvent* )
{
QPalette palette = client().widget()->palette();
palette.setCurrentColorGroup( (client().isActive() ) ? QPalette::Active : QPalette::Inactive );
// get relevant colors
QColor base( client().configuration().overwriteColors() ?
palette.button().color() :
client().options()->color( NitrogenClient::ColorTitleBar, client().isActive() ) );
QColor dark( base.darker(250) );
QColor light( base.darker(150) );
// create and configure painter
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing );
painter.setPen( Qt::NoPen );
painter.setBrush( base );
// polygon
QPolygon p;
p << QPoint( 0, GRIP_SIZE )
<< QPoint( GRIP_SIZE, 0 )
<< QPoint( GRIP_SIZE, GRIP_SIZE )
<< QPoint( 0, GRIP_SIZE );
painter.drawPolygon( p );
// diagonal border
painter.setBrush( Qt::NoBrush );
painter.setPen( QPen( dark, 3 ) );
painter.drawLine( QPoint( 0, GRIP_SIZE ), QPoint( GRIP_SIZE, 0 ) );
// side borders
painter.setPen( QPen( light, 1.5 ) );
painter.drawLine( QPoint( 1, GRIP_SIZE ), QPoint( GRIP_SIZE, GRIP_SIZE ) );
painter.drawLine( QPoint( GRIP_SIZE, 1 ), QPoint( GRIP_SIZE, GRIP_SIZE ) );
painter.end();
}
//_____________________________________________
void NitrogenSizeGrip::mousePressEvent( QMouseEvent* event )
{
switch (event->button())
{
case Qt::RightButton:
{
hide();
QTimer::singleShot(5000, this, SLOT(show()));
break;
}
case Qt::MidButton:
{
hide();
break;
}
case Qt::LeftButton:
if( rect().contains( event->pos() ) )
{
// check client window id
if( !client().windowId() ) break;
// get matching screen
int screen( client().widget()->x11Info().screen() );
client().widget()->setFocus();
// post event
X11Util::get().moveResizeWidget( client().windowId(), screen, event->globalPos(), X11Util::_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT );
}
break;
default: break;
}
return;
}
//_______________________________________________________________________________
void NitrogenSizeGrip::updatePosition( void )
{
QPoint position(
client().width() - GRIP_SIZE - OFFSET,
client().height() - GRIP_SIZE - OFFSET );
if( decoration_offset_ )
{
position-= QPoint( client().borderWidth(), client().borderHeight() );
} else {
position -= QPoint(
client().layoutMetric( NitrogenClient::LM_BorderRight ),
client().layoutMetric( NitrogenClient::LM_BorderBottom ) );
}
move( position );
}
}