From 09d81b7e870febd0f63a1b819b912b201bac29dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Sun, 24 Aug 2008 10:35:45 +0000 Subject: [PATCH] Cache the result of XQueryTree(). svn path=/trunk/KDE/kdebase/workspace/; revision=851667 --- composite.cpp | 2 +- events.cpp | 4 ++++ layers.cpp | 18 ++++++++++-------- workspace.cpp | 7 +++++++ workspace.h | 4 +++- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/composite.cpp b/composite.cpp index 04633765a5..c6d1489a71 100644 --- a/composite.cpp +++ b/composite.cpp @@ -322,7 +322,7 @@ void Workspace::performCompositing() return; } // create a list of all windows in the stacking order - ToplevelList windows = compositingStackingOrder(); + ToplevelList windows = xStackingOrder(); foreach( EffectWindow* c, static_cast< EffectsHandlerImpl* >( effects )->elevatedWindows()) { Toplevel* t = static_cast< EffectWindowImpl* >( c )->window(); diff --git a/events.cpp b/events.cpp index 1576f72991..6df955fac4 100644 --- a/events.cpp +++ b/events.cpp @@ -279,6 +279,10 @@ bool Workspace::workspaceEvent( XEvent * e ) return true; } break; + case ConfigureNotify: + if( e->xconfigure.event == rootWindow()) + x_stacking_dirty = true; + break; }; if( Client* c = findClient( WindowMatchPredicate( e->xany.window ))) diff --git a/layers.cpp b/layers.cpp index 39a8eb3fc9..5e4adef4bf 100644 --- a/layers.cpp +++ b/layers.cpp @@ -723,30 +723,32 @@ bool Workspace::keepTransientAbove( const Client* mainwindow, const Client* tran return true; } -// Returns all windows in their stacking order on the root window, used only by compositing. -// TODO This possibly should be optimized to avoid the X roundtrip and building it every pass. -ToplevelList Workspace::compositingStackingOrder() const +// Returns all windows in their stacking order on the root window. +ToplevelList Workspace::xStackingOrder() const { + if( !x_stacking_dirty ) + return x_stacking; + x_stacking_dirty = false; + x_stacking.clear(); Window dummy; Window* windows = NULL; unsigned int count = 0; XQueryTree( display(), rootWindow(), &dummy, &dummy, &windows, &count ); - ToplevelList ret; // use our own stacking order, not the X one, as they may differ foreach( Client* c, stacking_order ) - ret.append( c ); + x_stacking.append( c ); for( unsigned int i = 0; i < count; ++i ) { if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( windows[ i ] ))) - ret.append( c ); + x_stacking.append( c ); } foreach( Deleted* c, deleted ) - ret.append( c ); + x_stacking.append( c ); if( windows != NULL ) XFree( windows ); - return ret; + return x_stacking; } //******************************* diff --git a/workspace.cpp b/workspace.cpp index 32fcd50a11..21c5334177 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -99,6 +99,7 @@ Workspace::Workspace( bool restore ) active_screen (0), delayfocus_client (0), force_restacking( false ), + x_stacking_dirty( true ), showing_desktop( false ), block_showing_desktop( 0 ), was_user_interaction (false), @@ -544,6 +545,7 @@ void Workspace::addClient( Client* c, allowed_t ) stacking_order.append( c ); // c to be in stacking_order if( c->isTopMenu()) addTopMenu( c ); + x_stacking_dirty = true; updateClientArea(); // this cannot be in manage(), because the client got added only now updateClientLayer( c ); if( c->isDesktop()) @@ -566,6 +568,7 @@ void Workspace::addClient( Client* c, allowed_t ) void Workspace::addUnmanaged( Unmanaged* c, allowed_t ) { unmanaged.append( c ); + x_stacking_dirty = true; } /* @@ -597,6 +600,7 @@ void Workspace::removeClient( Client* c, allowed_t ) desktops.removeAll( c ); unconstrained_stacking_order.removeAll( c ); stacking_order.removeAll( c ); + x_stacking_dirty = true; for( int i = 1; i <= numberOfDesktops(); ++i ) @@ -633,12 +637,14 @@ void Workspace::removeUnmanaged( Unmanaged* c, allowed_t ) { assert( unmanaged.contains( c )); unmanaged.removeAll( c ); + x_stacking_dirty = true; } void Workspace::addDeleted( Deleted* c, allowed_t ) { assert( !deleted.contains( c )); deleted.append( c ); + x_stacking_dirty = true; } void Workspace::removeDeleted( Deleted* c, allowed_t ) @@ -649,6 +655,7 @@ void Workspace::removeDeleted( Deleted* c, allowed_t ) if( effects ) static_cast(effects)->windowDeleted( c->effectWindow()); deleted.removeAll( c ); + x_stacking_dirty = true; } void Workspace::updateFocusChains( Client* c, FocusChainChange change ) diff --git a/workspace.h b/workspace.h index 4ef841fdc9..05d73a8ee3 100644 --- a/workspace.h +++ b/workspace.h @@ -518,7 +518,7 @@ class Workspace : public QObject, public KDecorationDefines bool establishTabBoxGrab(); void removeTabBoxGrab(); - ToplevelList compositingStackingOrder() const; + ToplevelList xStackingOrder() const; void propagateClients( bool propagate_new_clients ); // called only from updateStackingOrder ClientList constrainedStackingOrder(); void raiseClientWithinApplication( Client* c ); @@ -613,6 +613,8 @@ class Workspace : public QObject, public KDecorationDefines ClientList unconstrained_stacking_order; // topmost last ClientList stacking_order; // topmost last bool force_restacking; + mutable ToplevelList x_stacking; // from XQueryTree() + mutable bool x_stacking_dirty; QVector< ClientList > focus_chain; // currently ative last ClientList global_focus_chain; // this one is only for things like tabbox's MRU ClientList should_get_focus; // last is most recent