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();
// 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);
}
}

View file

@ -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()) {

View file

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