diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-04-12 18:04:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-12 18:04:56 +0100 |
| commit | d67c4e2b7f1e381b24becbb45b8e8471fcdda163 (patch) | |
| tree | 510a1626babdc5ba4acc37f37f0ec643ab4b9512 | |
| parent | 24b121c7a3df5d4d5d44f19d6e4129ea82fdfc1e (diff) | |
layout/algo: preserve focused target if applicable on layout switches (#14058)
fixes #13804
| -rw-r--r-- | hyprtester/src/tests/main/layout.cpp | 26 | ||||
| -rw-r--r-- | src/layout/algorithm/Algorithm.cpp | 13 |
2 files changed, 39 insertions, 0 deletions
diff --git a/hyprtester/src/tests/main/layout.cpp b/hyprtester/src/tests/main/layout.cpp index 5be29a6f..208bee30 100644 --- a/hyprtester/src/tests/main/layout.cpp +++ b/hyprtester/src/tests/main/layout.cpp @@ -140,6 +140,31 @@ static bool testFocusMRUAfterClose() { return true; } +static bool testFocusPreservedLayoutChange() { + NLog::log("{}Testing focus is preserved on layout change", Colors::GREEN); + + OK(getFromSocket("/keyword general:layout master")); + + EXPECT(!!Tests::spawnKitty("kitty_A"), true); + EXPECT(!!Tests::spawnKitty("kitty_B"), true); + EXPECT(!!Tests::spawnKitty("kitty_C"), true); + EXPECT(!!Tests::spawnKitty("kitty_D"), true); + + OK(getFromSocket("/dispatch focuswindow class:kitty_C")); + + OK(getFromSocket("/keyword general:layout monocle")); + + { + auto str = getFromSocket("/activewindow"); + EXPECT(str.contains("class: kitty_C"), true); + } + + NLog::log("{}Killing all windows", Colors::YELLOW); + Tests::killAllWindows(); + EXPECT(Tests::windowCount(), 0); + return true; +} + static bool test() { NLog::log("{}Testing layout generic", Colors::GREEN); @@ -153,6 +178,7 @@ static bool test() { testCrashOnGeomUpdate(); testPosPreserve(); testFocusMRUAfterClose(); + testFocusPreservedLayoutChange(); // clean up NLog::log("Cleaning up", Colors::YELLOW); diff --git a/src/layout/algorithm/Algorithm.cpp b/src/layout/algorithm/Algorithm.cpp index b9e94524..eb737d34 100644 --- a/src/layout/algorithm/Algorithm.cpp +++ b/src/layout/algorithm/Algorithm.cpp @@ -6,6 +6,7 @@ #include "../space/Space.hpp" #include "../../desktop/view/Window.hpp" #include "../../desktop/history/WindowHistoryTracker.hpp" +#include "../../desktop/state/FocusState.hpp" #include "../../helpers/Monitor.hpp" #include "../../render/Renderer.hpp" @@ -190,6 +191,9 @@ void CAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool void CAlgorithm::updateFloatingAlgo(UP<IFloatingAlgorithm>&& algo) { algo->m_parent = m_self; + const auto FOCUSED_WINDOW = Desktop::focusState()->window(); + const auto FOCUSED_TARGET = FOCUSED_WINDOW ? FOCUSED_WINDOW->layoutTarget() : nullptr; + for (const auto& t : m_floatingTargets) { const auto TARGET = t.lock(); if (!TARGET) @@ -204,12 +208,18 @@ void CAlgorithm::updateFloatingAlgo(UP<IFloatingAlgorithm>&& algo) { algo->newTarget(TARGET); } + if (FOCUSED_TARGET && FOCUSED_TARGET->space() == m_space && FOCUSED_TARGET->floating()) + Desktop::focusState()->fullWindowFocus(FOCUSED_WINDOW, Desktop::eFocusReason::FOCUS_REASON_DESKTOP_STATE_CHANGE); + m_floating = std::move(algo); } void CAlgorithm::updateTiledAlgo(UP<ITiledAlgorithm>&& algo) { algo->m_parent = m_self; + const auto FOCUSED_WINDOW = Desktop::focusState()->window(); + const auto FOCUSED_TARGET = FOCUSED_WINDOW ? FOCUSED_WINDOW->layoutTarget() : nullptr; + for (const auto& t : m_tiledTargets) { const auto TARGET = t.lock(); if (!TARGET) @@ -225,6 +235,9 @@ void CAlgorithm::updateTiledAlgo(UP<ITiledAlgorithm>&& algo) { algo->newTarget(TARGET); } + if (FOCUSED_TARGET && FOCUSED_TARGET->space() == m_space && !FOCUSED_TARGET->floating()) + Desktop::focusState()->fullWindowFocus(FOCUSED_WINDOW, Desktop::eFocusReason::FOCUS_REASON_DESKTOP_STATE_CHANGE); + m_tiled = std::move(algo); } |
