diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-12-30 18:02:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-30 18:02:34 +0100 |
| commit | 529559712bbfa9c8d79fe01770a77e925a7a0496 (patch) | |
| tree | 9124e885d2e296b1eb2578c1e469a1f4f4ea0a84 | |
| parent | 293d3e5de9fb18d54a5b0b7f9dbb4492207a25dd (diff) | |
desktop/window: go back to the previously focused window in a group (#12763)
| -rw-r--r-- | hyprtester/src/tests/main/window.cpp | 37 | ||||
| -rw-r--r-- | src/desktop/view/Window.cpp | 19 |
2 files changed, 55 insertions, 1 deletions
diff --git a/hyprtester/src/tests/main/window.cpp b/hyprtester/src/tests/main/window.cpp index 37442790..0a2e31d0 100644 --- a/hyprtester/src/tests/main/window.cpp +++ b/hyprtester/src/tests/main/window.cpp @@ -373,6 +373,41 @@ static void testMaximizeSize() { EXPECT(Tests::windowCount(), 0); } +static void testGroupFallbackFocus() { + NLog::log("{}Testing group fallback focus", Colors::GREEN); + + EXPECT(spawnKitty("kitty_A"), true); + + OK(getFromSocket("/dispatch togglegroup")); + + EXPECT(spawnKitty("kitty_B"), true); + EXPECT(spawnKitty("kitty_C"), true); + EXPECT(spawnKitty("kitty_D"), true); + + { + auto str = getFromSocket("/activewindow"); + EXPECT(str.contains("class: kitty_D"), true); + } + + OK(getFromSocket("/dispatch focuswindow class:kitty_B")); + OK(getFromSocket("/dispatch focuswindow class:kitty_D")); + OK(getFromSocket("/dispatch killactive")); + + Tests::waitUntilWindowsN(3); + + // Focus must return to the last focus, in this case B. + { + auto str = getFromSocket("/activewindow"); + EXPECT(str.contains("class: kitty_B"), true); + } + + NLog::log("{}Killing all windows", Colors::YELLOW); + Tests::killAllWindows(); + + NLog::log("{}Expecting 0 windows", Colors::YELLOW); + EXPECT(Tests::windowCount(), 0); +} + static void testBringActiveToTopMouseMovement() { NLog::log("{}Testing bringactivetotop mouse movement", Colors::GREEN); @@ -847,6 +882,8 @@ static bool test() { testBringActiveToTopMouseMovement(); + testGroupFallbackFocus(); + NLog::log("{}Reloading config", Colors::YELLOW); OK(getFromSocket("/reload")); diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp index 695ba81f..b0e6a365 100644 --- a/src/desktop/view/Window.cpp +++ b/src/desktop/view/Window.cpp @@ -2437,7 +2437,24 @@ void CWindow::unmapWindow() { } bool wasLastWindow = false; - PHLWINDOW nextInGroup = m_groupData.pNextWindow ? m_groupData.pNextWindow.lock() : nullptr; + PHLWINDOW nextInGroup = [this] -> PHLWINDOW { + if (!m_groupData.pNextWindow) + return nullptr; + + // walk the history to find a suitable window + const auto HISTORY = Desktop::History::windowTracker()->fullHistory(); + for (const auto& w : HISTORY | std::views::reverse) { + if (!w || !w->m_isMapped || w == m_self) + continue; + + if (!hasInGroup(w.lock())) + continue; + + return w.lock(); + } + + return nullptr; + }(); if (m_self.lock() == Desktop::focusState()->window()) { wasLastWindow = true; |
