Prefer activating desktop window on active output

Workspace::findDesktop() doesn't take into account the current active
output, and instead returns the first top desktop window found in the
stack. This means that the active output may drift and the focus chain
logic can break.

BUG: 493735
BUG: 494332
(cherry picked from commit 47a2a2e12a)
wilder/Plasma/6.2
Vlad Zahorodnii 1 year ago
parent d7073839c2
commit 72d64a3b96
  1. 9
      src/activation.cpp
  2. 6
      src/layers.cpp
  3. 10
      src/workspace.cpp
  4. 2
      src/workspace.h

@ -492,13 +492,14 @@ bool Workspace::activateNextWindow(Window *window)
Window *focusCandidate = nullptr;
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
Output *output = window ? window->output() : workspace()->activeOutput();
if (!focusCandidate && showingDesktop()) {
focusCandidate = findDesktop(true, desktop); // to not break the state
focusCandidate = findDesktop(true, desktop, output); // to not break the state
}
if (!focusCandidate && options->isNextFocusPrefersMouse()) {
focusCandidate = windowUnderMouse(window ? window->output() : workspace()->activeOutput());
focusCandidate = windowUnderMouse(output);
if (focusCandidate && (focusCandidate == window || focusCandidate->isDesktop())) {
// should rather not happen, but it cannot get the focus. rest of usability is tested above
focusCandidate = nullptr;
@ -521,7 +522,7 @@ bool Workspace::activateNextWindow(Window *window)
}
if (focusCandidate == nullptr) { // last chance: focus the desktop
focusCandidate = findDesktop(true, desktop);
focusCandidate = findDesktop(true, desktop, output);
}
if (focusCandidate != nullptr) {
@ -542,7 +543,7 @@ void Workspace::switchToOutput(Output *output)
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
Window *get_focus = m_focusChain->getForActivation(desktop, output);
if (get_focus == nullptr) {
get_focus = findDesktop(true, desktop);
get_focus = findDesktop(true, desktop, output);
}
if (get_focus != nullptr && get_focus != mostRecentlyActivatedWindow()) {
requestFocus(get_focus);

@ -256,7 +256,7 @@ Window *Workspace::topWindowOnDesktop(VirtualDesktop *desktop, Output *output, b
return nullptr;
}
Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop, Output *output) const
{
// TODO Q_ASSERT( block_stacking_updates == 0 );
if (topmost) {
@ -265,7 +265,7 @@ Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
if (window->isDeleted()) {
continue;
}
if (window->isClient() && window->isOnDesktop(desktop) && window->isDesktop() && window->isShown()) {
if (window->isClient() && window->isOnDesktop(desktop) && window->isOnOutput(output) && window->isDesktop() && window->isShown()) {
return window;
}
}
@ -274,7 +274,7 @@ Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
if (window->isDeleted()) {
continue;
}
if (window->isClient() && window->isOnDesktop(desktop) && window->isDesktop() && window->isShown()) {
if (window->isClient() && window->isOnDesktop(desktop) && window->isOnOutput(output) && window->isDesktop() && window->isShown()) {
return window;
}
}

@ -414,7 +414,7 @@ void Workspace::initializeX11()
newActiveWindow = topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop());
}
if (newActiveWindow == nullptr) {
newActiveWindow = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
newActiveWindow = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(), activeOutput());
}
}
if (newActiveWindow != nullptr) {
@ -734,7 +734,7 @@ void Workspace::addX11Window(X11Window *window)
raiseWindow(window);
// If there's no active window, make this desktop the active one
if (activeWindow() == nullptr && should_get_focus.count() == 0) {
activateWindow(findDesktop(true, VirtualDesktopManager::self()->currentDesktop()));
activateWindow(findDesktop(true, VirtualDesktopManager::self()->currentDesktop(), window->output()));
}
}
window->checkActiveModal();
@ -999,7 +999,7 @@ void Workspace::activateWindowOnDesktop(VirtualDesktop *desktop)
}
if (!window) {
window = findDesktop(true, desktop);
window = findDesktop(true, desktop, activeOutput());
}
if (window != m_activeWindow) {
@ -1115,7 +1115,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
}
if (!window) {
window = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
window = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(), activeOutput());
}
if (window != m_activeWindow) {
@ -1582,7 +1582,7 @@ void Workspace::setShowingDesktop(bool showing, bool animated)
}
if (showing_desktop) {
Window *desktop = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
Window *desktop = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(), activeOutput());
if (desktop) {
requestFocus(desktop);
}

@ -314,7 +314,7 @@ public:
Window *topWindowOnDesktop(VirtualDesktop *desktop, Output *output = nullptr, bool unconstrained = false,
bool only_normal = true) const;
Window *findDesktop(bool topmost, VirtualDesktop *desktop) const;
Window *findDesktop(bool topmost, VirtualDesktop *desktop, Output *output) const;
void addWindowToDesktop(Window *window, VirtualDesktop *desktop);
void removeWindowFromDesktop(Window *window, VirtualDesktop *desktop);
void sendWindowToDesktops(Window *window, const QList<VirtualDesktop *> &desktops, bool dont_activate);

Loading…
Cancel
Save