Track stacking order of unmanaged windows.

svn path=/trunk/KDE/kdebase/workspace/; revision=667686
This commit is contained in:
Luboš Luňák 2007-05-23 16:22:59 +00:00
parent 4804cff7f1
commit 1040404a2a
5 changed files with 61 additions and 28 deletions

View file

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

View file

@ -1649,16 +1649,18 @@ void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
if( effects )
static_cast<EffectsHandlerImpl*>(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<EffectsHandlerImpl*>(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<EffectsHandlerImpl*>(effects)->windowGeometryShapeChanged( effectWindow(), old );
}
workspace()->restackUnmanaged( this, e->above );
}
// ****************************************

View file

@ -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 <QX11Info>
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
//*******************************

View file

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

View file

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