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
icc-effect-5.14.5
Luboš Luňák 2005-06-08 17:16:53 +00:00
parent a34f9ab748
commit 8ef2a46218
4 changed files with 100 additions and 78 deletions

View File

@ -86,7 +86,8 @@ Client::Client( Workspace *ws )
process_killer( NULL ), process_killer( NULL ),
user_time( CurrentTime ), // not known yet user_time( CurrentTime ), // not known yet
allowed_actions( 0 ), allowed_actions( 0 ),
block_geometry( 0 ), postpone_geometry_updates( 0 ),
pending_geometry_update( false ),
shade_geometry_change( false ), shade_geometry_change( false ),
border_left( 0 ), border_left( 0 ),
border_right( 0 ), border_right( 0 ),
@ -162,7 +163,7 @@ Client::~Client()
assert( client == None ); assert( client == None );
assert( frame == None && wrapper == None ); assert( frame == None && wrapper == None );
assert( decoration == NULL ); assert( decoration == NULL );
assert( block_geometry == 0 ); assert( postpone_geometry_updates == 0 );
assert( !check_active_modal ); assert( !check_active_modal );
delete info; delete info;
delete bridge; delete bridge;
@ -187,7 +188,7 @@ void Client::releaseWindow( bool on_shutdown )
if (moveResizeMode) if (moveResizeMode)
leaveMoveResize(); leaveMoveResize();
finishWindowRules(); finishWindowRules();
++block_geometry; ++postpone_geometry_updates;
setMappingState( WithdrawnState ); setMappingState( WithdrawnState );
setModal( false ); // otherwise its mainwindow wouldn't get focus 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) 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; wrapper = None;
XDestroyWindow( qt_xdisplay(), frame ); XDestroyWindow( qt_xdisplay(), frame );
frame = None; frame = None;
--block_geometry; --postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
deleteClient( this, Allowed ); deleteClient( this, Allowed );
} }
@ -241,7 +242,7 @@ void Client::destroyClient()
if (moveResizeMode) if (moveResizeMode)
leaveMoveResize(); leaveMoveResize();
finishWindowRules(); finishWindowRules();
++block_geometry; ++postpone_geometry_updates;
setModal( false ); setModal( false );
hidden = true; // so that it's not considered visible anymore hidden = true; // so that it's not considered visible anymore
workspace()->clientHidden( this ); workspace()->clientHidden( this );
@ -253,7 +254,7 @@ void Client::destroyClient()
wrapper = None; wrapper = None;
XDestroyWindow( qt_xdisplay(), frame ); XDestroyWindow( qt_xdisplay(), frame );
frame = None; frame = None;
--block_geometry; --postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
deleteClient( this, Allowed ); deleteClient( this, Allowed );
} }
@ -263,7 +264,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|| ( decoration != NULL && !noBorder()))) || ( decoration != NULL && !noBorder())))
return; return;
bool do_show = false; bool do_show = false;
++block_geometry; postponeGeometryUpdates( true );
if( force ) if( force )
destroyDecoration(); destroyDecoration();
if( !noBorder()) if( !noBorder())
@ -291,8 +292,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
destroyDecoration(); destroyDecoration();
if( check_workspace_pos ) if( check_workspace_pos )
checkWorkspacePosition(); checkWorkspacePosition();
--block_geometry; postponeGeometryUpdates( false );
setGeometry( geometry(), ForceGeometrySet );
if( do_show ) if( do_show )
decoration->widget()->show(); decoration->widget()->show();
updateFrameStrut(); updateFrameStrut();
@ -328,7 +328,7 @@ void Client::checkBorderSizes()
if( new_left == border_left && new_right == border_right if( new_left == border_left && new_right == border_right
&& new_top == border_top && new_bottom == border_bottom ) && new_top == border_top && new_bottom == border_bottom )
return; return;
++block_geometry; GeometryUpdatesPostponer blocker( this );
move( calculateGravitation( true )); move( calculateGravitation( true ));
border_left = new_left; border_left = new_left;
border_right = new_right; border_right = new_right;
@ -339,8 +339,6 @@ void Client::checkBorderSizes()
move( calculateGravitation( false )); move( calculateGravitation( false ));
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet ); plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
checkWorkspacePosition(); checkWorkspacePosition();
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
} }
void Client::detectNoBorder() void Client::detectNoBorder()
@ -731,7 +729,7 @@ void Client::setShade( ShadeMode mode )
} }
assert( decoration != NULL ); // noborder windows can't be shaded assert( decoration != NULL ); // noborder windows can't be shaded
++block_geometry; GeometryUpdatesPostponer blocker( this );
// decorations may turn off some borders when shaded // decorations may turn off some borders when shaded
decoration->borders( border_left, border_right, border_top, border_bottom ); decoration->borders( border_left, border_right, border_top, border_bottom );
@ -809,8 +807,6 @@ void Client::setShade( ShadeMode mode )
workspace()->requestFocus( this ); workspace()->requestFocus( this );
} }
checkMaximizeGeometry(); checkMaximizeGeometry();
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
info->setState( isShade() ? NET::Shaded : 0, NET::Shaded ); info->setState( isShade() ? NET::Shaded : 0, NET::Shaded );
info->setState( isShown( false ) ? 0 : NET::Hidden, NET::Hidden ); info->setState( isShown( false ) ? 0 : NET::Hidden, NET::Hidden );
updateVisibility(); updateVisibility();
@ -907,12 +903,8 @@ void Client::setMappingState(int s)
XChangeProperty(qt_xdisplay(), window(), qt_wm_state, qt_wm_state, 32, XChangeProperty(qt_xdisplay(), window(), qt_wm_state, qt_wm_state, 32,
PropModeReplace, (unsigned char *)data, 2); PropModeReplace, (unsigned char *)data, 2);
if( was_unmanaged ) // force setting the geometry, manage() did block_geometry = 1 if( was_unmanaged ) // manage() did postpone_geometry_updates = 1, now it's ok to finally set the geometry
{ postponeGeometryUpdates( false );
assert( block_geometry == 1 );
--block_geometry;
setGeometry( frame_geometry, ForceGeometrySet );
}
} }
/*! /*!

View File

@ -383,6 +383,7 @@ class Client : public QObject, public KDecorationDefines
NETExtendedStrut strut() const; NETExtendedStrut strut() const;
bool hasStrut() const; bool hasStrut() const;
int checkShadeGeometry( int w, int h ); int checkShadeGeometry( int w, int h );
void postponeGeometryUpdates( bool postpone );
bool startMoveResize(); bool startMoveResize();
void finishMoveResize( bool cancel ); void finishMoveResize( bool cancel );
@ -520,7 +521,8 @@ class Client : public QObject, public KDecorationDefines
unsigned long allowed_actions; unsigned long allowed_actions;
QRect frame_geometry; QRect frame_geometry;
QSize client_size; 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; bool shade_geometry_change;
int border_left, border_right, border_top, border_bottom; int border_left, border_right, border_top, border_bottom;
QRegion _mask; QRegion _mask;
@ -529,6 +531,7 @@ class Client : public QObject, public KDecorationDefines
friend struct FetchNameInternalPredicate; friend struct FetchNameInternalPredicate;
friend struct CheckIgnoreFocusStealingProcedure; friend struct CheckIgnoreFocusStealingProcedure;
friend struct ResetupRulesProcedure; friend struct ResetupRulesProcedure;
friend class GeometryUpdatesPostponer;
void show() { assert( false ); } // SELI remove after Client is no longer QWidget void show() { assert( false ); } // SELI remove after Client is no longer QWidget
void hide() { assert( false ); } void hide() { assert( false ); }
uint opacity_; uint opacity_;
@ -541,6 +544,19 @@ class Client : public QObject, public KDecorationDefines
QTimer* demandAttentionKNotifyTimer; 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 // NET WM Protocol handler class
class WinInfo : public NETWinInfo class WinInfo : public NETWinInfo
{ {

View File

@ -1393,7 +1393,7 @@ void Client::configureRequest( int value_mask, int rx, int ry, int rw, int rh, i
|| ns != size()) || ns != size())
{ {
QRect orig_geometry = geometry(); QRect orig_geometry = geometry();
++block_geometry; GeometryUpdatesPostponer blocker( this );
move( new_pos ); move( new_pos );
plainResize( ns ); plainResize( ns );
setGeometry( QRect( calculateGravitation( false, gravity ), size())); 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() if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
&& area.contains( orig_geometry )) && area.contains( orig_geometry ))
keepInArea( area ); keepInArea( area );
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
// this is part of the kicker-xinerama-hack... it should be // this is part of the kicker-xinerama-hack... it should be
// safe to remove when kicker gets proper ExtendedStrut support; // 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 if( ns != size()) // don't restore if some app sets its own size again
{ {
QRect orig_geometry = geometry(); QRect orig_geometry = geometry();
++block_geometry; GeometryUpdatesPostponer blocker( this );
int save_gravity = xSizeHint.win_gravity; int save_gravity = xSizeHint.win_gravity;
xSizeHint.win_gravity = gravity; xSizeHint.win_gravity = gravity;
resizeWithChecks( ns ); 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() if( !from_tool && ( !isSpecialWindow() || isToolbar()) && !isFullScreen()
&& area.contains( orig_geometry )) && area.contains( orig_geometry ))
keepInArea( area ); keepInArea( area );
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
} }
} }
// No need to send synthetic configure notify event here, either it's sent together // 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 else
client_size = QSize( w - border_left - border_right, client_size.height()); client_size = QSize( w - border_left - border_right, client_size.height());
updateWorkareaDiffs(); updateWorkareaDiffs();
if( block_geometry == 0 ) if( postpone_geometry_updates != 0 )
{ {
resizeDecoration( QSize( w, h )); pending_geometry_update = true;
XMoveResizeWindow( qt_xdisplay(), frameId(), x, y, w, h ); return;
// 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();
} }
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 ) 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 else
client_size = QSize( w - border_left - border_right, client_size.height()); client_size = QSize( w - border_left - border_right, client_size.height());
updateWorkareaDiffs(); updateWorkareaDiffs();
if( block_geometry == 0 ) if( postpone_geometry_updates != 0 )
{ {
resizeDecoration( QSize( w, h )); pending_geometry_update = true;
XResizeWindow( qt_xdisplay(), frameId(), w, h ); return;
// 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();
} }
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, // 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; return;
frame_geometry.moveTopLeft( QPoint( x, y )); frame_geometry.moveTopLeft( QPoint( x, y ));
updateWorkareaDiffs(); updateWorkareaDiffs();
if( block_geometry == 0 ) if( postpone_geometry_updates != 0 )
{ {
XMoveWindow( qt_xdisplay(), frameId(), x, y ); pending_geometry_update = true;
sendSyntheticConfigureNotify(); return;
updateWindowRules();
checkMaximizeGeometry();
} }
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 ) void Client::maximize( MaximizeMode m )
{ {
setMaximize( m & MaximizeVertical, m & MaximizeHorizontal ); setMaximize( m & MaximizeVertical, m & MaximizeHorizontal );
@ -1744,7 +1763,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
if( !adjust && max_mode == old_mode ) if( !adjust && max_mode == old_mode )
return; return;
++block_geometry; // TODO GeometryBlocker class? GeometryUpdatesPostponer blocker( this );
// maximing one way and unmaximizing the other way shouldn't happen // maximing one way and unmaximizing the other way shouldn't happen
Q_ASSERT( !( vertical && horizontal ) Q_ASSERT( !( vertical && horizontal )
@ -1865,9 +1884,6 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust )
break; break;
} }
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
updateAllowedActions(); updateAllowedActions();
if( decoration != NULL ) if( decoration != NULL )
decoration->maximizeChange(); decoration->maximizeChange();
@ -1973,8 +1989,8 @@ void Client::setFullScreen( bool set, bool user )
fullscreen_mode = set ? FullScreenNormal : FullScreenNone; fullscreen_mode = set ? FullScreenNormal : FullScreenNone;
if( was_fs == isFullScreen()) if( was_fs == isFullScreen())
return; return;
StackingUpdatesBlocker blocker( workspace()); StackingUpdatesBlocker blocker1( workspace());
++block_geometry; GeometryUpdatesPostponer blocker2( this );
workspace()->updateClientLayer( this ); // active fullscreens get different layer workspace()->updateClientLayer( this ); // active fullscreens get different layer
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen ); info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
updateDecoration( false, false ); updateDecoration( false, false );
@ -1992,8 +2008,6 @@ void Client::setFullScreen( bool set, bool user )
setGeometry( workspace()->clientArea( MaximizeArea, this )); setGeometry( workspace()->clientArea( MaximizeArea, this ));
} }
} }
--block_geometry;
setGeometry( geometry(), ForceGeometrySet );
updateWindowRules(); updateWindowRules();
} }

View File

@ -43,7 +43,7 @@ bool Client::manage( Window w, bool isMapped )
grabXServer(); grabXServer();
// from this place on, manage() mustn't return false // from this place on, manage() mustn't return false
block_geometry = 1; postpone_geometry_updates = 1;
embedClient( w, attr ); embedClient( w, attr );