2009-08-24 16:17:15 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nitrogensizegrip.cpp
|
|
|
|
// -------------------
|
|
|
|
//
|
2009-08-25 04:15:13 +00:00
|
|
|
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
2009-08-24 16:17:15 +00:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2009-08-22 08:24:06 +00:00
|
|
|
|
|
|
|
#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 )
|
|
|
|
{
|
|
|
|
|
2009-09-01 14:05:56 +00:00
|
|
|
setAttribute(Qt::WA_NoSystemBackground );
|
|
|
|
setAutoFillBackground( false );
|
|
|
|
|
2009-08-22 08:24:06 +00:00
|
|
|
// cursor
|
|
|
|
setCursor( Qt::SizeFDiagCursor );
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
updatePosition();
|
|
|
|
|
|
|
|
// event filter
|
|
|
|
client->widget()->installEventFilter( this );
|
|
|
|
|
|
|
|
// show
|
|
|
|
show();
|
|
|
|
|
|
|
|
}
|
|
|
|
//_____________________________________________
|
|
|
|
NitrogenSizeGrip::~NitrogenSizeGrip( void )
|
|
|
|
{}
|
|
|
|
|
|
|
|
//_____________________________________________
|
2009-09-01 14:05:56 +00:00
|
|
|
void NitrogenSizeGrip::activeChange( void )
|
|
|
|
{ XMapRaised( QX11Info::display(), winId() ); }
|
2009-08-22 08:24:06 +00:00
|
|
|
|
|
|
|
//_____________________________________________
|
|
|
|
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* )
|
|
|
|
{
|
|
|
|
|
|
|
|
// get relevant colors
|
2009-09-01 14:05:56 +00:00
|
|
|
QColor base( palette().brush( (client().isActive() ) ? QPalette::Active : QPalette::Inactive, QPalette::Button ).color() );
|
2009-08-22 08:24:06 +00:00
|
|
|
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 );
|
|
|
|
|
2009-09-01 14:05:56 +00:00
|
|
|
if( client().isPreview() )
|
|
|
|
{
|
2009-08-24 16:17:15 +00:00
|
|
|
|
2009-09-01 14:05:56 +00:00
|
|
|
position -= QPoint(
|
2009-09-02 04:26:59 +00:00
|
|
|
client().layoutMetric( NitrogenClient::LM_BorderRight )+
|
|
|
|
client().layoutMetric( NitrogenClient::LM_OuterPaddingRight ),
|
|
|
|
client().layoutMetric( NitrogenClient::LM_OuterPaddingBottom )+
|
|
|
|
client().layoutMetric( NitrogenClient::LM_BorderBottom )
|
|
|
|
);
|
2009-09-01 14:05:56 +00:00
|
|
|
|
|
|
|
} else if( decoration_offset_ ) {
|
|
|
|
|
|
|
|
// not sure whether this case still happens or not
|
|
|
|
position -= QPoint(
|
|
|
|
client().layoutMetric( NitrogenClient::LM_BorderLeft )+client().layoutMetric( NitrogenClient::LM_BorderRight ),
|
|
|
|
client().layoutMetric( NitrogenClient::LM_TitleHeight )+client().layoutMetric( NitrogenClient::LM_TitleEdgeTop )+client().layoutMetric( NitrogenClient::LM_TitleEdgeBottom )+client().layoutMetric( NitrogenClient::LM_BorderBottom ) );
|
2009-08-22 08:24:06 +00:00
|
|
|
|
2009-09-01 14:05:56 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
position -= QPoint(
|
|
|
|
client().layoutMetric( NitrogenClient::LM_BorderRight ),
|
|
|
|
client().layoutMetric( NitrogenClient::LM_BorderBottom ) );
|
2009-08-22 08:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
move( position );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-08-24 06:27:49 +00:00
|
|
|
}
|