Use functions for postponing geometry updates, rather doing
it manually all the time using setGeometry( geometry()). Needed for getting geometry of the damn shaded windows right finally. svn path=/trunk/KDE/kdebase/kwin/; revision=423506
This commit is contained in:
parent
a34f9ab748
commit
8ef2a46218
4 changed files with 100 additions and 78 deletions
34
client.cpp
34
client.cpp
|
@ -86,7 +86,8 @@ Client::Client( Workspace *ws )
|
|||
process_killer( NULL ),
|
||||
user_time( CurrentTime ), // not known yet
|
||||
allowed_actions( 0 ),
|
||||
block_geometry( 0 ),
|
||||
postpone_geometry_updates( 0 ),
|
||||
pending_geometry_update( false ),
|
||||
shade_geometry_change( false ),
|
||||
border_left( 0 ),
|
||||
border_right( 0 ),
|
||||
|
@ -162,7 +163,7 @@ Client::~Client()
|
|||
assert( client == None );
|
||||
assert( frame == None && wrapper == None );
|
||||
assert( decoration == NULL );
|
||||
assert( block_geometry == 0 );
|
||||
assert( postpone_geometry_updates == 0 );
|
||||
assert( !check_active_modal );
|
||||
delete info;
|
||||
delete bridge;
|
||||
|
@ -187,7 +188,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
if (moveResizeMode)
|
||||
leaveMoveResize();
|
||||
finishWindowRules();
|
||||
++block_geometry;
|
||||
++postpone_geometry_updates;
|
||||
setMappingState( WithdrawnState );
|
||||
setModal( false ); // otherwise its mainwindow wouldn't get focus
|
||||
hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags)
|
||||
|
@ -226,7 +227,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
wrapper = None;
|
||||
XDestroyWindow( qt_xdisplay(), frame );
|
||||
frame = None;
|
||||
--block_geometry;
|
||||
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
||||
|
@ -241,7 +242,7 @@ void Client::destroyClient()
|
|||
if (moveResizeMode)
|
||||
leaveMoveResize();
|
||||
finishWindowRules();
|
||||
++block_geometry;
|
||||
++postpone_geometry_updates;
|
||||
setModal( false );
|
||||
hidden = true; // so that it's not considered visible anymore
|
||||
workspace()->clientHidden( this );
|
||||
|
@ -253,7 +254,7 @@ void Client::destroyClient()
|
|||
wrapper = None;
|
||||
XDestroyWindow( qt_xdisplay(), frame );
|
||||
frame = None;
|
||||
--block_geometry;
|
||||
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
||||
|
@ -263,7 +264,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|
|||
|| ( decoration != NULL && !noBorder())))
|
||||
return;
|
||||
bool do_show = false;
|
||||
++block_geometry;
|
||||
postponeGeometryUpdates( true );
|
||||
if( force )
|
||||
destroyDecoration();
|
||||
if( !noBorder())
|
||||
|
@ -291,8 +292,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|
|||
destroyDecoration();
|
||||
if( check_workspace_pos )
|
||||
checkWorkspacePosition();
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
postponeGeometryUpdates( false );
|
||||
if( do_show )
|
||||
decoration->widget()->show();
|
||||
updateFrameStrut();
|
||||
|
@ -328,7 +328,7 @@ void Client::checkBorderSizes()
|
|||
if( new_left == border_left && new_right == border_right
|
||||
&& new_top == border_top && new_bottom == border_bottom )
|
||||
return;
|
||||
++block_geometry;
|
||||
GeometryUpdatesPostponer blocker( this );
|
||||
move( calculateGravitation( true ));
|
||||
border_left = new_left;
|
||||
border_right = new_right;
|
||||
|
@ -339,8 +339,6 @@ void Client::checkBorderSizes()
|
|||
move( calculateGravitation( false ));
|
||||
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
|
||||
checkWorkspacePosition();
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
}
|
||||
|
||||
void Client::detectNoBorder()
|
||||
|
@ -731,7 +729,7 @@ void Client::setShade( ShadeMode mode )
|
|||
}
|
||||
|
||||
assert( decoration != NULL ); // noborder windows can't be shaded
|
||||
++block_geometry;
|
||||
GeometryUpdatesPostponer blocker( this );
|
||||
// decorations may turn off some borders when shaded
|
||||
decoration->borders( border_left, border_right, border_top, border_bottom );
|
||||
|
||||
|
@ -809,8 +807,6 @@ void Client::setShade( ShadeMode mode )
|
|||
workspace()->requestFocus( this );
|
||||
}
|
||||
checkMaximizeGeometry();
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
info->setState( isShade() ? NET::Shaded : 0, NET::Shaded );
|
||||
info->setState( isShown( false ) ? 0 : NET::Hidden, NET::Hidden );
|
||||
updateVisibility();
|
||||
|
@ -907,12 +903,8 @@ void Client::setMappingState(int s)
|
|||
XChangeProperty(qt_xdisplay(), window(), qt_wm_state, qt_wm_state, 32,
|
||||
PropModeReplace, (unsigned char *)data, 2);
|
||||
|
||||
if( was_unmanaged ) // force setting the geometry, manage() did block_geometry = 1
|
||||
{
|
||||
assert( block_geometry == 1 );
|
||||
--block_geometry;
|
||||
setGeometry( frame_geometry, ForceGeometrySet );
|
||||
}
|
||||
if( was_unmanaged ) // manage() did postpone_geometry_updates = 1, now it's ok to finally set the geometry
|
||||
postponeGeometryUpdates( false );
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
18
client.h
18
client.h
|
@ -383,6 +383,7 @@ class Client : public QObject, public KDecorationDefines
|
|||
NETExtendedStrut strut() const;
|
||||
bool hasStrut() const;
|
||||
int checkShadeGeometry( int w, int h );
|
||||
void postponeGeometryUpdates( bool postpone );
|
||||
|
||||
bool startMoveResize();
|
||||
void finishMoveResize( bool cancel );
|
||||
|
@ -520,7 +521,8 @@ class Client : public QObject, public KDecorationDefines
|
|||
unsigned long allowed_actions;
|
||||
QRect frame_geometry;
|
||||
QSize client_size;
|
||||
int block_geometry; // >0 - new geometry is remembered, but not actually set
|
||||
int postpone_geometry_updates; // >0 - new geometry is remembered, but not actually set
|
||||
bool pending_geometry_update;
|
||||
bool shade_geometry_change;
|
||||
int border_left, border_right, border_top, border_bottom;
|
||||
QRegion _mask;
|
||||
|
@ -529,6 +531,7 @@ class Client : public QObject, public KDecorationDefines
|
|||
friend struct FetchNameInternalPredicate;
|
||||
friend struct CheckIgnoreFocusStealingProcedure;
|
||||
friend struct ResetupRulesProcedure;
|
||||
friend class GeometryUpdatesPostponer;
|
||||
void show() { assert( false ); } // SELI remove after Client is no longer QWidget
|
||||
void hide() { assert( false ); }
|
||||
uint opacity_;
|
||||
|
@ -541,6 +544,19 @@ class Client : public QObject, public KDecorationDefines
|
|||
QTimer* demandAttentionKNotifyTimer;
|
||||
};
|
||||
|
||||
// helper for Client::postponeGeometryUpdates() being called in pairs (true/false)
|
||||
class GeometryUpdatesPostponer
|
||||
{
|
||||
public:
|
||||
GeometryUpdatesPostponer( Client* c )
|
||||
: cl( c ) { cl->postponeGeometryUpdates( true ); }
|
||||
~GeometryUpdatesPostponer()
|
||||
{ cl->postponeGeometryUpdates( false ); }
|
||||
private:
|
||||
Client* cl;
|
||||
};
|
||||
|
||||
|
||||
// NET WM Protocol handler class
|
||||
class WinInfo : public NETWinInfo
|
||||
{
|
||||
|
|
124
geometry.cpp
124
geometry.cpp
|
@ -1393,7 +1393,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
|||
|| ns != size())
|
||||
{
|
||||
QRect orig_geometry = geometry();
|
||||
++block_geometry;
|
||||
GeometryUpdatesPostponer blocker( this );
|
||||
move( new_pos );
|
||||
plainResize( ns );
|
||||
setGeometry( QRect( calculateGravitation( false, gravity ), size()));
|
||||
|
@ -1402,8 +1402,6 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
|||
if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
|
||||
&& area.contains( orig_geometry ))
|
||||
keepInArea( area );
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
|
||||
// this is part of the kicker-xinerama-hack... it should be
|
||||
// safe to remove when kicker gets proper ExtendedStrut support;
|
||||
|
@ -1428,7 +1426,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
|||
if( ns != size()) // don't restore if some app sets its own size again
|
||||
{
|
||||
QRect orig_geometry = geometry();
|
||||
++block_geometry;
|
||||
GeometryUpdatesPostponer blocker( this );
|
||||
int save_gravity = xSizeHint.win_gravity;
|
||||
xSizeHint.win_gravity = gravity;
|
||||
resizeWithChecks( ns );
|
||||
|
@ -1438,8 +1436,6 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|
|||
if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
|
||||
&& area.contains( orig_geometry ))
|
||||
keepInArea( area );
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
}
|
||||
}
|
||||
// No need to send synthetic configure notify event here, either it's sent together
|
||||
|
@ -1612,27 +1608,28 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
else
|
||||
client_size = QSize( w - border_left - border_right, client_size.height());
|
||||
updateWorkareaDiffs();
|
||||
if( block_geometry == 0 )
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XMoveResizeWindow( qt_xdisplay(), frameId(), x, y, w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
// FRAME tady poradi tak, at neni flicker
|
||||
XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
// SELI TODO won't this be too expensive?
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
pending_geometry_update = true;
|
||||
return;
|
||||
}
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XMoveResizeWindow( qt_xdisplay(), frameId(), x, y, w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
// SELI TODO won't this be too expensive?
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
}
|
||||
|
||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||
|
@ -1651,25 +1648,27 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
else
|
||||
client_size = QSize( w - border_left - border_right, client_size.height());
|
||||
updateWorkareaDiffs();
|
||||
if( block_geometry == 0 )
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XResizeWindow( qt_xdisplay(), frameId(), w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
pending_geometry_update = true;
|
||||
return;
|
||||
}
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XResizeWindow( qt_xdisplay(), frameId(), w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( qt_xdisplay(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( qt_xdisplay(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
}
|
||||
|
||||
// There may be cases when an application requests resizing while shaded,
|
||||
|
@ -1699,16 +1698,36 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
|||
return;
|
||||
frame_geometry.moveTopLeft( QPoint( x, y ));
|
||||
updateWorkareaDiffs();
|
||||
if( block_geometry == 0 )
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
XMoveWindow( qt_xdisplay(), frameId(), x, y );
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
pending_geometry_update = true;
|
||||
return;
|
||||
}
|
||||
XMoveWindow( qt_xdisplay(), frameId(), x, y );
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
}
|
||||
|
||||
|
||||
void Client::postponeGeometryUpdates( bool postpone )
|
||||
{
|
||||
if( postpone )
|
||||
{
|
||||
++postpone_geometry_updates;
|
||||
pending_geometry_update = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( --postpone_geometry_updates == 0 )
|
||||
{
|
||||
if( pending_geometry_update )
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
pending_geometry_update = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::maximize( MaximizeMode m )
|
||||
{
|
||||
setMaximize( m & MaximizeVertical, m & MaximizeHorizontal );
|
||||
|
@ -1744,7 +1763,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
|
|||
if( !adjust && max_mode == old_mode )
|
||||
return;
|
||||
|
||||
++block_geometry; // TODO GeometryBlocker class?
|
||||
GeometryUpdatesPostponer blocker( this );
|
||||
|
||||
// maximing one way and unmaximizing the other way shouldn't happen
|
||||
Q_ASSERT( !( vertical && horizontal )
|
||||
|
@ -1865,9 +1884,6 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
|
|||
break;
|
||||
}
|
||||
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
|
||||
updateAllowedActions();
|
||||
if( decoration != NULL )
|
||||
decoration->maximizeChange();
|
||||
|
@ -1973,8 +1989,8 @@ void Client::setFullScreen( bool set, bool user )
|
|||
fullscreen_mode = set ? FullScreenNormal : FullScreenNone;
|
||||
if( was_fs == isFullScreen())
|
||||
return;
|
||||
StackingUpdatesBlocker blocker( workspace());
|
||||
++block_geometry;
|
||||
StackingUpdatesBlocker blocker1( workspace());
|
||||
GeometryUpdatesPostponer blocker2( this );
|
||||
workspace()->updateClientLayer( this ); // active fullscreens get different layer
|
||||
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
|
||||
updateDecoration( false, false );
|
||||
|
@ -1992,8 +2008,6 @@ void Client::setFullScreen( bool set, bool user )
|
|||
setGeometry( workspace()->clientArea( MaximizeArea, this ));
|
||||
}
|
||||
}
|
||||
--block_geometry;
|
||||
setGeometry( geometry(), ForceGeometrySet );
|
||||
updateWindowRules();
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
grabXServer();
|
||||
|
||||
// from this place on, manage() mustn't return false
|
||||
block_geometry = 1;
|
||||
postpone_geometry_updates = 1;
|
||||
|
||||
embedClient( w, attr );
|
||||
|
||||
|
|
Loading…
Reference in a new issue