diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index a318cdfdbd..24dbeab560 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -240,3 +240,6 @@ Performance + various caching - there are many things that usually don't change and could gain few fps (is it worth it?) - Workspace::performCompositing() - WindowQuadList could perhaps cache quads split by contents/decoration (for select()) + ++ avoiding X roundtrips each compositing pass + - right now it at least always polls the mouse position and the current stacking order diff --git a/composite.cpp b/composite.cpp index ed88cae258..5ffae47277 100644 --- a/composite.cpp +++ b/composite.cpp @@ -294,13 +294,7 @@ void Workspace::performCompositing() return; } // create a list of all windows in the stacking order - ToplevelList windows; - foreach( Client* c, stacking_order ) - windows.append( c ); - foreach( Unmanaged* c, unmanaged_stacking_order ) - windows.append( c ); - foreach( Deleted* c, deleted ) // TODO remember stacking order somehow - windows.append( c ); + ToplevelList windows = rootStackingOrder(); foreach( EffectWindow* c, static_cast< EffectsHandlerImpl* >( effects )->elevatedWindows()) { Toplevel* t = static_cast< EffectWindowImpl* >( c )->window(); diff --git a/events.cpp b/events.cpp index 4bf23bdbce..5d99ba62bb 100644 --- a/events.cpp +++ b/events.cpp @@ -1714,7 +1714,6 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e ) if( effects != NULL ) static_cast(effects)->windowGeometryShapeChanged( effectWindow(), old ); } - workspace()->restackUnmanaged( this, e->above ); } // **************************************** diff --git a/layers.cpp b/layers.cpp index c0fa590a34..1b845eb1fb 100644 --- a/layers.cpp +++ b/layers.cpp @@ -83,6 +83,7 @@ along with this program. If not, see . #include "group.h" #include "rules.h" #include "unmanaged.h" +#include "deleted.h" #include namespace KWin @@ -719,42 +720,27 @@ bool Workspace::keepTransientAbove( const Client* mainwindow, const Client* tran return true; } -void Workspace::restackUnmanaged( Unmanaged* c, Window above ) +// 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::rootStackingOrder() const { - if( above == None ) - { - unmanaged_stacking_order.removeAll( c ); - unmanaged_stacking_order.prepend( c ); - addRepaint( c->geometry()); - return; - } - bool was_below = false; - for( int i = 0; - i < unmanaged_stacking_order.size(); + Window dummy; + Window* windows; + unsigned int count = 0; + XQueryTree( display(), rootWindow(), &dummy, &dummy, &windows, &count ); + ToplevelList ret; + for( unsigned int i = 0; + i < count; ++i ) { - if( unmanaged_stacking_order.at( i )->window() == above ) - { - if( i + 1 < unmanaged_stacking_order.size() - && unmanaged_stacking_order.at( i + 1 ) == c ) - { - // it is already there, do nothing - return; - } - unmanaged_stacking_order.removeAll( c ); - if( was_below ) - --i; - unmanaged_stacking_order.insert( i + 1, c ); - addRepaint( c->geometry()); - return; - } - if( unmanaged_stacking_order.at( i ) == c ) - was_below = true; + if( Client* c = findClient( FrameIdMatchPredicate( windows[ i ] ))) + ret.append( c ); + else if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( windows[ i ] ))) + ret.append( c ); } - // TODO not found? - unmanaged_stacking_order.removeAll( c ); - unmanaged_stacking_order.append( c ); - addRepaint( c->geometry()); + foreach( Deleted* c, deleted ) + ret.append( c ); + return ret; } //******************************* diff --git a/workspace.cpp b/workspace.cpp index cffe4cfa1f..b9965c2ab1 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -564,7 +564,6 @@ void Workspace::addClient( Client* c, allowed_t ) void Workspace::addUnmanaged( Unmanaged* c, allowed_t ) { unmanaged.append( c ); - unmanaged_stacking_order.append( c ); } /* @@ -632,7 +631,6 @@ void Workspace::removeUnmanaged( Unmanaged* c, allowed_t ) { assert( unmanaged.contains( c )); unmanaged.removeAll( c ); - unmanaged_stacking_order.removeAll( c ); } void Workspace::addDeleted( Deleted* c, allowed_t ) diff --git a/workspace.h b/workspace.h index 73e5e2b804..814bb135c6 100644 --- a/workspace.h +++ b/workspace.h @@ -74,10 +74,10 @@ class Workspace : public QObject, public KDecorationDefines bool hasClient( const Client * ); - template< typename T > Client* findClient( T predicate ); + template< typename T > Client* findClient( T predicate ) const; template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate ); template< typename T > void forEachClient( T procedure ); - template< typename T > Unmanaged* findUnmanaged( T predicate ); + template< typename T > Unmanaged* findUnmanaged( T predicate ) const; template< typename T1, typename T2 > void forEachUnmanaged( T1 procedure, T2 predicate ); template< typename T > void forEachUnmanaged( T procedure ); @@ -137,7 +137,6 @@ class Workspace : public QObject, public KDecorationDefines void updateClientLayer( Client* c ); void raiseOrLowerClient( Client * ); void restoreSessionStackingOrder( Client* c ); - void restackUnmanaged( Unmanaged* c, Window above ); void reconfigure(); void forceRestacking(); @@ -508,6 +507,7 @@ class Workspace : public QObject, public KDecorationDefines void removeTabBoxGrab(); void updateStackingOrder( bool propagate_new_clients = false ); + ToplevelList rootStackingOrder() const; void propagateClients( bool propagate_new_clients ); // called only from updateStackingOrder ClientList constrainedStackingOrder(); void raiseClientWithinApplication( Client* c ); @@ -601,7 +601,6 @@ class Workspace : public QObject, public KDecorationDefines ClientList unconstrained_stacking_order; // topmost last ClientList stacking_order; // topmost last - UnmanagedList unmanaged_stacking_order; bool force_restacking; QVector< ClientList > focus_chain; // currently ative last ClientList global_focus_chain; // this one is only for things like tabbox's MRU @@ -896,7 +895,7 @@ QPoint Workspace::focusMousePosition() const } template< typename T > -inline Client* Workspace::findClient( T predicate ) +inline Client* Workspace::findClient( T predicate ) const { if( Client* ret = findClientInList( clients, predicate )) return ret; @@ -923,7 +922,7 @@ inline void Workspace::forEachClient( T procedure ) } template< typename T > -inline Unmanaged* Workspace::findUnmanaged( T predicate ) +inline Unmanaged* Workspace::findUnmanaged( T predicate ) const { return findUnmanagedInList( unmanaged, predicate ); }