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
This commit is contained in:
parent
ca3a1382f2
commit
6b3d8e134a
6 changed files with 190 additions and 156 deletions
66
client.cpp
66
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()))
|
||||
|
|
4
client.h
4
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 );
|
||||
|
|
98
events.cpp
98
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 );
|
||||
|
|
176
geometry.cpp
176
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.
|
||||
*/
|
||||
|
|
|
@ -233,6 +233,7 @@ void Workspace::init()
|
|||
NET::WM2StartupId |
|
||||
NET::WM2AllowedActions |
|
||||
NET::WM2RestackWindow |
|
||||
NET::WM2MoveResizeWindow |
|
||||
0
|
||||
,
|
||||
NET::ActionMove |
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue