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
wilder/Plasma/6.3
Vlad Zahorodnii 1 year ago
parent a9de526787
commit 47a2a2e12a
  1. 9
      src/activation.cpp
  2. 6
      src/layers.cpp
  3. 10
      src/workspace.cpp
  4. 2
      src/workspace.h

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

@ -256,7 +256,7 @@ Window *Workspace::topWindowOnDesktop(VirtualDesktop *desktop, Output *output, b
return nullptr; 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 ); // TODO Q_ASSERT( block_stacking_updates == 0 );
if (topmost) { if (topmost) {
@ -265,7 +265,7 @@ Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
if (window->isDeleted()) { if (window->isDeleted()) {
continue; 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; return window;
} }
} }
@ -274,7 +274,7 @@ Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
if (window->isDeleted()) { if (window->isDeleted()) {
continue; 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; return window;
} }
} }

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

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

Loading…
Cancel
Save