Add checking code to detect inconsistencies of internal structures
for window relations, like #117677. svn path=/trunk/KDE/kdebase/workspace/; revision=613274icc-effect-5.14.5
parent
f57d89d597
commit
508178e0d1
2
client.h
2
client.h
|
@ -520,6 +520,8 @@ class Client : public QObject, public KDecorationDefines
|
||||||
void show() { assert( false ); } // SELI remove after Client is no longer QWidget
|
void show() { assert( false ); } // SELI remove after Client is no longer QWidget
|
||||||
void hide() { assert( false ); }
|
void hide() { assert( false ); }
|
||||||
QTimer* demandAttentionKNotifyTimer;
|
QTimer* demandAttentionKNotifyTimer;
|
||||||
|
|
||||||
|
friend bool performTransiencyCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper for Client::postponeGeometryUpdates() being called in pairs (true/false)
|
// helper for Client::postponeGeometryUpdates() being called in pairs (true/false)
|
||||||
|
|
110
group.cpp
110
group.cpp
|
@ -36,6 +36,103 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
namespace KWinInternal
|
namespace KWinInternal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Consistency checks for window relations. Since transients are determinated
|
||||||
|
using Client::transiency_list and main windows are determined using Client::transientFor()
|
||||||
|
or the group for group transients, these have to match both ways.
|
||||||
|
*/
|
||||||
|
//#define ENABLE_TRANSIENCY_CHECK
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#undef ENABLE_TRANSIENCY_CHECK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_TRANSIENCY_CHECK
|
||||||
|
bool performTransiencyCheck()
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
ClientList clients = Workspace::self()->clients;
|
||||||
|
for( ClientList::ConstIterator it1 = clients.begin();
|
||||||
|
it1 != clients.end();
|
||||||
|
++it1 )
|
||||||
|
{
|
||||||
|
if( (*it1)->deleting )
|
||||||
|
continue;
|
||||||
|
if( !(*it1)->isTransient())
|
||||||
|
{
|
||||||
|
if( !(*it1)->mainClients().isEmpty())
|
||||||
|
{
|
||||||
|
kdDebug() << "TC: " << *it1 << " is not transient, has main clients:" << (*it1)->mainClients() << endl;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClientList mains = (*it1)->mainClients();
|
||||||
|
for( ClientList::ConstIterator it2 = mains.begin();
|
||||||
|
it2 != mains.end();
|
||||||
|
++it2 )
|
||||||
|
{
|
||||||
|
if( !(*it2)->transients_list.contains( *it1 ))
|
||||||
|
{
|
||||||
|
kdDebug() << "TC:" << *it1 << " has main client " << *it2 << " but main client does not have it as a transient" << endl;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClientList trans = (*it1)->transients_list;
|
||||||
|
for( ClientList::ConstIterator it2 = trans.begin();
|
||||||
|
it2 != trans.end();
|
||||||
|
++it2 )
|
||||||
|
{
|
||||||
|
if( !(*it2)->mainClients().contains( *it1 ))
|
||||||
|
{
|
||||||
|
kdDebug() << "TC:" << *it1 << " has transient " << *it2 << " but transient does not have it as a main client" << endl;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString transiencyCheckStartBt;
|
||||||
|
static const Client* transiencyCheckClient;
|
||||||
|
static int transiencyCheck = 0;
|
||||||
|
static void startTransiencyCheck( const QString& bt, const Client* c )
|
||||||
|
{
|
||||||
|
if( ++transiencyCheck == 1 )
|
||||||
|
{
|
||||||
|
transiencyCheckStartBt = bt;
|
||||||
|
transiencyCheckClient = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void checkTransiency()
|
||||||
|
{
|
||||||
|
if( --transiencyCheck == 0 )
|
||||||
|
{
|
||||||
|
if( !performTransiencyCheck())
|
||||||
|
{
|
||||||
|
kdDebug() << "BT:" << transiencyCheckStartBt << endl;
|
||||||
|
kdDebug() << "CLIENT:" << transiencyCheckClient << endl;
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class TransiencyChecker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransiencyChecker( const QString& bt, const Client*c ) { startTransiencyCheck( bt, c ); }
|
||||||
|
~TransiencyChecker() { checkTransiency(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TRANSIENCY_CHECK( c ) TransiencyChecker transiency_checker( kdBacktrace(), c )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define TRANSIENCY_CHECK( c )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//********************************************
|
//********************************************
|
||||||
// Group
|
// Group
|
||||||
//********************************************
|
//********************************************
|
||||||
|
@ -90,6 +187,7 @@ QPixmap Group::miniIcon() const
|
||||||
|
|
||||||
void Group::addMember( Client* member_P )
|
void Group::addMember( Client* member_P )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( member_P );
|
||||||
_members.append( member_P );
|
_members.append( member_P );
|
||||||
// kDebug() << "GROUPADD:" << this << ":" << member_P << endl;
|
// kDebug() << "GROUPADD:" << this << ":" << member_P << endl;
|
||||||
// kDebug() << kBacktrace() << endl;
|
// kDebug() << kBacktrace() << endl;
|
||||||
|
@ -97,6 +195,7 @@ void Group::addMember( Client* member_P )
|
||||||
|
|
||||||
void Group::removeMember( Client* member_P )
|
void Group::removeMember( Client* member_P )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( member_P );
|
||||||
// kDebug() << "GROUPREMOVE:" << this << ":" << member_P << endl;
|
// kDebug() << "GROUPREMOVE:" << this << ":" << member_P << endl;
|
||||||
// kDebug() << kBacktrace() << endl;
|
// kDebug() << kBacktrace() << endl;
|
||||||
Q_ASSERT( _members.contains( member_P ));
|
Q_ASSERT( _members.contains( member_P ));
|
||||||
|
@ -149,6 +248,7 @@ Group* Workspace::findGroup( Window leader ) const
|
||||||
// group with windows with the same client leader.
|
// group with windows with the same client leader.
|
||||||
Group* Workspace::findClientLeaderGroup( const Client* c ) const
|
Group* Workspace::findClientLeaderGroup( const Client* c ) const
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( c );
|
||||||
Group* ret = NULL;
|
Group* ret = NULL;
|
||||||
for( ClientList::ConstIterator it = clients.begin();
|
for( ClientList::ConstIterator it = clients.begin();
|
||||||
it != clients.end();
|
it != clients.end();
|
||||||
|
@ -233,6 +333,7 @@ void Workspace::updateOnAllDesktopsOfTransients( Client* c )
|
||||||
// A new window has been mapped. Check if it's not a mainwindow for some already existing transient window.
|
// A new window has been mapped. Check if it's not a mainwindow for some already existing transient window.
|
||||||
void Workspace::checkTransients( Window w )
|
void Workspace::checkTransients( Window w )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( NULL );
|
||||||
for( ClientList::ConstIterator it = clients.begin();
|
for( ClientList::ConstIterator it = clients.begin();
|
||||||
it != clients.end();
|
it != clients.end();
|
||||||
++it )
|
++it )
|
||||||
|
@ -398,6 +499,7 @@ bool Client::sameAppWindowRoleMatch( const Client* c1, const Client* c2, bool ac
|
||||||
|
|
||||||
void Client::readTransient()
|
void Client::readTransient()
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
Window new_transient_for_id;
|
Window new_transient_for_id;
|
||||||
if( XGetTransientForHint( display(), window(), &new_transient_for_id ))
|
if( XGetTransientForHint( display(), window(), &new_transient_for_id ))
|
||||||
{
|
{
|
||||||
|
@ -414,6 +516,7 @@ void Client::readTransient()
|
||||||
|
|
||||||
void Client::setTransient( Window new_transient_for_id )
|
void Client::setTransient( Window new_transient_for_id )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
if( new_transient_for_id != transient_for_id )
|
if( new_transient_for_id != transient_for_id )
|
||||||
{
|
{
|
||||||
removeFromMainClients();
|
removeFromMainClients();
|
||||||
|
@ -434,6 +537,7 @@ void Client::setTransient( Window new_transient_for_id )
|
||||||
|
|
||||||
void Client::removeFromMainClients()
|
void Client::removeFromMainClients()
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
if( transientFor() != NULL )
|
if( transientFor() != NULL )
|
||||||
transientFor()->removeTransient( this );
|
transientFor()->removeTransient( this );
|
||||||
if( groupTransient())
|
if( groupTransient())
|
||||||
|
@ -451,6 +555,7 @@ void Client::removeFromMainClients()
|
||||||
// related lists.
|
// related lists.
|
||||||
void Client::cleanGrouping()
|
void Client::cleanGrouping()
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
// kDebug() << "CLEANGROUPING:" << this << endl;
|
// kDebug() << "CLEANGROUPING:" << this << endl;
|
||||||
// for( ClientList::ConstIterator it = group()->members().begin();
|
// for( ClientList::ConstIterator it = group()->members().begin();
|
||||||
// it != group()->members().end();
|
// it != group()->members().end();
|
||||||
|
@ -520,6 +625,7 @@ void Client::cleanGrouping()
|
||||||
// Non-group transients not causing loops are checked in verifyTransientFor().
|
// Non-group transients not causing loops are checked in verifyTransientFor().
|
||||||
void Client::checkGroupTransients()
|
void Client::checkGroupTransients()
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
for( ClientList::ConstIterator it1 = group()->members().begin();
|
for( ClientList::ConstIterator it1 = group()->members().begin();
|
||||||
it1 != group()->members().end();
|
it1 != group()->members().end();
|
||||||
++it1 )
|
++it1 )
|
||||||
|
@ -649,6 +755,7 @@ Window Client::verifyTransientFor( Window new_transient_for, bool defined )
|
||||||
|
|
||||||
void Client::addTransient( Client* cl )
|
void Client::addTransient( Client* cl )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
assert( !transients_list.contains( cl ));
|
assert( !transients_list.contains( cl ));
|
||||||
// assert( !cl->hasTransient( this, true )); will be fixed in checkGroupTransients()
|
// assert( !cl->hasTransient( this, true )); will be fixed in checkGroupTransients()
|
||||||
assert( cl != this );
|
assert( cl != this );
|
||||||
|
@ -665,6 +772,7 @@ void Client::addTransient( Client* cl )
|
||||||
|
|
||||||
void Client::removeTransient( Client* cl )
|
void Client::removeTransient( Client* cl )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
// kDebug() << "REMOVETRANS:" << this << ":" << cl << endl;
|
// kDebug() << "REMOVETRANS:" << this << ":" << cl << endl;
|
||||||
// kDebug() << kBacktrace() << endl;
|
// kDebug() << kBacktrace() << endl;
|
||||||
transients_list.removeAll( cl );
|
transients_list.removeAll( cl );
|
||||||
|
@ -682,6 +790,7 @@ void Client::removeTransient( Client* cl )
|
||||||
// A new window has been mapped. Check if it's not a mainwindow for this already existing window.
|
// A new window has been mapped. Check if it's not a mainwindow for this already existing window.
|
||||||
void Client::checkTransient( Window w )
|
void Client::checkTransient( Window w )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
if( original_transient_for_id != w )
|
if( original_transient_for_id != w )
|
||||||
return;
|
return;
|
||||||
w = verifyTransientFor( w, true );
|
w = verifyTransientFor( w, true );
|
||||||
|
@ -762,6 +871,7 @@ Client* Client::findModal()
|
||||||
// Argument is only when some specific group needs to be set.
|
// Argument is only when some specific group needs to be set.
|
||||||
void Client::checkGroup( Group* set_group, bool force )
|
void Client::checkGroup( Group* set_group, bool force )
|
||||||
{
|
{
|
||||||
|
TRANSIENCY_CHECK( this );
|
||||||
Group* old_group = in_group;
|
Group* old_group = in_group;
|
||||||
if( set_group != NULL )
|
if( set_group != NULL )
|
||||||
{
|
{
|
||||||
|
|
81
workspace.h
81
workspace.h
|
@ -18,8 +18,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <netwm.h>
|
#include <netwm.h>
|
||||||
#include <kxmessages.h>
|
#include <kxmessages.h>
|
||||||
#include <qdatetime.h>
|
|
||||||
#include <kmanagerselection.h>
|
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "kdecoration.h"
|
#include "kdecoration.h"
|
||||||
|
@ -79,7 +77,7 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
virtual ~Workspace();
|
virtual ~Workspace();
|
||||||
|
|
||||||
static Workspace * self() { return _self; }
|
static Workspace * self() { return _self; }
|
||||||
|
|
||||||
bool workspaceEvent( XEvent * );
|
bool workspaceEvent( XEvent * );
|
||||||
|
|
||||||
KDecoration* createDecoration( KDecorationBridge* bridge );
|
KDecoration* createDecoration( KDecorationBridge* bridge );
|
||||||
|
@ -89,9 +87,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
template< typename T > Client* findClient( T predicate );
|
template< typename T > Client* findClient( T predicate );
|
||||||
template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate );
|
template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate );
|
||||||
template< typename T > void forEachClient( T procedure );
|
template< typename T > void forEachClient( T procedure );
|
||||||
template< typename T > Unmanaged* findUnmanaged( T predicate );
|
|
||||||
template< typename T1, typename T2 > void forEachUnmanaged( T1 procedure, T2 predicate );
|
|
||||||
template< typename T > void forEachUnmanaged( T procedure );
|
|
||||||
|
|
||||||
QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const;
|
QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const;
|
||||||
QRect clientArea( clientAreaOption, const Client* c ) const;
|
QRect clientArea( clientAreaOption, const Client* c ) const;
|
||||||
|
@ -186,7 +181,7 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
|
|
||||||
ClientList ensureStackingOrder( const ClientList& clients ) const;
|
ClientList ensureStackingOrder( const ClientList& clients ) const;
|
||||||
|
|
||||||
Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const;
|
Client* topClientOnDesktop( int desktop, bool unconstrained = false, bool only_normal = true ) const;
|
||||||
Client* findDesktop( bool topmost, int desktop ) const;
|
Client* findDesktop( bool topmost, int desktop ) const;
|
||||||
void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
|
void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
|
||||||
void windowToPreviousDesktop( Client* c );
|
void windowToPreviousDesktop( Client* c );
|
||||||
|
@ -247,9 +242,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void removeGroup( Group* group, allowed_t );
|
void removeGroup( Group* group, allowed_t );
|
||||||
Group* findClientLeaderGroup( const Client* c ) const;
|
Group* findClientLeaderGroup( const Client* c ) const;
|
||||||
|
|
||||||
// only called from Unmanaged::release()
|
|
||||||
void removeUnmanaged( Unmanaged*, allowed_t );
|
|
||||||
|
|
||||||
bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
|
bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
|
||||||
|
|
||||||
void focusToNull(); // SELI public?
|
void focusToNull(); // SELI public?
|
||||||
|
@ -284,17 +276,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void requestDelayFocus( Client* );
|
void requestDelayFocus( Client* );
|
||||||
|
|
||||||
void toggleTopDockShadows(bool on);
|
void toggleTopDockShadows(bool on);
|
||||||
|
|
||||||
void addDamage( const QRect& r );
|
|
||||||
void addDamage( int x, int y, int w, int h );
|
|
||||||
void addDamageFull();
|
|
||||||
// creates XComposite overlay window, cal initOverlay() afterwards
|
|
||||||
bool createOverlay();
|
|
||||||
// init overlay and the destination window in it
|
|
||||||
void setupOverlay( Window window );
|
|
||||||
// destroys XComposite overlay window
|
|
||||||
void destroyOverlay();
|
|
||||||
Window overlayWindow();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
@ -425,10 +406,11 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void cleanupTemporaryRules();
|
void cleanupTemporaryRules();
|
||||||
void writeWindowRules();
|
void writeWindowRules();
|
||||||
void slotBlockShortcuts(int data);
|
void slotBlockShortcuts(int data);
|
||||||
void setPopupClientOpacity( QAction* action );
|
// kompmgr
|
||||||
void setupCompositing();
|
void setPopupClientOpacity(int v);
|
||||||
void performCompositing();
|
void resetClientOpacity();
|
||||||
void lostCMSelection();
|
void setTransButtonText(int value);
|
||||||
|
// end
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool keyPressMouseEmulation( XKeyEvent& ev );
|
bool keyPressMouseEmulation( XKeyEvent& ev );
|
||||||
|
@ -476,8 +458,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
// this is the right way to create a new client
|
// this is the right way to create a new client
|
||||||
Client* createClient( Window w, bool is_mapped );
|
Client* createClient( Window w, bool is_mapped );
|
||||||
void addClient( Client* c, allowed_t );
|
void addClient( Client* c, allowed_t );
|
||||||
Unmanaged* createUnmanaged( Window w );
|
|
||||||
void addUnmanaged( Unmanaged* c, allowed_t );
|
|
||||||
|
|
||||||
Window findSpecialEventWindow( XEvent* e );
|
Window findSpecialEventWindow( XEvent* e );
|
||||||
|
|
||||||
|
@ -519,8 +499,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void closeActivePopup();
|
void closeActivePopup();
|
||||||
|
|
||||||
void updateClientArea( bool force );
|
void updateClientArea( bool force );
|
||||||
|
|
||||||
void finishCompositing();
|
|
||||||
|
|
||||||
SystemTrayWindowList systemTrayWins;
|
SystemTrayWindowList systemTrayWins;
|
||||||
|
|
||||||
|
@ -557,11 +535,10 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
|
|
||||||
ClientList clients;
|
ClientList clients;
|
||||||
ClientList desktops;
|
ClientList desktops;
|
||||||
UnmanagedList unmanaged;
|
|
||||||
|
|
||||||
ClientList unconstrained_stacking_order;
|
ClientList unconstrained_stacking_order; // topmost last
|
||||||
ClientList stacking_order;
|
ClientList stacking_order; // topmost last
|
||||||
QVector< ClientList > focus_chain;
|
QVector< ClientList > focus_chain; // currently ative last
|
||||||
ClientList global_focus_chain; // this one is only for things like tabbox's MRU
|
ClientList global_focus_chain; // this one is only for things like tabbox's MRU
|
||||||
ClientList should_get_focus; // last is most recent
|
ClientList should_get_focus; // last is most recent
|
||||||
ClientList attention_chain;
|
ClientList attention_chain;
|
||||||
|
@ -595,7 +572,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
|
|
||||||
QMenu *popup;
|
QMenu *popup;
|
||||||
QMenu *advanced_popup;
|
QMenu *advanced_popup;
|
||||||
QMenu *trans_popup;
|
|
||||||
QMenu *desk_popup;
|
QMenu *desk_popup;
|
||||||
int desk_popup_index;
|
int desk_popup_index;
|
||||||
|
|
||||||
|
@ -679,14 +655,12 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
bool forced_global_mouse_grab;
|
bool forced_global_mouse_grab;
|
||||||
friend class StackingUpdatesBlocker;
|
friend class StackingUpdatesBlocker;
|
||||||
|
|
||||||
KSelectionOwner* cm_selection;
|
//kompmgr
|
||||||
QTimer compositeTimer;
|
|
||||||
QTime lastCompositePaint;
|
|
||||||
int compositeRate;
|
|
||||||
QRegion damage_region;
|
|
||||||
Window overlay; // XComposite overlay window
|
|
||||||
QSlider *transSlider;
|
QSlider *transSlider;
|
||||||
QPushButton *transButton;
|
QPushButton *transButton;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend bool performTransiencyCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper for Workspace::blockStackingUpdates() being called in pairs (true/false)
|
// helper for Workspace::blockStackingUpdates() being called in pairs (true/false)
|
||||||
|
@ -829,11 +803,6 @@ inline bool Workspace::globalShortcutsDisabled() const
|
||||||
return global_shortcuts_disabled || global_shortcuts_disabled_for_client;
|
return global_shortcuts_disabled || global_shortcuts_disabled_for_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Window Workspace::overlayWindow()
|
|
||||||
{
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
inline Client* Workspace::findClient( T predicate )
|
inline Client* Workspace::findClient( T predicate )
|
||||||
{
|
{
|
||||||
|
@ -861,27 +830,7 @@ inline void Workspace::forEachClient( T procedure )
|
||||||
return forEachClient( procedure, TruePredicate());
|
return forEachClient( procedure, TruePredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value );
|
||||||
inline Unmanaged* Workspace::findUnmanaged( T predicate )
|
|
||||||
{
|
|
||||||
return findUnmanagedInList( unmanaged, predicate );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename T1, typename T2 >
|
|
||||||
inline void Workspace::forEachUnmanaged( T1 procedure, T2 predicate )
|
|
||||||
{
|
|
||||||
for ( UnmanagedList::ConstIterator it = unmanaged.begin(); it != unmanaged.end(); ++it)
|
|
||||||
if ( predicate( const_cast< const Unmanaged* >( *it)))
|
|
||||||
procedure( *it );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename T >
|
|
||||||
inline void Workspace::forEachUnmanaged( T procedure )
|
|
||||||
{
|
|
||||||
return forEachUnmanaged( procedure, TruePredicate());
|
|
||||||
}
|
|
||||||
|
|
||||||
KWIN_COMPARE_PREDICATE( ClientMatchPredicate, Client, const Client*, cl == value );
|
|
||||||
inline bool Workspace::hasClient( const Client* c )
|
inline bool Workspace::hasClient( const Client* c )
|
||||||
{
|
{
|
||||||
return findClient( ClientMatchPredicate( c ));
|
return findClient( ClientMatchPredicate( c ));
|
||||||
|
|
Loading…
Reference in New Issue