From e97154ccd7242a349447a21e7cb155b95a13cc3f Mon Sep 17 00:00:00 2001 From: Yuki Joou Date: Mon, 16 Sep 2024 15:03:21 +0200 Subject: [PATCH] activation+focuschain: Fixed activation not handling per-output VDs --- src/activation.cpp | 9 ++++++++- src/focuschain.cpp | 35 ++++++++++++++++++++++++++++++++++- src/focuschain.h | 2 ++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/activation.cpp b/src/activation.cpp index 11143d1655..25c29351dd 100644 --- a/src/activation.cpp +++ b/src/activation.cpp @@ -493,6 +493,7 @@ bool Workspace::activateNextWindow(Window *window) VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(); + // TODO: !focusCandidate will always be true? if (!focusCandidate && showingDesktop()) { focusCandidate = findDesktop(true, desktop); // to not break the state } @@ -516,7 +517,13 @@ bool Workspace::activateNextWindow(Window *window) } if (!focusCandidate) { // nope, ask the focus chain for the next candidate - focusCandidate = m_focusChain->nextForDesktop(window, desktop); + // focusCandidate = m_focusChain->nextForDesktop(window, desktop); + + // Not using desktop-specific focus chains, there is + // probably an optimisation reason to use those. Or a + // logic reason. If something breaks, this is probably + // why! + focusCandidate = m_focusChain->nextUsableMostRecentlyUsed(window); } } diff --git a/src/focuschain.cpp b/src/focuschain.cpp index 0270204501..10b58ec6c7 100644 --- a/src/focuschain.cpp +++ b/src/focuschain.cpp @@ -252,11 +252,13 @@ Window *FocusChain::nextMostRecentlyUsed(Window *reference) const // copied from activation.cpp bool FocusChain::isUsableFocusCandidate(Window *c, Window *prev) const { - return c != prev && !c->isShade() && c->isShown() && c->isOnCurrentDesktop() && c->isOnCurrentActivity() && (!m_separateScreenFocus || c->isOnOutput(prev ? prev->output() : workspace()->activeOutput())); + // TODO: Figure out why separate screen focus doesn't work. + return c != prev && !c->isShade() && c->isShown() && c->isOnCurrentDesktop() && c->isOnCurrentActivity(); // && (!m_separateScreenFocus || c->isOnOutput(prev ? prev->output() : workspace()->activeOutput())); } Window *FocusChain::nextForDesktop(Window *reference, VirtualDesktop *desktop) const { + qInfo("nextForDesktop"); auto it = m_desktopFocusChains.constFind(desktop); if (it == m_desktopFocusChains.constEnd()) { return nullptr; @@ -271,6 +273,37 @@ Window *FocusChain::nextForDesktop(Window *reference, VirtualDesktop *desktop) c return nullptr; } +// TODO: Check that the logic actually makes sense. +Window *FocusChain::nextUsableMostRecentlyUsed(Window *reference) const +{ + if (m_mostRecentlyUsed.isEmpty()) { + return nullptr; + } + const int index = m_mostRecentlyUsed.indexOf(reference); + if (index == -1) { + auto first = m_mostRecentlyUsed.first(); + if (isUsableFocusCandidate(first, reference)) { + return first; + } + return nullptr; + } + if (index == 0) { + auto last = m_mostRecentlyUsed.last(); + if (isUsableFocusCandidate(last, reference)) { + return last; + } + return nullptr; + } + for (int i = index - 1; i >= 0; --i) { + auto window = m_mostRecentlyUsed.at(i); + if (isUsableFocusCandidate(window, reference)) { + return window; + } + } + qInfo("NULL"); + return nullptr; +} + void FocusChain::makeFirstInChain(Window *window, Chain &chain) { if (window->isDeleted()) { diff --git a/src/focuschain.h b/src/focuschain.h index 8e5baedb47..ba5559d012 100644 --- a/src/focuschain.h +++ b/src/focuschain.h @@ -164,6 +164,8 @@ public: */ Window *firstMostRecentlyUsed() const; + Window *nextUsableMostRecentlyUsed(Window *reference) const; + bool isUsableFocusCandidate(Window *window, Window *prev) const; public Q_SLOTS: