layout/algo: preserve focused target if applicable on layout switches (#14058)

fixes #13804
This commit is contained in:
Vaxry 2026-04-12 18:04:56 +01:00 committed by GitHub
parent 24b121c7a3
commit d67c4e2b7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 0 deletions

View file

@ -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);

View file

@ -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);
}