From 33721ded25cb01f030980904d2a4eddce7f8b4d9 Mon Sep 17 00:00:00 2001 From: Fazzi Date: Sun, 3 May 2026 13:47:38 +0100 Subject: [PATCH] windows/focus: add fallbacks when focussing workspaces --- src/config/shared/actions/ConfigActions.cpp | 12 +++++++----- src/desktop/Workspace.cpp | 12 ++++++++++++ src/desktop/Workspace.hpp | 1 + src/desktop/state/FocusState.cpp | 8 ++++++-- src/helpers/Monitor.cpp | 5 +---- src/managers/input/InputManager.cpp | 3 ++- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/config/shared/actions/ConfigActions.cpp b/src/config/shared/actions/ConfigActions.cpp index 7111afd8f..56fb88e98 100644 --- a/src/config/shared/actions/ConfigActions.cpp +++ b/src/config/shared/actions/ConfigActions.cpp @@ -94,7 +94,7 @@ static bool tryMoveFocusToMonitor(PHLMONITOR monitor) { const auto PNEWMAINWORKSPACE = monitor->m_activeWorkspace; const auto PNEWWORKSPACE = monitor->m_activeSpecialWorkspace ? monitor->m_activeSpecialWorkspace : PNEWMAINWORKSPACE; - const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow(); + auto PNEWWINDOW = PNEWWORKSPACE->getFocusCandidate(); if (PNEWWINDOW) { updateRelativeCursorCoords(); @@ -931,11 +931,13 @@ ActionResult Actions::changeWorkspace(PHLWORKSPACE ws) { PMONITORWORKSPACEOWNER->changeWorkspace(ws, false, true); if (PMONITOR != PMONITORWORKSPACEOWNER) { - Vector2D middle = PMONITORWORKSPACEOWNER->middle(); - if (const auto PLAST = ws->getLastFocusedWindow(); PLAST) { - Desktop::focusState()->fullWindowFocus(PLAST, Desktop::FOCUS_REASON_KEYBIND); + Vector2D middle = PMONITORWORKSPACEOWNER->middle(); + auto pWindow = ws->getFocusCandidate(); + + if (pWindow) { + Desktop::focusState()->fullWindowFocus(pWindow, Desktop::FOCUS_REASON_KEYBIND); if (*PWORKSPACECENTERON == 1) - middle = PLAST->middle(); + middle = pWindow->middle(); } g_pCompositor->warpCursorTo(middle); } diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 60d8d9853..23ea0dd73 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -83,6 +83,18 @@ PHLWINDOW CWorkspace::getLastFocusedWindow() { return m_lastFocusedWindow.lock(); } +PHLWINDOW CWorkspace::getFocusCandidate() { + auto pWindow = getLastFocusedWindow(); + + if (!pWindow) + pWindow = getTopLeftWindow(); + + if (!pWindow) + pWindow = getFirstWindow(); + + return pWindow; +} + std::string CWorkspace::getConfigName() { if (m_isSpecialWorkspace) { return m_name; diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index d778324de..1ccf14542 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -61,6 +61,7 @@ class CWorkspace { bool inert(); MONITORID monitorID(); PHLWINDOW getLastFocusedWindow(); + PHLWINDOW getFocusCandidate(); std::string getConfigName(); bool matchesStaticSelector(const std::string& selector); void markInert(); diff --git a/src/desktop/state/FocusState.cpp b/src/desktop/state/FocusState.cpp index 5db4bac5c..5dd22f94b 100644 --- a/src/desktop/state/FocusState.cpp +++ b/src/desktop/state/FocusState.cpp @@ -167,8 +167,12 @@ void CFocusState::rawWindowFocus(PHLWINDOW pWindow, eFocusReason reason, SPm_pinned) + rawMonitorFocus(PMONITOR); + + const auto PLASTWINDOW = m_focusWindow.lock(); + m_focusWindow = pWindow; + pWindow->m_workspace->m_lastFocusedWindow = pWindow; /* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which window focuses are "via keybinds" and which ones aren't. */ diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index b2e94a312..c7d4168ae 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1406,10 +1406,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo Desktop::View::RESERVED_EXTENTS | Desktop::View::INPUT_EXTENTS | Desktop::View::ALLOW_FLOATING); if (!pWindow) - pWindow = pWorkspace->getTopLeftWindow(); - - if (!pWindow) - pWindow = pWorkspace->getFirstWindow(); + pWindow = pWorkspace->getFocusCandidate(); } Desktop::focusState()->fullWindowFocus(pWindow, Desktop::FOCUS_REASON_KEYBIND); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index b6f384337..65a981814 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1694,7 +1694,8 @@ bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) { foundSurface = nullptr; } - if (!foundSurface && Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace && Desktop::focusState()->window()->m_workspace->isVisibleNotCovered()) { + if (!foundSurface && Desktop::focusState()->window() && Desktop::focusState()->window()->m_monitor == pMonitor && Desktop::focusState()->window()->m_workspace && + Desktop::focusState()->window()->m_workspace->isVisibleNotCovered()) { // then the last focused window if we're on the same workspace as it const auto PLASTWINDOW = Desktop::focusState()->window(); Desktop::focusState()->fullWindowFocus(PLASTWINDOW, Desktop::FOCUS_REASON_FFM);