diff --git a/activation.cpp b/activation.cpp index cde06b4c37..4824645911 100644 --- a/activation.cpp +++ b/activation.cpp @@ -695,13 +695,6 @@ void Client::demandAttention(bool set) emit demandsAttentionChanged(); } -// TODO I probably shouldn't be lazy here and do it without the macro, so that people can read it -KWIN_COMPARE_PREDICATE(SameApplicationActiveHackPredicate, Client, const Client*, - // ignore already existing splashes, toolbars, utilities and menus, - // as the app may show those before the main window - !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu() - && Client::belongToSameApplication(cl, value, true) && cl != value); - xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data, bool session) const { @@ -733,17 +726,23 @@ xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, c Client* act = workspace()->mostRecentlyActivatedClient(); if (act != NULL && !belongToSameApplication(act, this, true)) { bool first_window = true; + auto sameApplicationActiveHackPredicate = [this](const Client *cl) { + // ignore already existing splashes, toolbars, utilities and menus, + // as the app may show those before the main window + return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu() + && cl != this && Client::belongToSameApplication(cl, this, true); + }; if (isTransient()) { if (act->hasTransient(this, true)) ; // is transient for currently active window, even though it's not // the same app (e.g. kcookiejar dialog) -> allow activation else if (groupTransient() && - findClientInList(mainClients(), SameApplicationActiveHackPredicate(this)) == NULL) + findInList(mainClients(), sameApplicationActiveHackPredicate) == NULL) ; // standalone transient else first_window = false; } else { - if (workspace()->findClient(SameApplicationActiveHackPredicate(this))) + if (workspace()->findClient(sameApplicationActiveHackPredicate)) first_window = false; } // don't refuse if focus stealing prevention is turned off diff --git a/appmenu.cpp b/appmenu.cpp index 2937a46ea1..d8266449c7 100644 --- a/appmenu.cpp +++ b/appmenu.cpp @@ -50,13 +50,13 @@ bool ApplicationMenu::hasMenu(xcb_window_t window) void ApplicationMenu::slotShowRequest(qulonglong wid) { - if (Client *c = Workspace::self()->findClient(WindowMatchPredicate(wid))) + if (Client *c = Workspace::self()->findClient(Predicate::WindowMatch, wid)) c->emitShowRequest(); } void ApplicationMenu::slotMenuAvailable(qulonglong wid) { - if (Client *c = Workspace::self()->findClient(WindowMatchPredicate(wid))) + if (Client *c = Workspace::self()->findClient(Predicate::WindowMatch, wid)) c->setAppMenuAvailable(); else m_windowsMenu.append(wid); @@ -64,7 +64,7 @@ void ApplicationMenu::slotMenuAvailable(qulonglong wid) void ApplicationMenu::slotMenuHidden(qulonglong wid) { - if (Client *c = Workspace::self()->findClient(WindowMatchPredicate(wid))) + if (Client *c = Workspace::self()->findClient(Predicate::WindowMatch, wid)) c->emitMenuHidden(); } diff --git a/client.cpp b/client.cpp index 7d4ef33d8b..4a9de4a438 100644 --- a/client.cpp +++ b/client.cpp @@ -1800,8 +1800,6 @@ QString Client::readName() const return KWindowSystem::readNameProperty(window(), XCB_ATOM_WM_NAME); } -KWIN_COMPARE_PREDICATE(FetchNameInternalPredicate, Client, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption()); - // The list is taken from http://www.unicode.org/reports/tr9/ (#154840) QChar LRM(0x200E); QChar RLM(0x200F); @@ -1856,12 +1854,16 @@ void Client::setCaption(const QString& _s, bool force) } QString shortcut_suffix = !shortcut().isEmpty() ? (QStringLiteral(" {") + shortcut().toString() + QStringLiteral("}")) : QString(); cap_suffix = machine_suffix + shortcut_suffix; - if ((!isSpecialWindow() || isToolbar()) && workspace()->findClient(FetchNameInternalPredicate(this))) { + auto fetchNameInternalPredicate = [this](const Client *cl) { + return (!cl->isSpecialWindow() || cl->isToolbar()) && + cl != this && cl->caption() == caption(); + }; + if ((!isSpecialWindow() || isToolbar()) && workspace()->findClient(fetchNameInternalPredicate)) { int i = 2; do { cap_suffix = machine_suffix + QStringLiteral(" <") + QString::number(i) + QStringLiteral(">") + LRM; i++; - } while (workspace()->findClient(FetchNameInternalPredicate(this))); + } while (workspace()->findClient(fetchNameInternalPredicate)); info->setVisibleName(caption().toUtf8().constData()); reset_name = false; } diff --git a/client.h b/client.h index 5f5ac91583..8737ff5bf5 100644 --- a/client.h +++ b/client.h @@ -55,6 +55,19 @@ class TabBoxClientImpl; class Bridge; class PaintRedirector; + +/** + * @brief Defines Predicates on how to search for a Client. + * + * Used by Workspace::findClient. + */ +enum class Predicate { + WindowMatch, + WrapperIdMatch, + FrameIdMatch, + InputIdMatch +}; + class Client : public Toplevel { @@ -978,7 +991,6 @@ private: static bool check_active_modal; ///< \see Client::checkActiveModal() QKeySequence _shortcut; int sm_stacking_order; - friend struct FetchNameInternalPredicate; friend struct ResetupRulesProcedure; friend class GeometryUpdatesBlocker; PaintRedirector* paintRedirector; @@ -1269,9 +1281,6 @@ inline void Client::print(T &stream) const << resourceName() << ";Caption:" << caption() << "\'"; } -KWIN_COMPARE_PREDICATE(WrapperIdMatchPredicate, Client, Window, cl->wrapperId() == value); -KWIN_COMPARE_PREDICATE(InputIdMatchPredicate, Client, Window, cl->inputId() == value); - } // namespace Q_DECLARE_METATYPE(KWin::Client*) Q_DECLARE_METATYPE(QList) diff --git a/effects.cpp b/effects.cpp index 1d6f913449..b847a03911 100644 --- a/effects.cpp +++ b/effects.cpp @@ -1112,7 +1112,7 @@ WindowQuadType EffectsHandlerImpl::newWindowQuadType() EffectWindow* EffectsHandlerImpl::findWindow(WId id) const { - if (Client* w = Workspace::self()->findClient(WindowMatchPredicate(id))) + if (Client* w = Workspace::self()->findClient(Predicate::WindowMatch, id)) return w->effectWindow(); if (Unmanaged* w = Workspace::self()->findUnmanaged(id)) return w->effectWindow(); diff --git a/events.cpp b/events.cpp index 0005151401..07eae014a5 100644 --- a/events.cpp +++ b/events.cpp @@ -234,16 +234,16 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) const xcb_window_t eventWindow = findEventWindow(e); if (eventWindow != XCB_WINDOW_NONE) { - if (Client* c = findClient(WindowMatchPredicate(eventWindow))) { + if (Client* c = findClient(Predicate::WindowMatch, eventWindow)) { if (c->windowEvent(e)) return true; - } else if (Client* c = findClient(WrapperIdMatchPredicate(eventWindow))) { + } else if (Client* c = findClient(Predicate::WrapperIdMatch, eventWindow)) { if (c->windowEvent(e)) return true; - } else if (Client* c = findClient(FrameIdMatchPredicate(eventWindow))) { + } else if (Client* c = findClient(Predicate::FrameIdMatch, eventWindow)) { if (c->windowEvent(e)) return true; - } else if (Client *c = findClient(InputIdMatchPredicate(eventWindow))) { + } else if (Client *c = findClient(Predicate::InputIdMatch, eventWindow)) { if (c->windowEvent(e)) return true; } else if (Unmanaged* c = findUnmanaged(eventWindow)) { @@ -300,7 +300,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) updateXTime(); const auto *event = reinterpret_cast(e); - if (Client* c = findClient(WindowMatchPredicate(event->window))) { + if (Client* c = findClient(Predicate::WindowMatch, event->window)) { // e->xmaprequest.window is different from e->xany.window // TODO this shouldn't be necessary now c->windowEvent(e); @@ -350,7 +350,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) break; // TODO is this cliente ever found, given that client events are searched above? const auto *event = reinterpret_cast(e); - Client* c = findClient(FrameIdMatchPredicate(event->event)); + Client* c = findClient(Predicate::FrameIdMatch, event->event); if (c && event->detail != XCB_NOTIFY_DETAIL_INFERIOR) QWhatsThis::leaveWhatsThisMode(); break; diff --git a/group.cpp b/group.cpp index 296da16844..1819f928d1 100644 --- a/group.cpp +++ b/group.cpp @@ -203,7 +203,7 @@ Group::Group(Window leader_P) refcount(0) { if (leader_P != None) { - leader_client = workspace()->findClient(WindowMatchPredicate(leader_P)); + leader_client = workspace()->findClient(Predicate::WindowMatch, leader_P); leader_info = new NETWinInfo(connection(), leader_P, rootWindow(), 0, NET::WM2StartupId); } @@ -583,7 +583,7 @@ void Client::setTransient(xcb_window_t new_transient_for_id) transient_for = NULL; m_transientForId = new_transient_for_id; if (m_transientForId != XCB_WINDOW_NONE && !groupTransient()) { - transient_for = workspace()->findClient(WindowMatchPredicate(m_transientForId)); + transient_for = workspace()->findClient(Predicate::WindowMatch, m_transientForId); assert(transient_for != NULL); // verifyTransient() had to check this transient_for->addTransient(this); } // checkGroup() will check 'check_active_modal' @@ -755,14 +755,14 @@ xcb_window_t Client::verifyTransientFor(xcb_window_t new_transient_for, bool set xcb_window_t before_search = new_transient_for; while (new_transient_for != XCB_WINDOW_NONE && new_transient_for != rootWindow() - && !workspace()->findClient(WindowMatchPredicate(new_transient_for))) { + && !workspace()->findClient(Predicate::WindowMatch, new_transient_for)) { Xcb::Tree tree(new_transient_for); if (tree.isNull()) { break; } new_transient_for = tree->parent; } - if (Client* new_transient_for_client = workspace()->findClient(WindowMatchPredicate(new_transient_for))) { + if (Client* new_transient_for_client = workspace()->findClient(Predicate::WindowMatch, new_transient_for)) { if (new_transient_for != before_search) { qDebug() << "Client " << this << " has WM_TRANSIENT_FOR poiting to non-toplevel window " << before_search << ", child of " << new_transient_for_client << ", adjusting." << endl; @@ -776,7 +776,7 @@ xcb_window_t Client::verifyTransientFor(xcb_window_t new_transient_for, bool set int count = 20; xcb_window_t loop_pos = new_transient_for; while (loop_pos != XCB_WINDOW_NONE && loop_pos != rootWindow()) { - Client* pos = workspace()->findClient(WindowMatchPredicate(loop_pos)); + Client* pos = workspace()->findClient(Predicate::WindowMatch, loop_pos); if (pos == NULL) break; loop_pos = pos->m_transientForId; @@ -786,7 +786,7 @@ xcb_window_t Client::verifyTransientFor(xcb_window_t new_transient_for, bool set } } if (new_transient_for != rootWindow() - && workspace()->findClient(WindowMatchPredicate(new_transient_for)) == NULL) { + && workspace()->findClient(Predicate::WindowMatch, new_transient_for) == NULL) { // it's transient for a specific window, but that window is not mapped new_transient_for = rootWindow(); } diff --git a/killwindow.cpp b/killwindow.cpp index f12cab9c92..d3d951c3bc 100644 --- a/killwindow.cpp +++ b/killwindow.cpp @@ -203,7 +203,7 @@ void KillWindow::killWindowId(xcb_window_t window_to_kill) xcb_window_t window = window_to_kill; Client* client = NULL; while (true) { - client = Workspace::self()->findClient(FrameIdMatchPredicate(window)); + client = Workspace::self()->findClient(Predicate::FrameIdMatch, window); if (client) { break; // Found the client } diff --git a/layers.cpp b/layers.cpp index 5dd8a4a5c8..362839a239 100644 --- a/layers.cpp +++ b/layers.cpp @@ -694,7 +694,7 @@ void Client::restackWindow(xcb_window_t above, int detail, NET::RequestSource sr { Client *other = 0; if (detail == XCB_STACK_MODE_OPPOSITE) { - other = workspace()->findClient(WindowMatchPredicate(above)); + other = workspace()->findClient(Predicate::WindowMatch, above); if (!other) { workspace()->raiseOrLowerClient(this); return; @@ -713,20 +713,20 @@ void Client::restackWindow(xcb_window_t above, int detail, NET::RequestSource sr } } else if (detail == XCB_STACK_MODE_TOP_IF) { - other = workspace()->findClient(WindowMatchPredicate(above)); + other = workspace()->findClient(Predicate::WindowMatch, above); if (other && other->geometry().intersects(geometry())) workspace()->raiseClientRequest(this, src, timestamp); return; } else if (detail == XCB_STACK_MODE_BOTTOM_IF) { - other = workspace()->findClient(WindowMatchPredicate(above)); + other = workspace()->findClient(Predicate::WindowMatch, above); if (other && other->geometry().intersects(geometry())) workspace()->lowerClientRequest(this, src, timestamp); return; } if (!other) - other = workspace()->findClient(WindowMatchPredicate(above)); + other = workspace()->findClient(Predicate::WindowMatch, above); if (other && detail == XCB_STACK_MODE_ABOVE) { ToplevelList::const_iterator it = workspace()->stackingOrder().constEnd(), diff --git a/netinfo.cpp b/netinfo.cpp index 391ffb3956..85983b478b 100644 --- a/netinfo.cpp +++ b/netinfo.cpp @@ -157,7 +157,7 @@ void RootInfo::changeCurrentDesktop(int d) void RootInfo::changeActiveWindow(xcb_window_t w, NET::RequestSource src, xcb_timestamp_t timestamp, xcb_window_t active_window) { Workspace *workspace = Workspace::self(); - if (Client* c = workspace->findClient(WindowMatchPredicate(w))) { + if (Client* c = workspace->findClient(Predicate::WindowMatch, w)) { if (timestamp == CurrentTime) timestamp = c->userTime(); if (src != NET::FromApplication && src != FromTool) @@ -172,7 +172,7 @@ void RootInfo::changeActiveWindow(xcb_window_t w, NET::RequestSource src, xcb_ti workspace->activateClient(c); // if activation of the requestor's window would be allowed, allow activation too else if (active_window != None - && (c2 = workspace->findClient(WindowMatchPredicate(active_window))) != NULL + && (c2 = workspace->findClient(Predicate::WindowMatch, active_window)) != NULL && workspace->allowClientActivation(c2, timestampCompare(timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true)) { workspace->activateClient(c); @@ -184,7 +184,7 @@ void RootInfo::changeActiveWindow(xcb_window_t w, NET::RequestSource src, xcb_ti void RootInfo::restackWindow(xcb_window_t w, RequestSource src, xcb_window_t above, int detail, xcb_timestamp_t timestamp) { - if (Client* c = Workspace::self()->findClient(WindowMatchPredicate(w))) { + if (Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w)) { if (timestamp == CurrentTime) timestamp = c->userTime(); if (src != NET::FromApplication && src != FromTool) @@ -195,14 +195,14 @@ void RootInfo::restackWindow(xcb_window_t w, RequestSource src, xcb_window_t abo void RootInfo::closeWindow(xcb_window_t w) { - Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w); if (c) c->closeWindow(); } void RootInfo::moveResize(xcb_window_t w, int x_root, int y_root, unsigned long direction) { - Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w); if (c) { updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp c->NETMoveResize(x_root, y_root, (Direction)direction); @@ -211,14 +211,14 @@ void RootInfo::moveResize(xcb_window_t w, int x_root, int y_root, unsigned long void RootInfo::moveResizeWindow(xcb_window_t w, int flags, int x, int y, int width, int height) { - Client* c = Workspace::self()->findClient(WindowMatchPredicate(w)); + Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w); if (c) c->NETMoveResizeWindow(flags, x, y, width, height); } void RootInfo::gotPing(xcb_window_t w, xcb_timestamp_t timestamp) { - if (Client* c = Workspace::self()->findClient(WindowMatchPredicate(w))) + if (Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w)) c->gotPing(timestamp); } diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp index d42222543f..cb52a828bd 100644 --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -261,7 +261,7 @@ void WorkspaceWrapper::hideOutline() Client *WorkspaceWrapper::getClient(qulonglong windowId) { - return Workspace::self()->findClient(WindowMatchPredicate(windowId)); + return Workspace::self()->findClient(Predicate::WindowMatch, windowId); } QSize WorkspaceWrapper::desktopGridSize() const diff --git a/thumbnailitem.cpp b/thumbnailitem.cpp index 531dfe8802..d4124ae14b 100644 --- a/thumbnailitem.cpp +++ b/thumbnailitem.cpp @@ -138,7 +138,7 @@ void WindowThumbnailItem::setWId(qulonglong wId) } m_wId = wId; if (m_wId != 0) { - setClient(Workspace::self()->findClient(WindowMatchPredicate(m_wId))); + setClient(Workspace::self()->findClient(Predicate::WindowMatch, m_wId)); } else if (m_client) { m_client = NULL; emit clientChanged(); @@ -165,7 +165,7 @@ void WindowThumbnailItem::paint(QPainter *painter) if (effects) { return; } - Client *client = Workspace::self()->findClient(WindowMatchPredicate(m_wId)); + Client *client = Workspace::self()->findClient(Predicate::WindowMatch, m_wId); if (!client) { return; } diff --git a/toplevel.h b/toplevel.h index 70775e538b..f8a05bead8 100644 --- a/toplevel.h +++ b/toplevel.h @@ -685,9 +685,6 @@ inline T *Toplevel::findInList(const QList &list, std::functionwindow() == value); -KWIN_COMPARE_PREDICATE(FrameIdMatchPredicate, Toplevel, Window, cl->frameId() == value); - } // namespace Q_DECLARE_METATYPE(KWin::Toplevel*) diff --git a/utils.h b/utils.h index 9deae736c3..99291d64ff 100644 --- a/utils.h +++ b/utils.h @@ -156,40 +156,6 @@ public: #define UrgencyHint XUrgencyHint #endif -// for STL-like algo's -#define KWIN_CHECK_PREDICATE( name, cls, check ) \ - struct name \ - { \ - inline bool operator()( const cls* cl ) { return check; } \ - } - -#define KWIN_COMPARE_PREDICATE( name, cls, type, check ) \ - struct name \ - { \ - typedef type type_helper; /* in order to work also with type being 'const Client*' etc. */ \ - inline name( const type_helper& compare_value ) : value( compare_value ) {} \ - inline bool operator()( const cls* cl ) { return check; } \ - const type_helper& value; \ - } - -#define KWIN_PROCEDURE( name, cls, action ) \ - struct name \ - { \ - inline void operator()( cls* cl ) { action; } \ - } - -KWIN_CHECK_PREDICATE(TruePredicate, Client, cl == cl /*true, avoid warning about 'cl' */); - -template< typename T > -Client* findClientInList(const ClientList& list, T predicate) -{ - for (ClientList::ConstIterator it = list.begin(); it != list.end(); ++it) { - if (predicate(const_cast< const Client* >(*it))) - return *it; - } - return NULL; -} - QPoint cursorPos(); // converting between X11 mouse/keyboard state mask and Qt button/keyboard states diff --git a/workspace.cpp b/workspace.cpp index 50df1d6cd2..3d2c672752 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -381,7 +381,7 @@ void Workspace::init() Client* new_active_client = NULL; if (!qApp->isSessionRestored()) { --block_focus; - new_active_client = findClient(WindowMatchPredicate(client_info.activeWindow())); + new_active_client = findClient(Predicate::WindowMatch, client_info.activeWindow()); } if (new_active_client == NULL && activeClient() == NULL && should_get_focus.count() == 0) { @@ -1527,6 +1527,17 @@ void Workspace::slotToggleCompositing() } } +Client *Workspace::findClient(std::function func) const +{ + if (Client *ret = Toplevel::findInList(clients, func)) { + return ret; + } + if (Client *ret = Toplevel::findInList(desktops, func)) { + return ret; + } + return nullptr; +} + Unmanaged *Workspace::findUnmanaged(std::function func) const { return Toplevel::findInList(unmanaged, func); @@ -1539,6 +1550,29 @@ Unmanaged *Workspace::findUnmanaged(xcb_window_t w) const }); } +Client *Workspace::findClient(Predicate predicate, xcb_window_t w) const +{ + switch (predicate) { + case Predicate::WindowMatch: + return findClient([w](const Client *c) { + return c->window() == w; + }); + case Predicate::WrapperIdMatch: + return findClient([w](const Client *c) { + return c->wrapperId() == w; + }); + case Predicate::FrameIdMatch: + return findClient([w](const Client *c) { + return c->frameId() == w; + }); + case Predicate::InputIdMatch: + return findClient([w](const Client *c) { + return c->inputId() == w; + }); + } + return nullptr; +} + } // namespace #include "workspace.moc" diff --git a/workspace.h b/workspace.h index f3ef7b9e73..71c328e4f4 100644 --- a/workspace.h +++ b/workspace.h @@ -55,6 +55,7 @@ class KillWindow; class ShortcutDialog; class UserActionsMenu; class Compositor; +enum class Predicate; class Workspace : public QObject, public KDecorationDefines { @@ -72,7 +73,44 @@ public: bool hasClient(const Client*); - template Client* findClient(T predicate) const; + /** + * @brief Finds the first Client matching the condition expressed by passed in @p func. + * + * Internally findClient uses the std::find_if algorithm and that determines how the function + * needs to be implemented. An example usage for finding a Client with a matching windowId + * @code + * xcb_window_t w; // our test window + * Client *client = findClient([w](const Client *c) -> bool { + * return c->window() == w; + * }); + * @endcode + * + * For the standard cases of matching the window id with one of the Client's windows use + * the simplified overload method findClient(Predicate, xcb_window_t). Above example + * can be simplified to: + * @code + * xcb_window_t w; // our test window + * Client *client = findClient(Predicate::WindowMatch, w); + * @endcode + * + * @param func Unary function that accepts a Client* as argument and + * returns a value convertible to bool. The value returned indicates whether the + * Client* is considered a match in the context of this function. + * The function shall not modify its argument. + * This can either be a function pointer or a function object. + * @return KWin::Client* The found Client or @c null + * @see findClient(Predicate, xcb_window_t) + */ + Client *findClient(std::function func) const; + /** + * @brief Finds the Client matching the given match @p predicate for the given window. + * + * @param predicate Which window should be compared + * @param w The window id to test against + * @return KWin::Client* The found Client or @c null + * @see findClient(std::function) + */ + Client *findClient(Predicate predicate, xcb_window_t w) const; void forEachClient(std::function func); Unmanaged *findUnmanaged(std::function func) const; /** @@ -659,17 +697,6 @@ inline QPoint Workspace::focusMousePosition() const return focusMousePos; } -template< typename T > -inline Client* Workspace::findClient(T predicate) const -{ - if (Client* ret = findClientInList(clients, predicate)) - return ret; - if (Client* ret = findClientInList(desktops, predicate)) - return ret; - return NULL; -} - - inline void Workspace::forEachClient(std::function< void (Client*) > func) { @@ -683,11 +710,11 @@ void Workspace::forEachUnmanaged(std::function< void (Unmanaged*) > func) std::for_each(unmanaged.constBegin(), unmanaged.constEnd(), func); } -KWIN_COMPARE_PREDICATE(ClientMatchPredicate, Client, const Client*, cl == value); - inline bool Workspace::hasClient(const Client* c) { - return findClient(ClientMatchPredicate(c)); + return findClient([c](const Client *test) { + return test == c; + }); } inline Workspace *workspace()