[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();
|
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,
|
xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data,
|
||||||
bool session) const
|
bool session) const
|
||||||
{
|
{
|
||||||
|
@ -733,17 +726,23 @@ xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, c
|
||||||
Client* act = workspace()->mostRecentlyActivatedClient();
|
Client* act = workspace()->mostRecentlyActivatedClient();
|
||||||
if (act != NULL && !belongToSameApplication(act, this, true)) {
|
if (act != NULL && !belongToSameApplication(act, this, true)) {
|
||||||
bool first_window = 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 (isTransient()) {
|
||||||
if (act->hasTransient(this, true))
|
if (act->hasTransient(this, true))
|
||||||
; // is transient for currently active window, even though it's not
|
; // is transient for currently active window, even though it's not
|
||||||
// the same app (e.g. kcookiejar dialog) -> allow activation
|
// the same app (e.g. kcookiejar dialog) -> allow activation
|
||||||
else if (groupTransient() &&
|
else if (groupTransient() &&
|
||||||
findClientInList(mainClients(), SameApplicationActiveHackPredicate(this)) == NULL)
|
findInList<Client>(mainClients(), sameApplicationActiveHackPredicate) == NULL)
|
||||||
; // standalone transient
|
; // standalone transient
|
||||||
else
|
else
|
||||||
first_window = false;
|
first_window = false;
|
||||||
} else {
|
} else {
|
||||||
if (workspace()->findClient(SameApplicationActiveHackPredicate(this)))
|
if (workspace()->findClient(sameApplicationActiveHackPredicate))
|
||||||
first_window = false;
|
first_window = false;
|
||||||
}
|
}
|
||||||
// don't refuse if focus stealing prevention is turned off
|
// 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)
|
void ApplicationMenu::slotShowRequest(qulonglong wid)
|
||||||
{
|
{
|
||||||
if (Client *c = Workspace::self()->findClient(WindowMatchPredicate(wid)))
|
if (Client *c = Workspace::self()->findClient(Predicate::WindowMatch, wid))
|
||||||
c->emitShowRequest();
|
c->emitShowRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationMenu::slotMenuAvailable(qulonglong wid)
|
void ApplicationMenu::slotMenuAvailable(qulonglong wid)
|
||||||
{
|
{
|
||||||
if (Client *c = Workspace::self()->findClient(WindowMatchPredicate(wid)))
|
if (Client *c = Workspace::self()->findClient(Predicate::WindowMatch, wid))
|
||||||
c->setAppMenuAvailable();
|
c->setAppMenuAvailable();
|
||||||
else
|
else
|
||||||
m_windowsMenu.append(wid);
|
m_windowsMenu.append(wid);
|
||||||
|
@ -64,7 +64,7 @@ void ApplicationMenu::slotMenuAvailable(qulonglong wid)
|
||||||
|
|
||||||
void ApplicationMenu::slotMenuHidden(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();
|
c->emitMenuHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
client.cpp
10
client.cpp
|
@ -1800,8 +1800,6 @@ QString Client::readName() const
|
||||||
return KWindowSystem::readNameProperty(window(), XCB_ATOM_WM_NAME);
|
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)
|
// The list is taken from http://www.unicode.org/reports/tr9/ (#154840)
|
||||||
QChar LRM(0x200E);
|
QChar LRM(0x200E);
|
||||||
QChar RLM(0x200F);
|
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();
|
QString shortcut_suffix = !shortcut().isEmpty() ? (QStringLiteral(" {") + shortcut().toString() + QStringLiteral("}")) : QString();
|
||||||
cap_suffix = machine_suffix + shortcut_suffix;
|
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;
|
int i = 2;
|
||||||
do {
|
do {
|
||||||
cap_suffix = machine_suffix + QStringLiteral(" <") + QString::number(i) + QStringLiteral(">") + LRM;
|
cap_suffix = machine_suffix + QStringLiteral(" <") + QString::number(i) + QStringLiteral(">") + LRM;
|
||||||
i++;
|
i++;
|
||||||
} while (workspace()->findClient(FetchNameInternalPredicate(this)));
|
} while (workspace()->findClient(fetchNameInternalPredicate));
|
||||||
info->setVisibleName(caption().toUtf8().constData());
|
info->setVisibleName(caption().toUtf8().constData());
|
||||||
reset_name = false;
|
reset_name = false;
|
||||||
}
|
}
|
||||||
|
|
17
client.h
17
client.h
|
@ -55,6 +55,19 @@ class TabBoxClientImpl;
|
||||||
class Bridge;
|
class Bridge;
|
||||||
class PaintRedirector;
|
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
|
class Client
|
||||||
: public Toplevel
|
: public Toplevel
|
||||||
{
|
{
|
||||||
|
@ -978,7 +991,6 @@ private:
|
||||||
static bool check_active_modal; ///< \see Client::checkActiveModal()
|
static bool check_active_modal; ///< \see Client::checkActiveModal()
|
||||||
QKeySequence _shortcut;
|
QKeySequence _shortcut;
|
||||||
int sm_stacking_order;
|
int sm_stacking_order;
|
||||||
friend struct FetchNameInternalPredicate;
|
|
||||||
friend struct ResetupRulesProcedure;
|
friend struct ResetupRulesProcedure;
|
||||||
friend class GeometryUpdatesBlocker;
|
friend class GeometryUpdatesBlocker;
|
||||||
PaintRedirector* paintRedirector;
|
PaintRedirector* paintRedirector;
|
||||||
|
@ -1269,9 +1281,6 @@ inline void Client::print(T &stream) const
|
||||||
<< resourceName() << ";Caption:" << caption() << "\'";
|
<< resourceName() << ";Caption:" << caption() << "\'";
|
||||||
}
|
}
|
||||||
|
|
||||||
KWIN_COMPARE_PREDICATE(WrapperIdMatchPredicate, Client, Window, cl->wrapperId() == value);
|
|
||||||
KWIN_COMPARE_PREDICATE(InputIdMatchPredicate, Client, Window, cl->inputId() == value);
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
Q_DECLARE_METATYPE(KWin::Client*)
|
Q_DECLARE_METATYPE(KWin::Client*)
|
||||||
Q_DECLARE_METATYPE(QList<KWin::Client*>)
|
Q_DECLARE_METATYPE(QList<KWin::Client*>)
|
||||||
|
|
|
@ -1112,7 +1112,7 @@ WindowQuadType EffectsHandlerImpl::newWindowQuadType()
|
||||||
|
|
||||||
EffectWindow* EffectsHandlerImpl::findWindow(WId id) const
|
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();
|
return w->effectWindow();
|
||||||
if (Unmanaged* w = Workspace::self()->findUnmanaged(id))
|
if (Unmanaged* w = Workspace::self()->findUnmanaged(id))
|
||||||
return w->effectWindow();
|
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);
|
const xcb_window_t eventWindow = findEventWindow(e);
|
||||||
if (eventWindow != XCB_WINDOW_NONE) {
|
if (eventWindow != XCB_WINDOW_NONE) {
|
||||||
if (Client* c = findClient(WindowMatchPredicate(eventWindow))) {
|
if (Client* c = findClient(Predicate::WindowMatch, eventWindow)) {
|
||||||
if (c->windowEvent(e))
|
if (c->windowEvent(e))
|
||||||
return true;
|
return true;
|
||||||
} else if (Client* c = findClient(WrapperIdMatchPredicate(eventWindow))) {
|
} else if (Client* c = findClient(Predicate::WrapperIdMatch, eventWindow)) {
|
||||||
if (c->windowEvent(e))
|
if (c->windowEvent(e))
|
||||||
return true;
|
return true;
|
||||||
} else if (Client* c = findClient(FrameIdMatchPredicate(eventWindow))) {
|
} else if (Client* c = findClient(Predicate::FrameIdMatch, eventWindow)) {
|
||||||
if (c->windowEvent(e))
|
if (c->windowEvent(e))
|
||||||
return true;
|
return true;
|
||||||
} else if (Client *c = findClient(InputIdMatchPredicate(eventWindow))) {
|
} else if (Client *c = findClient(Predicate::InputIdMatch, eventWindow)) {
|
||||||
if (c->windowEvent(e))
|
if (c->windowEvent(e))
|
||||||
return true;
|
return true;
|
||||||
} else if (Unmanaged* c = findUnmanaged(eventWindow)) {
|
} else if (Unmanaged* c = findUnmanaged(eventWindow)) {
|
||||||
|
@ -300,7 +300,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
||||||
updateXTime();
|
updateXTime();
|
||||||
|
|
||||||
const auto *event = reinterpret_cast<xcb_map_request_event_t*>(e);
|
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
|
// e->xmaprequest.window is different from e->xany.window
|
||||||
// TODO this shouldn't be necessary now
|
// TODO this shouldn't be necessary now
|
||||||
c->windowEvent(e);
|
c->windowEvent(e);
|
||||||
|
@ -350,7 +350,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
||||||
break;
|
break;
|
||||||
// TODO is this cliente ever found, given that client events are searched above?
|
// TODO is this cliente ever found, given that client events are searched above?
|
||||||
const auto *event = reinterpret_cast<xcb_leave_notify_event_t*>(e);
|
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)
|
if (c && event->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
QWhatsThis::leaveWhatsThisMode();
|
QWhatsThis::leaveWhatsThisMode();
|
||||||
break;
|
break;
|
||||||
|
|
12
group.cpp
12
group.cpp
|
@ -203,7 +203,7 @@ Group::Group(Window leader_P)
|
||||||
refcount(0)
|
refcount(0)
|
||||||
{
|
{
|
||||||
if (leader_P != None) {
|
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(),
|
leader_info = new NETWinInfo(connection(), leader_P, rootWindow(),
|
||||||
0, NET::WM2StartupId);
|
0, NET::WM2StartupId);
|
||||||
}
|
}
|
||||||
|
@ -583,7 +583,7 @@ void Client::setTransient(xcb_window_t new_transient_for_id)
|
||||||
transient_for = NULL;
|
transient_for = NULL;
|
||||||
m_transientForId = new_transient_for_id;
|
m_transientForId = new_transient_for_id;
|
||||||
if (m_transientForId != XCB_WINDOW_NONE && !groupTransient()) {
|
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
|
assert(transient_for != NULL); // verifyTransient() had to check this
|
||||||
transient_for->addTransient(this);
|
transient_for->addTransient(this);
|
||||||
} // checkGroup() will check 'check_active_modal'
|
} // 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;
|
xcb_window_t before_search = new_transient_for;
|
||||||
while (new_transient_for != XCB_WINDOW_NONE
|
while (new_transient_for != XCB_WINDOW_NONE
|
||||||
&& new_transient_for != rootWindow()
|
&& new_transient_for != rootWindow()
|
||||||
&& !workspace()->findClient(WindowMatchPredicate(new_transient_for))) {
|
&& !workspace()->findClient(Predicate::WindowMatch, new_transient_for)) {
|
||||||
Xcb::Tree tree(new_transient_for);
|
Xcb::Tree tree(new_transient_for);
|
||||||
if (tree.isNull()) {
|
if (tree.isNull()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new_transient_for = tree->parent;
|
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) {
|
if (new_transient_for != before_search) {
|
||||||
qDebug() << "Client " << this << " has WM_TRANSIENT_FOR poiting to non-toplevel window "
|
qDebug() << "Client " << this << " has WM_TRANSIENT_FOR poiting to non-toplevel window "
|
||||||
<< before_search << ", child of " << new_transient_for_client << ", adjusting." << endl;
|
<< 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;
|
int count = 20;
|
||||||
xcb_window_t loop_pos = new_transient_for;
|
xcb_window_t loop_pos = new_transient_for;
|
||||||
while (loop_pos != XCB_WINDOW_NONE && loop_pos != rootWindow()) {
|
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)
|
if (pos == NULL)
|
||||||
break;
|
break;
|
||||||
loop_pos = pos->m_transientForId;
|
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()
|
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
|
// it's transient for a specific window, but that window is not mapped
|
||||||
new_transient_for = rootWindow();
|
new_transient_for = rootWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ void KillWindow::killWindowId(xcb_window_t window_to_kill)
|
||||||
xcb_window_t window = window_to_kill;
|
xcb_window_t window = window_to_kill;
|
||||||
Client* client = NULL;
|
Client* client = NULL;
|
||||||
while (true) {
|
while (true) {
|
||||||
client = Workspace::self()->findClient(FrameIdMatchPredicate(window));
|
client = Workspace::self()->findClient(Predicate::FrameIdMatch, window);
|
||||||
if (client) {
|
if (client) {
|
||||||
break; // Found the client
|
break; // Found the client
|
||||||
}
|
}
|
||||||
|
|
|
@ -694,7 +694,7 @@ void Client::restackWindow(xcb_window_t above, int detail, NET::RequestSource sr
|
||||||
{
|
{
|
||||||
Client *other = 0;
|
Client *other = 0;
|
||||||
if (detail == XCB_STACK_MODE_OPPOSITE) {
|
if (detail == XCB_STACK_MODE_OPPOSITE) {
|
||||||
other = workspace()->findClient(WindowMatchPredicate(above));
|
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||||
if (!other) {
|
if (!other) {
|
||||||
workspace()->raiseOrLowerClient(this);
|
workspace()->raiseOrLowerClient(this);
|
||||||
return;
|
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) {
|
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()))
|
if (other && other->geometry().intersects(geometry()))
|
||||||
workspace()->raiseClientRequest(this, src, timestamp);
|
workspace()->raiseClientRequest(this, src, timestamp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (detail == XCB_STACK_MODE_BOTTOM_IF) {
|
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()))
|
if (other && other->geometry().intersects(geometry()))
|
||||||
workspace()->lowerClientRequest(this, src, timestamp);
|
workspace()->lowerClientRequest(this, src, timestamp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!other)
|
if (!other)
|
||||||
other = workspace()->findClient(WindowMatchPredicate(above));
|
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||||
|
|
||||||
if (other && detail == XCB_STACK_MODE_ABOVE) {
|
if (other && detail == XCB_STACK_MODE_ABOVE) {
|
||||||
ToplevelList::const_iterator it = workspace()->stackingOrder().constEnd(),
|
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)
|
void RootInfo::changeActiveWindow(xcb_window_t w, NET::RequestSource src, xcb_timestamp_t timestamp, xcb_window_t active_window)
|
||||||
{
|
{
|
||||||
Workspace *workspace = Workspace::self();
|
Workspace *workspace = Workspace::self();
|
||||||
if (Client* c = workspace->findClient(WindowMatchPredicate(w))) {
|
if (Client* c = workspace->findClient(Predicate::WindowMatch, w)) {
|
||||||
if (timestamp == CurrentTime)
|
if (timestamp == CurrentTime)
|
||||||
timestamp = c->userTime();
|
timestamp = c->userTime();
|
||||||
if (src != NET::FromApplication && src != FromTool)
|
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);
|
workspace->activateClient(c);
|
||||||
// if activation of the requestor's window would be allowed, allow activation too
|
// if activation of the requestor's window would be allowed, allow activation too
|
||||||
else if (active_window != None
|
else if (active_window != None
|
||||||
&& (c2 = workspace->findClient(WindowMatchPredicate(active_window))) != NULL
|
&& (c2 = workspace->findClient(Predicate::WindowMatch, active_window)) != NULL
|
||||||
&& workspace->allowClientActivation(c2,
|
&& workspace->allowClientActivation(c2,
|
||||||
timestampCompare(timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true)) {
|
timestampCompare(timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true)) {
|
||||||
workspace->activateClient(c);
|
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)
|
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)
|
if (timestamp == CurrentTime)
|
||||||
timestamp = c->userTime();
|
timestamp = c->userTime();
|
||||||
if (src != NET::FromApplication && src != FromTool)
|
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)
|
void RootInfo::closeWindow(xcb_window_t w)
|
||||||
{
|
{
|
||||||
Client* c = Workspace::self()->findClient(WindowMatchPredicate(w));
|
Client* c = Workspace::self()->findClient(Predicate::WindowMatch, w);
|
||||||
if (c)
|
if (c)
|
||||||
c->closeWindow();
|
c->closeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootInfo::moveResize(xcb_window_t w, int x_root, int y_root, unsigned long direction)
|
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) {
|
if (c) {
|
||||||
updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp
|
updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp
|
||||||
c->NETMoveResize(x_root, y_root, (Direction)direction);
|
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)
|
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)
|
if (c)
|
||||||
c->NETMoveResizeWindow(flags, x, y, width, height);
|
c->NETMoveResizeWindow(flags, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootInfo::gotPing(xcb_window_t w, xcb_timestamp_t timestamp)
|
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);
|
c->gotPing(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ void WorkspaceWrapper::hideOutline()
|
||||||
|
|
||||||
Client *WorkspaceWrapper::getClient(qulonglong windowId)
|
Client *WorkspaceWrapper::getClient(qulonglong windowId)
|
||||||
{
|
{
|
||||||
return Workspace::self()->findClient(WindowMatchPredicate(windowId));
|
return Workspace::self()->findClient(Predicate::WindowMatch, windowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize WorkspaceWrapper::desktopGridSize() const
|
QSize WorkspaceWrapper::desktopGridSize() const
|
||||||
|
|
|
@ -138,7 +138,7 @@ void WindowThumbnailItem::setWId(qulonglong wId)
|
||||||
}
|
}
|
||||||
m_wId = wId;
|
m_wId = wId;
|
||||||
if (m_wId != 0) {
|
if (m_wId != 0) {
|
||||||
setClient(Workspace::self()->findClient(WindowMatchPredicate(m_wId)));
|
setClient(Workspace::self()->findClient(Predicate::WindowMatch, m_wId));
|
||||||
} else if (m_client) {
|
} else if (m_client) {
|
||||||
m_client = NULL;
|
m_client = NULL;
|
||||||
emit clientChanged();
|
emit clientChanged();
|
||||||
|
@ -165,7 +165,7 @@ void WindowThumbnailItem::paint(QPainter *painter)
|
||||||
if (effects) {
|
if (effects) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client *client = Workspace::self()->findClient(WindowMatchPredicate(m_wId));
|
Client *client = Workspace::self()->findClient(Predicate::WindowMatch, m_wId);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
return;
|
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 Toplevel*);
|
||||||
QDebug& operator<<(QDebug& stream, const ToplevelList&);
|
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
|
} // namespace
|
||||||
Q_DECLARE_METATYPE(KWin::Toplevel*)
|
Q_DECLARE_METATYPE(KWin::Toplevel*)
|
||||||
|
|
||||||
|
|
34
utils.h
34
utils.h
|
@ -156,40 +156,6 @@ public:
|
||||||
#define UrgencyHint XUrgencyHint
|
#define UrgencyHint XUrgencyHint
|
||||||
#endif
|
#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();
|
QPoint cursorPos();
|
||||||
|
|
||||||
// converting between X11 mouse/keyboard state mask and Qt button/keyboard states
|
// converting between X11 mouse/keyboard state mask and Qt button/keyboard states
|
||||||
|
|
|
@ -381,7 +381,7 @@ void Workspace::init()
|
||||||
Client* new_active_client = NULL;
|
Client* new_active_client = NULL;
|
||||||
if (!qApp->isSessionRestored()) {
|
if (!qApp->isSessionRestored()) {
|
||||||
--block_focus;
|
--block_focus;
|
||||||
new_active_client = findClient(WindowMatchPredicate(client_info.activeWindow()));
|
new_active_client = findClient(Predicate::WindowMatch, client_info.activeWindow());
|
||||||
}
|
}
|
||||||
if (new_active_client == NULL
|
if (new_active_client == NULL
|
||||||
&& activeClient() == NULL && should_get_focus.count() == 0) {
|
&& 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
|
Unmanaged *Workspace::findUnmanaged(std::function<bool (const Unmanaged*)> func) const
|
||||||
{
|
{
|
||||||
return Toplevel::findInList(unmanaged, func);
|
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
|
} // namespace
|
||||||
|
|
||||||
#include "workspace.moc"
|
#include "workspace.moc"
|
||||||
|
|
57
workspace.h
57
workspace.h
|
@ -55,6 +55,7 @@ class KillWindow;
|
||||||
class ShortcutDialog;
|
class ShortcutDialog;
|
||||||
class UserActionsMenu;
|
class UserActionsMenu;
|
||||||
class Compositor;
|
class Compositor;
|
||||||
|
enum class Predicate;
|
||||||
|
|
||||||
class Workspace : public QObject, public KDecorationDefines
|
class Workspace : public QObject, public KDecorationDefines
|
||||||
{
|
{
|
||||||
|
@ -72,7 +73,44 @@ public:
|
||||||
|
|
||||||
bool hasClient(const Client*);
|
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);
|
void forEachClient(std::function<void (Client*)> func);
|
||||||
Unmanaged *findUnmanaged(std::function<bool (const Unmanaged*)> func) const;
|
Unmanaged *findUnmanaged(std::function<bool (const Unmanaged*)> func) const;
|
||||||
/**
|
/**
|
||||||
|
@ -659,17 +697,6 @@ inline QPoint Workspace::focusMousePosition() const
|
||||||
return focusMousePos;
|
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
|
inline
|
||||||
void Workspace::forEachClient(std::function< void (Client*) > func)
|
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);
|
std::for_each(unmanaged.constBegin(), unmanaged.constEnd(), func);
|
||||||
}
|
}
|
||||||
|
|
||||||
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([c](const Client *test) {
|
||||||
|
return test == c;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Workspace *workspace()
|
inline Workspace *workspace()
|
||||||
|
|
Loading…
Reference in a new issue