diff --git a/hyprtester/src/tests/main/dwindle.cpp b/hyprtester/src/tests/main/dwindle.cpp index 8f17c815..4135f2d6 100644 --- a/hyprtester/src/tests/main/dwindle.cpp +++ b/hyprtester/src/tests/main/dwindle.cpp @@ -34,6 +34,51 @@ static void testFloatClamp() { // clean up NLog::log("{}Killing all windows", Colors::YELLOW); Tests::killAllWindows(); + + OK(getFromSocket("/reload")); +} + +static void test13349() { + + // Test if dwindle properly uses a focal point to place a new window. + // exposed by #13349 as a regression from #12890 + + for (auto const& win : {"a", "b", "c"}) { + if (!Tests::spawnKitty(win)) { + NLog::log("{}Failed to spawn kitty with win class `{}`", Colors::RED, win); + ++TESTS_FAILED; + ret = 1; + return; + } + } + + OK(getFromSocket("/dispatch focuswindow class:c")); + + { + auto str = getFromSocket("/activewindow"); + EXPECT_CONTAINS(str, "at: 967,547"); + EXPECT_CONTAINS(str, "size: 931,511"); + } + + OK(getFromSocket("/dispatch movewindow l")); + + { + auto str = getFromSocket("/activewindow"); + EXPECT_CONTAINS(str, "at: 22,547"); + EXPECT_CONTAINS(str, "size: 931,511"); + } + + OK(getFromSocket("/dispatch movewindow r")); + + { + auto str = getFromSocket("/activewindow"); + EXPECT_CONTAINS(str, "at: 967,547"); + EXPECT_CONTAINS(str, "size: 931,511"); + } + + // clean up + NLog::log("{}Killing all windows", Colors::YELLOW); + Tests::killAllWindows(); } static bool test() { @@ -43,6 +88,9 @@ static bool test() { NLog::log("{}Testing float clamp", Colors::GREEN); testFloatClamp(); + NLog::log("{}Testing #13349", Colors::GREEN); + test13349(); + // clean up NLog::log("Cleaning up", Colors::YELLOW); getFromSocket("/dispatch workspace 1"); diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp index 5b90bb46..f5e230f8 100644 --- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp +++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp @@ -100,16 +100,14 @@ void CDwindleAlgorithm::addTarget(SP target, bool newTarget) { OPENINGON = getClosestNode(MOUSECOORDS); } else if (*PUSEACTIVE) { - if (Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isFloating && Desktop::focusState()->window() != target->window() && - Desktop::focusState()->window()->m_workspace == PWORKSPACE && Desktop::focusState()->window()->m_isMapped) { - OPENINGON = getNodeFromWindow(Desktop::focusState()->window()); - } else { - OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, Desktop::View::RESERVED_EXTENTS | Desktop::View::INPUT_EXTENTS)); - } + const auto ACTIVE_WINDOW = Desktop::focusState()->window(); - if (!OPENINGON && g_pCompositor->isPointOnReservedArea(MOUSECOORDS, ACTIVE_MON)) - OPENINGON = getClosestNode(MOUSECOORDS); + if (!m_overrideFocalPoint && ACTIVE_WINDOW && !ACTIVE_WINDOW->m_isFloating && ACTIVE_WINDOW != target->window() && ACTIVE_WINDOW->m_workspace == PWORKSPACE && + ACTIVE_WINDOW->m_isMapped) + OPENINGON = getNodeFromWindow(ACTIVE_WINDOW); + if (!OPENINGON) + OPENINGON = getClosestNode(MOUSECOORDS, target); } else OPENINGON = getFirstNode(); @@ -635,10 +633,13 @@ SP CDwindleAlgorithm::getFirstNode() { return m_dwindleNodesData.empty() ? nullptr : m_dwindleNodesData.at(0); } -SP CDwindleAlgorithm::getClosestNode(const Vector2D& point) { +SP CDwindleAlgorithm::getClosestNode(const Vector2D& point, SP skip) { SP res = nullptr; double distClosest = -1; for (auto& n : m_dwindleNodesData) { + if (skip && n->pTarget == skip) + continue; + if (n->pTarget && Desktop::View::validMapped(n->pTarget->window())) { auto distAnother = vecToRectDistanceSquared(point, n->box.pos(), n->box.pos() + n->box.size()); if (!res || distAnother < distClosest) { diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp index 27c905a4..594b033b 100644 --- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp +++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp @@ -45,7 +45,7 @@ namespace Layout::Tiled { SP getNodeFromWindow(PHLWINDOW w); int getNodes(); SP getFirstNode(); - SP getClosestNode(const Vector2D&); + SP getClosestNode(const Vector2D&, SP skip = nullptr); SP getMasterNode(); void toggleSplit(SP);