[kwin] Use std::find_if and lambda functions for Workspace::findUnmanaged

Instead of passing the macro based Predicate to findUnmanaged it now
expects a function which can be passed to std::find_if.

Existing code like:
xcb_window_t window; // our test window
Unmanaged *u = findUnmanaged(WindowMatchPredicated(window));

becomes:
Unmanaged *u = findUnmanaged([window](const Unmanaged *u) {
    return u->window() == window;
});

In addition an overload is added which takes the window id to cover
the common case to search for an Unmanaged by its ID. The above example
becomes:
Unmanaged *u = findUnmanaged(window);

The advantage is that it is way more flexible and has the logic what
to check for directly with the code and not hidden in the macro
definition.
icc-effect-5.14.5
Martin Gräßlin 2014-03-20 07:52:18 +01:00
parent 970e8765f0
commit 12a4923959
8 changed files with 47 additions and 22 deletions

View File

@ -1114,7 +1114,7 @@ EffectWindow* EffectsHandlerImpl::findWindow(WId id) const
{
if (Client* w = Workspace::self()->findClient(WindowMatchPredicate(id)))
return w->effectWindow();
if (Unmanaged* w = Workspace::self()->findUnmanaged(WindowMatchPredicate(id)))
if (Unmanaged* w = Workspace::self()->findUnmanaged(id))
return w->effectWindow();
return NULL;
}

View File

@ -246,7 +246,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
} else if (Client *c = findClient(InputIdMatchPredicate(eventWindow))) {
if (c->windowEvent(e))
return true;
} else if (Unmanaged* c = findUnmanaged(WindowMatchPredicate(eventWindow))) {
} else if (Unmanaged* c = findUnmanaged(eventWindow)) {
if (c->windowEvent(e))
return true;
} else {
@ -324,7 +324,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
case XCB_MAP_NOTIFY: {
const auto *event = reinterpret_cast<xcb_map_notify_event_t*>(e);
if (event->override_redirect) {
Unmanaged* c = findUnmanaged(WindowMatchPredicate(event->window));
Unmanaged* c = findUnmanaged(event->window);
if (c == NULL)
c = createUnmanaged(event->window);
if (c)

View File

@ -677,7 +677,7 @@ ToplevelList Workspace::xStackingOrder() const
for (unsigned int i = 0;
i < tree->children_len;
++i) {
if (Unmanaged* c = findUnmanaged(WindowMatchPredicate(windows[ i ])))
if (Unmanaged* c = findUnmanaged(windows[i]))
x_stacking.append(c);
}
if (m_compositor) {

View File

@ -307,7 +307,7 @@ void TabBoxHandlerImpl::elevateClient(TabBoxClient *c, WId tabbox, bool b) const
{
Client *cl = static_cast<TabBoxClientImpl*>(c)->client();
cl->elevate(b);
if (Unmanaged *w = Workspace::self()->findUnmanaged(WindowMatchPredicate(tabbox)))
if (Unmanaged *w = Workspace::self()->findUnmanaged(tabbox))
w->elevate(b);
}

View File

@ -327,6 +327,18 @@ public:
virtual void sendPointerAxisEvent(InputRedirection::PointerAxis axis, qreal delta);
virtual void sendKeybordKeyEvent(uint32_t key, InputRedirection::KeyboardKeyState state);
/**
* @brief Finds the Toplevel matching the condition expressed in @p func in @p list.
*
* The method is templated to operate on either a list of Toplevels or on a list of
* a subclass type of Toplevel.
* @param list The list to search in
* @param func The condition function (compare std::find_if)
* @return T* The found Toplevel or @c null if there is no matching Toplevel
*/
template <class T>
static T *findInList(const QList<T*> &list, std::function<bool (const T*)> func);
Q_SIGNALS:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
void damaged(KWin::Toplevel* toplevel, const QRect& damage);
@ -660,6 +672,16 @@ inline const ClientMachine *Toplevel::clientMachine() const
return m_clientMachine;
}
template <class T>
inline T *Toplevel::findInList(const QList<T*> &list, std::function<bool (const T*)> func)
{
const auto it = std::find_if(list.begin(), list.end(), func);
if (it == list.end()) {
return nullptr;
}
return *it;
}
QDebug& operator<<(QDebug& stream, const Toplevel*);
QDebug& operator<<(QDebug& stream, const ToplevelList&);

10
utils.h
View File

@ -190,16 +190,6 @@ Client* findClientInList(const ClientList& list, T predicate)
return NULL;
}
template< typename T >
Unmanaged* findUnmanagedInList(const UnmanagedList& list, T predicate)
{
for (UnmanagedList::ConstIterator it = list.begin(); it != list.end(); ++it) {
if (predicate(const_cast< const Unmanaged* >(*it)))
return *it;
}
return NULL;
}
QPoint cursorPos();
// converting between X11 mouse/keyboard state mask and Qt button/keyboard states

View File

@ -1527,6 +1527,18 @@ void Workspace::slotToggleCompositing()
}
}
Unmanaged *Workspace::findUnmanaged(std::function<bool (const Unmanaged*)> func) const
{
return Toplevel::findInList(unmanaged, func);
}
Unmanaged *Workspace::findUnmanaged(xcb_window_t w) const
{
return findUnmanaged([w](const Unmanaged *u) {
return u->window() == w;
});
}
} // namespace
#include "workspace.moc"

View File

@ -76,7 +76,14 @@ public:
template<typename T1, typename T2> void forEachClient(T1 procedure, T2 predicate);
template<typename T> void forEachClient(T procedure);
void forEachClient(std::function<void (Client*)> func);
template<typename T> Unmanaged* findUnmanaged(T predicate) const;
Unmanaged *findUnmanaged(std::function<bool (const Unmanaged*)> func) const;
/**
* @brief Finds the Unmanaged with the given window id.
*
* @param w The window id to search for
* @return KWin::Unmanaged* Found Unmanaged or @c null if there is no Unmanaged with given Id.
*/
Unmanaged *findUnmanaged(xcb_window_t w) const;
template<typename T1, typename T2> void forEachUnmanaged(T1 procedure, T2 predicate);
template<typename T> void forEachUnmanaged(T procedure);
void forEachUnmanaged(std::function<void (Unmanaged*)> func);
@ -690,12 +697,6 @@ inline void Workspace::forEachClient(T procedure)
return forEachClient(procedure, TruePredicate());
}
template< typename T >
inline Unmanaged* Workspace::findUnmanaged(T predicate) const
{
return findUnmanagedInList(unmanaged, predicate);
}
template< typename T1, typename T2 >
inline void Workspace::forEachUnmanaged(T1 procedure, T2 predicate)
{