From 6b3d8e134ab923ddbfa4f138963bb71ef0f1a68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Wed, 1 Oct 2003 12:08:53 +0000 Subject: [PATCH] Implemented _NET_MOVERESIZE_WINDOW. Moved KWin code related to configure request to geometry.cpp to a common function. svn path=/trunk/kdebase/kwin/; revision=255355 --- client.cpp | 66 ------------------- client.h | 4 +- events.cpp | 98 +++------------------------- geometry.cpp | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++ workspace.cpp | 1 + workspace.h | 1 + 6 files changed, 190 insertions(+), 156 deletions(-) diff --git a/client.cpp b/client.cpp index dc896e8521..aa5509cc77 100644 --- a/client.cpp +++ b/client.cpp @@ -313,72 +313,6 @@ void Client::checkBorderSizes() setGeometry( geometry(), true ); } -const QPoint Client::calculateGravitation( bool invert ) const - { - int gravity, dx, dy; - dx = dy = 0; - - gravity = NorthWestGravity; - if ( xSizeHint.flags & PWinGravity) - gravity = xSizeHint.win_gravity; -// dx, dy specify how the client window moves to make space for the frame - switch (gravity) - { - case NorthWestGravity: // move down right - dx = border_left; - dy = border_top; - break; - case NorthGravity: // move right - dx = 0; - dy = border_top; - break; - case NorthEastGravity: // move down left - dx = -border_right; - dy = border_top; - break; - case WestGravity: // move right - dx = border_left; - dy = 0; - break; - case CenterGravity: - break; // will be handled specially - case StaticGravity: // don't move - dx = 0; - dy = 0; - break; - case EastGravity: // move left - dx = -border_right; - dy = 0; - break; - case SouthWestGravity: // move up right - dx = border_left ; - dy = -border_bottom; - break; - case SouthGravity: // move up - dx = 0; - dy = -border_bottom; - break; - case SouthEastGravity: // move up left - dx = -border_right; - dy = -border_bottom; - break; - } - if( gravity != CenterGravity ) - { // translate from client movement to frame movement - dx -= border_left; - dy -= border_top; - } - else - { // center of the frame will be at the same position client center without frame would be - dx = - ( width() - clientSize().width()) / 2; - dy = - ( height() - clientSize().height()) / 2; - } - if( !invert ) - return QPoint( x() + dx, y() + dy ); - else - return QPoint( x() - dx, y() - dy ); - } - void Client::detectNoBorder() { if( Shape::hasShape( window()) || Motif::noBorder( window())) diff --git a/client.h b/client.h index 94a6c989fe..5f639046f5 100644 --- a/client.h +++ b/client.h @@ -225,9 +225,10 @@ class Client : public QObject, public KDecorationDefines void keyPressEvent( uint key_code ); // FRAME ?? - const QPoint calculateGravitation( bool invert ) const; // FRAME public? + const QPoint calculateGravitation( bool invert, int gravity = 0 ) const; // FRAME public? void NETMoveResize( int x_root, int y_root, NET::Direction direction ); + void NETMoveResizeWindow( int flags, int x, int y, int width, int height ); void restackWindow( Window above, int detail, NET::RequestSource source, bool send_event = false ); void gotPing( Time timestamp ); @@ -323,6 +324,7 @@ class Client : public QObject, public KDecorationDefines void updateWorkareaDiffs( const QRect& area = QRect()); void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area ); static int computeWorkareaDiff( int left, int right, int a_left, int a_right ); + void configureRequest( int value_mask, int rx, int ry, int rw, int rh, int gravity = 0 ); bool startMoveResize(); void finishMoveResize( bool cancel ); diff --git a/events.cpp b/events.cpp index b99709e8cc..a4f4c809f6 100644 --- a/events.cpp +++ b/events.cpp @@ -137,6 +137,13 @@ void RootInfo::moveResize(Window w, int x_root, int y_root, unsigned long direct } } +void RootInfo::moveResizeWindow(Window w, int flags, int x, int y, int width, int height ) + { + Client* c = workspace->findClient( WindowMatchPredicate( w )); + if ( c ) + c->NETMoveResizeWindow( flags, x, y, width, height ); + } + void RootInfo::gotPing( Window w, Time timestamp ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) @@ -672,9 +679,6 @@ void Client::configureRequestEvent( XConfigureRequestEvent* e ) return; } - if ( isShade() ) // SELI SHADE - setShade( ShadeNone ); - if ( e->value_mask & CWBorderWidth ) { // first, get rid of a window border @@ -686,92 +690,8 @@ void Client::configureRequestEvent( XConfigureRequestEvent* e ) XConfigureWindow( qt_xdisplay(), window(), value_mask, & wc ); } - if ( e->value_mask & (CWX | CWY ) ) - { - int ox = 0; - int oy = 0; - // GRAVITATE - int gravity = NorthWestGravity; - if ( xSizeHint.flags & PWinGravity) - gravity = xSizeHint.win_gravity; - if ( gravity == StaticGravity ) - { // only with StaticGravity according to ICCCM 4.1.5 - ox = clientPos().x(); - oy = clientPos().y(); - } - - int nx = x() + ox; - int ny = y() + oy; - - if ( e->value_mask & CWX ) - nx = e->x; - if ( e->value_mask & CWY ) - ny = e->y; - - - // clever workaround for applications like xv that want to set - // the location to the current location but miscalculate the - // frame size due to kwin being a double-reparenting window - // manager - if ( ox == 0 && oy == 0 && - nx == x() + clientPos().x() && - ny == y() + clientPos().y() ) - { - nx = x(); - ny = y(); - } - - - QPoint np( nx-ox, ny-oy); -#if 0 - if ( windowType() == NET::Normal && isMovable()) - { - // crap for broken netscape - QRect area = workspace()->clientArea(); - if ( !area.contains( np ) && width() < area.width() && - height() < area.height() ) - { - if ( np.x() < area.x() ) - np.rx() = area.x(); - if ( np.y() < area.y() ) - np.ry() = area.y(); - } - } -#endif - - if ( maximizeMode() != MaximizeFull ) - { - resetMaximize(); - move( np ); - } - } - - if ( e->value_mask & (CWWidth | CWHeight ) ) - { - int nw = clientSize().width(); - int nh = clientSize().height(); - if ( e->value_mask & CWWidth ) - nw = e->width; - if ( e->value_mask & CWHeight ) - nh = e->height; - QSize ns = sizeForClientSize( QSize( nw, nh ) ); - - //QRect area = workspace()->clientArea(); - if ( maximizeMode() != MaximizeRestore ) - { //&& ( ns.width() < area.width() || ns.height() < area.height() ) ) { - if( ns != size()) - { // don't restore if some app sets its own size again - resetMaximize(); - resize( ns ); - } - } - else - { - if ( ns == size() ) - return; // broken xemacs stuff (ediff) - resize( ns ); - } - } + if( e->value_mask & ( CWX | CWY | CWHeight | CWWidth )) + configureRequest( e->value_mask, e->x, e->y, e->width, e->height ); if ( e->value_mask & CWStackMode ) restackWindow( e->above, e->detail, NET::FromApplication ); diff --git a/geometry.cpp b/geometry.cpp index 5b7129a2be..00f8eb9269 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -741,6 +741,8 @@ void Client::getWmNormalHints() xSizeHint.max_aspect.x = INT_MAX; xSizeHint.max_aspect.y = 1; } + if( !xSizeHint.flags & PWinGravity ) + xSizeHint.win_gravity = NorthWestGravity; if( isManaged()) { // update to match restrictions QSize new_size = adjustedSize( size()); @@ -772,6 +774,180 @@ void Client::sendSyntheticConfigureNotify() XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c ); } +const QPoint Client::calculateGravitation( bool invert, int gravity ) const + { + int dx, dy; + dx = dy = 0; + + if( gravity == 0 ) // default (nonsense) value for the argument + gravity = xSizeHint.win_gravity; + +// dx, dy specify how the client window moves to make space for the frame + switch (gravity) + { + case NorthWestGravity: // move down right + dx = border_left; + dy = border_top; + break; + case NorthGravity: // move right + dx = 0; + dy = border_top; + break; + case NorthEastGravity: // move down left + dx = -border_right; + dy = border_top; + break; + case WestGravity: // move right + dx = border_left; + dy = 0; + break; + case CenterGravity: + break; // will be handled specially + case StaticGravity: // don't move + dx = 0; + dy = 0; + break; + case EastGravity: // move left + dx = -border_right; + dy = 0; + break; + case SouthWestGravity: // move up right + dx = border_left ; + dy = -border_bottom; + break; + case SouthGravity: // move up + dx = 0; + dy = -border_bottom; + break; + case SouthEastGravity: // move up left + dx = -border_right; + dy = -border_bottom; + break; + } + if( gravity != CenterGravity ) + { // translate from client movement to frame movement + dx -= border_left; + dy -= border_top; + } + else + { // center of the frame will be at the same position client center without frame would be + dx = - ( width() - clientSize().width()) / 2; + dy = - ( height() - clientSize().height()) / 2; + } + if( !invert ) + return QPoint( x() + dx, y() + dy ); + else + return QPoint( x() - dx, y() - dy ); + } + +void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, int gravity ) + { + if( gravity == 0 ) // default (nonsense) value for the argument + gravity = xSizeHint.win_gravity; + if( value_mask & ( CWX | CWY )) + { + if ( isShade()) // SELI SHADE + setShade( ShadeNone ); + + int ox = 0; + int oy = 0; + // GRAVITATE + if ( gravity == StaticGravity ) + { // only with StaticGravity according to ICCCM 4.1.5 + ox = clientPos().x(); + oy = clientPos().y(); + } + + int nx = x() + ox; + int ny = y() + oy; + + if ( value_mask & CWX ) + nx = rx; + if ( value_mask & CWY ) + ny = ry; + + + // clever workaround for applications like xv that want to set + // the location to the current location but miscalculate the + // frame size due to kwin being a double-reparenting window + // manager + if ( ox == 0 && oy == 0 && + nx == x() + clientPos().x() && + ny == y() + clientPos().y() ) + { + nx = x(); + ny = y(); + } + + + QPoint np( nx-ox, ny-oy); +#if 0 + if ( windowType() == NET::Normal && isMovable()) + { + // crap for broken netscape + QRect area = workspace()->clientArea(); + if ( !area.contains( np ) && width() < area.width() && + height() < area.height() ) + { + if ( np.x() < area.x() ) + np.rx() = area.x(); + if ( np.y() < area.y() ) + np.ry() = area.y(); + } + } +#endif + + if ( maximizeMode() != MaximizeFull ) + { + resetMaximize(); + move( np ); + } + } + + if ( value_mask & (CWWidth | CWHeight ) ) + { + int nw = clientSize().width(); + int nh = clientSize().height(); + if ( value_mask & CWWidth ) + nw = rw; + if ( value_mask & CWHeight ) + nh = rh; + QSize ns = sizeForClientSize( QSize( nw, nh ) ); + + //QRect area = workspace()->clientArea(); + if ( maximizeMode() != MaximizeRestore ) + { //&& ( ns.width() < area.width() || ns.height() < area.height() ) ) { + if( ns != size()) + { // don't restore if some app sets its own size again + resetMaximize(); + resize( ns ); + } + } + else + { + if ( ns == size() ) + return; // broken xemacs stuff (ediff) + resize( ns ); + } + } + } + +// _NET_MOVERESIZE_WINDOW +void Client::NETMoveResizeWindow( int flags, int x, int y, int width, int height ) + { + int gravity = flags & 0xff; + int value_mask = 0; + if( flags & ( 1 << 8 )) + value_mask |= CWX; + if( flags & ( 1 << 9 )) + value_mask |= CWY; + if( flags & ( 1 << 10 )) + value_mask |= CWWidth; + if( flags & ( 1 << 11 )) + value_mask |= CWHeight; + configureRequest( value_mask, x, y, width, height, gravity ); + } + /*! Returns whether the window is resizable or has a fixed size. */ diff --git a/workspace.cpp b/workspace.cpp index 28f8704e97..e3da9ecb31 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -233,6 +233,7 @@ void Workspace::init() NET::WM2StartupId | NET::WM2AllowedActions | NET::WM2RestackWindow | + NET::WM2MoveResizeWindow | 0 , NET::ActionMove | diff --git a/workspace.h b/workspace.h index f7420914c2..9f835fdf6c 100644 --- a/workspace.h +++ b/workspace.h @@ -568,6 +568,7 @@ class RootInfo : public NETRootInfo2 virtual void changeActiveWindow(Window w,NET::RequestSource src, Time timestamp); virtual void closeWindow(Window w); virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction); + virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height ); virtual void gotPing(Window w, Time timestamp); virtual void restackWindow(Window w, Window above, int detail); private: