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:
Luboš Luňák 2003-10-01 12:08:53 +00:00
parent ca3a1382f2
commit 6b3d8e134a
6 changed files with 190 additions and 156 deletions

View file

@ -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()))

View file

@ -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 );

View file

@ -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 );

View file

@ -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.
*/

View file

@ -233,6 +233,7 @@ void Workspace::init()
NET::WM2StartupId |
NET::WM2AllowedActions |
NET::WM2RestackWindow |
NET::WM2MoveResizeWindow |
0
,
NET::ActionMove |

View file

@ -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: