activation+focuschain: Fixed activation not handling per-output VDs

This commit is contained in:
Yuki Joou 2024-09-16 15:03:21 +02:00
parent 94e2ce9129
commit e97154ccd7
3 changed files with 44 additions and 2 deletions

View file

@ -493,6 +493,7 @@ bool Workspace::activateNextWindow(Window *window)
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(); VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
// TODO: !focusCandidate will always be true?
if (!focusCandidate && showingDesktop()) { if (!focusCandidate && showingDesktop()) {
focusCandidate = findDesktop(true, desktop); // to not break the state focusCandidate = findDesktop(true, desktop); // to not break the state
} }
@ -516,7 +517,13 @@ bool Workspace::activateNextWindow(Window *window)
} }
if (!focusCandidate) { if (!focusCandidate) {
// nope, ask the focus chain for the next candidate // 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);
} }
} }

View file

@ -252,11 +252,13 @@ Window *FocusChain::nextMostRecentlyUsed(Window *reference) const
// copied from activation.cpp // copied from activation.cpp
bool FocusChain::isUsableFocusCandidate(Window *c, Window *prev) const 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 Window *FocusChain::nextForDesktop(Window *reference, VirtualDesktop *desktop) const
{ {
qInfo("nextForDesktop");
auto it = m_desktopFocusChains.constFind(desktop); auto it = m_desktopFocusChains.constFind(desktop);
if (it == m_desktopFocusChains.constEnd()) { if (it == m_desktopFocusChains.constEnd()) {
return nullptr; return nullptr;
@ -271,6 +273,37 @@ Window *FocusChain::nextForDesktop(Window *reference, VirtualDesktop *desktop) c
return nullptr; 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) void FocusChain::makeFirstInChain(Window *window, Chain &chain)
{ {
if (window->isDeleted()) { if (window->isDeleted()) {

View file

@ -164,6 +164,8 @@ public:
*/ */
Window *firstMostRecentlyUsed() const; Window *firstMostRecentlyUsed() const;
Window *nextUsableMostRecentlyUsed(Window *reference) const;
bool isUsableFocusCandidate(Window *window, Window *prev) const; bool isUsableFocusCandidate(Window *window, Window *prev) const;
public Q_SLOTS: public Q_SLOTS: