[kwin] Use std::find_if and lambda functions for Workspace::findClient
Instead of passing the macro based Predicate to findClient it now expects a function which can be passed to std::find_if. Existing code like: xcb_window_t window; // our test window Client *c = findClient(WindowMatchPredicated(window)); becomes: Client *c = findClient([window](const Client *c) { return c->window() == 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. In addition there is a simplified overload for the very common case of matching a window id against one of Client's windows. This overloaded method takes a Predicate and the window id. Above example becomes: Client *c = findClient(Predicate::WindowMatch, w); Existing code is migrated to use the simplified method taking MatchPredicate and window id. The very few cases where a more complex condition is tested the lambda function is used. As these are very local tests only used in one function it's not worthwhile to add further overloads to the findClient method in Workspace. With this change all the Predicate macro definitions are removed from utils.h as they are now completely unused. REVIEW: 116916
This commit is contained in:
parent
fe5f7fb2f6
commit
bc0a9cb53a
16 changed files with 135 additions and 101 deletions
|
@ -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<Client>(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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
10
client.cpp
10
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;
|
||||
}
|
||||
|
|
17
client.h
17
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<KWin::Client*>)
|
||||
|
|
|
@ -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();
|
||||
|
|
12
events.cpp
12
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<xcb_map_request_event_t*>(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<xcb_leave_notify_event_t*>(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;
|
||||
|
|
12
group.cpp
12
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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
14
netinfo.cpp
14
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -685,9 +685,6 @@ inline T *Toplevel::findInList(const QList<T*> &list, std::function<bool (const
|
|||
QDebug& operator<<(QDebug& stream, const Toplevel*);
|
||||
QDebug& operator<<(QDebug& stream, const ToplevelList&);
|
||||
|
||||
KWIN_COMPARE_PREDICATE(WindowMatchPredicate, Toplevel, Window, cl->window() == value);
|
||||
KWIN_COMPARE_PREDICATE(FrameIdMatchPredicate, Toplevel, Window, cl->frameId() == value);
|
||||
|
||||
} // namespace
|
||||
Q_DECLARE_METATYPE(KWin::Toplevel*)
|
||||
|
||||
|
|
34
utils.h
34
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
|
||||
|
|
|
@ -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<bool (const Client*)> 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<bool (const Unmanaged*)> 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"
|
||||
|
|
57
workspace.h
57
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<typename T> 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<bool (const Client*)> 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<bool (const Client*)>)
|
||||
*/
|
||||
Client *findClient(Predicate predicate, xcb_window_t w) const;
|
||||
void forEachClient(std::function<void (Client*)> func);
|
||||
Unmanaged *findUnmanaged(std::function<bool (const Unmanaged*)> 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()
|
||||
|
|
Loading…
Reference in a new issue