diff --git a/composite.cpp b/composite.cpp index 3f9881b5a6..20ed571987 100644 --- a/composite.cpp +++ b/composite.cpp @@ -227,25 +227,13 @@ void Workspace::performCompositing() return; } // create a list of all windows in the stacking order - // TODO keep this list like now a stacking order of Client window is kept ToplevelList windows; - Window* children; - unsigned int children_count; - Window dummy; - XQueryTree( display(), rootWindow(), &dummy, &dummy, &children, &children_count ); - for( unsigned int i = 0; - i < children_count; - ++i ) - { - if( Client* c = findClient( FrameIdMatchPredicate( children[ i ] ))) - windows.append( c ); - else if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( children[ i ] ))) - windows.append( c ); - } + 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 ); - if( children != NULL ) - XFree( children ); foreach( Toplevel* c, windows ) { // This could be possibly optimized WRT obscuring, but that'd need being already // past prePaint() phase - probably not worth it. diff --git a/events.cpp b/events.cpp index 4392583549..6d97094344 100644 --- a/events.cpp +++ b/events.cpp @@ -1649,16 +1649,18 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e ) if( effects ) static_cast(effects)->checkInputWindowStacking(); // keep them on top QRect newgeom( e->x, e->y, e->width, e->height ); - if( newgeom == geom ) - return; - addWorkspaceRepaint( geometry()); // damage old area - QRect old = geom; - geom = newgeom; - discardWindowPixmap(); - if( scene != NULL ) - scene->windowGeometryShapeChanged( this ); - if( effects != NULL ) - static_cast(effects)->windowGeometryShapeChanged( effectWindow(), old ); + if( newgeom != geom ) + { + addWorkspaceRepaint( geometry()); // damage old area + QRect old = geom; + geom = newgeom; + discardWindowPixmap(); + if( scene != NULL ) + scene->windowGeometryShapeChanged( this ); + if( effects != NULL ) + static_cast(effects)->windowGeometryShapeChanged( effectWindow(), old ); + } + workspace()->restackUnmanaged( this, e->above ); } // **************************************** diff --git a/layers.cpp b/layers.cpp index cf6298427e..9295392cc3 100644 --- a/layers.cpp +++ b/layers.cpp @@ -72,6 +72,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "tabbox.h" #include "group.h" #include "rules.h" +#include "unmanaged.h" #include namespace KWin @@ -227,7 +228,7 @@ Client* Workspace::findDesktop( bool topmost, int desktop ) const // TODO Q_ASSERT( block_stacking_updates == 0 ); if( topmost ) { - for ( int i = stacking_order.size() - 1; i>=0; i-- ) + for ( int i = stacking_order.size() - 1; i>=0; i-- ) { if ( stacking_order.at( i )->isOnDesktop( desktop ) && stacking_order.at( i )->isDesktop() && stacking_order.at( i )->isShown( true )) @@ -236,7 +237,7 @@ Client* Workspace::findDesktop( bool topmost, int desktop ) const } else // bottom-most { - foreach ( Client* c, stacking_order ) + foreach ( Client* c, stacking_order ) { if ( c->isOnDesktop( desktop ) && c->isDesktop() && c->isShown( true )) @@ -688,6 +689,44 @@ bool Workspace::keepTransientAbove( const Client* mainwindow, const Client* tran return true; } +void Workspace::restackUnmanaged( Unmanaged* c, Window above ) + { + 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(); + ++i ) + { + if( unmanaged_stacking_order.at( i )->window() == above ) + { + if( i + 1 < unmanaged_stacking_order.size() + && unmanaged_stacking_order.at( i ) == c ) + { + // it is already there, do nothing + return; + } + unmanaged_stacking_order.removeAll( c ); + if( was_below ) + --i; + unmanaged_stacking_order.insert( i, c ); + addRepaint( c->geometry()); + return; + } + if( unmanaged_stacking_order.at( i ) == c ) + was_below = true; + } + // TODO not found? + unmanaged_stacking_order.removeAll( c ); + unmanaged_stacking_order.append( c ); + addRepaint( c->geometry()); + } + //******************************* // Client //******************************* diff --git a/workspace.cpp b/workspace.cpp index 9316cadaa9..09c89c55c5 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -573,6 +573,7 @@ void Workspace::addClient( Client* c, allowed_t ) void Workspace::addUnmanaged( Unmanaged* c, allowed_t ) { unmanaged.append( c ); + unmanaged_stacking_order.append( c ); } /* @@ -640,6 +641,7 @@ 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 b35ee74018..dcc2615504 100644 --- a/workspace.h +++ b/workspace.h @@ -151,6 +151,7 @@ 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 clientHidden( Client* ); @@ -617,6 +618,7 @@ class Workspace : public QObject, public KDecorationDefines ClientList unconstrained_stacking_order; // topmost last ClientList stacking_order; // topmost last + UnmanagedList unmanaged_stacking_order; 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