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 ),
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 );
}
/*!

View File

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

View File

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

View File

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