diff --git a/hyprtester/src/tests/main/window.cpp b/hyprtester/src/tests/main/window.cpp index 2cf42eef5..871875927 100644 --- a/hyprtester/src/tests/main/window.cpp +++ b/hyprtester/src/tests/main/window.cpp @@ -152,40 +152,22 @@ static bool test() { NLog::log("{}Testing window split ratios", Colors::YELLOW); { - const double INITIAL_RATIO = 1.25; - const int GAPSIN = 5; - const int GAPSOUT = 20; - const int BORDERSIZE = 2; - const int BORDERS = BORDERSIZE * 2; - const int MONITOR_W = 1920; - const int MONITOR_H = 1080; - - const float totalAvailableHeight = MONITOR_H - (GAPSOUT * 2); - const int HEIGHT = std::round(totalAvailableHeight) - BORDERS; - const float availableWidthForSplit = MONITOR_W - (GAPSOUT * 2) - GAPSIN; - - auto calculateFinalWidth = [&](double boxWidth, bool isLeftWindow) { - double gapLeft = isLeftWindow ? GAPSOUT : GAPSIN; - double gapRight = isLeftWindow ? GAPSIN : GAPSOUT; - return std::round(boxWidth - gapLeft - gapRight - BORDERS); - }; - - double geomBoxWidthA_R1 = (availableWidthForSplit * INITIAL_RATIO / 2.0) + GAPSOUT + (GAPSIN / 2.0); - double geomBoxWidthB_R1 = MONITOR_W - geomBoxWidthA_R1; - const int WIDTH1 = calculateFinalWidth(geomBoxWidthB_R1, false); - - const double INVERTED_RATIO = 0.75; - double geomBoxWidthA_R2 = (availableWidthForSplit * INVERTED_RATIO / 2.0) + GAPSOUT + (GAPSIN / 2.0); - double geomBoxWidthB_R2 = MONITOR_W - geomBoxWidthA_R2; - const int WIDTH2 = calculateFinalWidth(geomBoxWidthB_R2, false); - const int WIDTH_A_FINAL = calculateFinalWidth(geomBoxWidthA_R2, true); + const double RATIO = 1.25; + const double PERCENT = RATIO / 2.0 * 100.0; + const int GAPSIN = 5; + const int GAPSOUT = 20; + const int BORDERS = 2 * 2; + const int WTRIM = BORDERS + GAPSIN + GAPSOUT; + const int HEIGHT = 1080 - (BORDERS + (GAPSOUT * 2)); + const int WIDTH1 = std::round(1920.0 / 2.0 * (2 - RATIO)) - WTRIM; + const int WIDTH2 = std::round(1920.0 / 2.0 * RATIO) - WTRIM; OK(getFromSocket("/keyword dwindle:default_split_ratio 1.25")); if (!spawnKitty("kitty_B")) return false; - NLog::log("{}Expecting kitty_B size: {},{}", Colors::YELLOW, WIDTH1, HEIGHT); + NLog::log("{}Expecting kitty_B to take up roughly {}% of screen width", Colors::YELLOW, 100 - PERCENT); EXPECT_CONTAINS(getFromSocket("/activewindow"), std::format("size: {},{}", WIDTH1, HEIGHT)); OK(getFromSocket("/dispatch killwindow activewindow")); @@ -197,12 +179,12 @@ static bool test() { if (!spawnKitty("kitty_B")) return false; - NLog::log("{}Expecting kitty_B size: {},{}", Colors::YELLOW, WIDTH2, HEIGHT); + NLog::log("{}Expecting kitty_B to take up roughly {}% of screen width", Colors::YELLOW, PERCENT); EXPECT_CONTAINS(getFromSocket("/activewindow"), std::format("size: {},{}", WIDTH2, HEIGHT)); OK(getFromSocket("/dispatch focuswindow class:kitty_A")); - NLog::log("{}Expecting kitty_A size: {},{}", Colors::YELLOW, WIDTH_A_FINAL, HEIGHT); - EXPECT_CONTAINS(getFromSocket("/activewindow"), std::format("size: {},{}", WIDTH_A_FINAL, HEIGHT)); + NLog::log("{}Expecting kitty_A to have the same width as the previous kitty_B", Colors::YELLOW); + EXPECT_CONTAINS(getFromSocket("/activewindow"), std::format("size: {},{}", WIDTH1, HEIGHT)); OK(getFromSocket("/keyword dwindle:default_split_ratio 1")); } diff --git a/hyprtester/src/tests/main/workspaces.cpp b/hyprtester/src/tests/main/workspaces.cpp index 9d3802816..622236dcf 100644 --- a/hyprtester/src/tests/main/workspaces.cpp +++ b/hyprtester/src/tests/main/workspaces.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include "../shared.hpp" @@ -15,7 +14,6 @@ static int ret = 0; using namespace Hyprutils::OS; using namespace Hyprutils::Memory; -using namespace Hyprutils::Utils; #define UP CUniquePointer #define SP CSharedPointer @@ -361,95 +359,6 @@ static bool test() { NLog::log("{}Killing all windows", Colors::YELLOW); Tests::killAllWindows(); - NLog::log("{}Testing asymmetric gap splits", Colors::YELLOW); - { - - CScopeGuard guard = {[&]() { - NLog::log("{}Cleaning up asymmetric gap test", Colors::YELLOW); - Tests::killAllWindows(); - OK(getFromSocket("/reload")); - }}; - - OK(getFromSocket("/dispatch workspace name:gap_split_test")); - OK(getFromSocket("r/keyword general:gaps_in 0")); - OK(getFromSocket("r/keyword general:border_size 0")); - OK(getFromSocket("r/keyword dwindle:split_width_multiplier 1.0")); - OK(getFromSocket("r/keyword workspace name:gap_split_test,gapsout:0 1000 0 0")); - - NLog::log("{}Testing default split (force_split = 0)", Colors::YELLOW); - OK(getFromSocket("r/keyword dwindle:force_split 0")); - - if (!Tests::spawnKitty("gaps_kitty_A") || !Tests::spawnKitty("gaps_kitty_B")) { - return false; - } - - NLog::log("{}Expecting vertical split (B below A)", Colors::YELLOW); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_A")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,0"); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_B")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,540"); - - Tests::killAllWindows(); - EXPECT(Tests::windowCount(), 0); - - NLog::log("{}Testing force_split = 1", Colors::YELLOW); - OK(getFromSocket("r/keyword dwindle:force_split 1")); - - if (!Tests::spawnKitty("gaps_kitty_A") || !Tests::spawnKitty("gaps_kitty_B")) { - return false; - } - - NLog::log("{}Expecting vertical split (B above A)", Colors::YELLOW); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_B")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,0"); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_A")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,540"); - - NLog::log("{}Expecting horizontal split (C left of B)", Colors::YELLOW); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_B")); - - if (!Tests::spawnKitty("gaps_kitty_C")) { - return false; - } - - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_C")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,0"); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_B")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 460,0"); - - Tests::killAllWindows(); - EXPECT(Tests::windowCount(), 0); - - NLog::log("{}Testing force_split = 2", Colors::YELLOW); - OK(getFromSocket("r/keyword dwindle:force_split 2")); - - if (!Tests::spawnKitty("gaps_kitty_A") || !Tests::spawnKitty("gaps_kitty_B")) { - return false; - } - - NLog::log("{}Expecting vertical split (B below A)", Colors::YELLOW); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_A")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,0"); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_B")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,540"); - - NLog::log("{}Expecting horizontal split (C right of A)", Colors::YELLOW); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_A")); - - if (!Tests::spawnKitty("gaps_kitty_C")) { - return false; - } - - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_A")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 0,0"); - OK(getFromSocket("/dispatch focuswindow class:gaps_kitty_C")); - EXPECT_CONTAINS(getFromSocket("/activewindow"), "at: 460,0"); - } - - // kill all - NLog::log("{}Killing all windows", Colors::YELLOW); - Tests::killAllWindows(); - NLog::log("{}Expecting 0 windows", Colors::YELLOW); EXPECT(Tests::windowCount(), 0); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index c653a47ea..4925a50e6 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -9,51 +9,14 @@ #include "../managers/EventManager.hpp" #include "xwayland/XWayland.hpp" -SWorkspaceGaps CHyprDwindleLayout::getWorkspaceGaps(const PHLWORKSPACE& pWorkspace) { - const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(pWorkspace); - static auto PGAPSINDATA = CConfigValue("general:gaps_in"); - static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); - auto* const PGAPSIN = sc((PGAPSINDATA.ptr())->getData()); - auto* const PGAPSOUT = sc((PGAPSOUTDATA.ptr())->getData()); - - SWorkspaceGaps gaps; - gaps.in = WORKSPACERULE.gapsIn.value_or(*PGAPSIN); - gaps.out = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); - return gaps; -} - -SNodeDisplayEdgeFlags CHyprDwindleLayout::getNodeDisplayEdgeFlags(const CBox& box, const PHLMONITOR& monitor) { - return { - .top = STICKS(box.y, monitor->m_position.y + monitor->m_reservedTopLeft.y), - .bottom = STICKS(box.y + box.h, monitor->m_position.y + monitor->m_size.y - monitor->m_reservedBottomRight.y), - .left = STICKS(box.x, monitor->m_position.x + monitor->m_reservedTopLeft.x), - .right = STICKS(box.x + box.w, monitor->m_position.x + monitor->m_size.x - monitor->m_reservedBottomRight.x), - }; -} - void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) { if (children[0]) { static auto PSMARTSPLIT = CConfigValue("dwindle:smart_split"); static auto PPRESERVESPLIT = CConfigValue("dwindle:preserve_split"); static auto PFLMULT = CConfigValue("dwindle:split_width_multiplier"); - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID); - if (!PWORKSPACE) - return; - - const auto PMONITOR = PWORKSPACE->m_monitor.lock(); - if (!PMONITOR) - return; - - const auto edges = layout->getNodeDisplayEdgeFlags(box, PMONITOR); - auto [gapsIn, gapsOut] = layout->getWorkspaceGaps(PWORKSPACE); - - const Vector2D availableSize = box.size() - - Vector2D{(edges.left ? gapsOut.m_left : gapsIn.m_left / 2.f) + (edges.right ? gapsOut.m_right : gapsIn.m_right / 2.f), - (edges.top ? gapsOut.m_top : gapsIn.m_top / 2.f) + (edges.bottom ? gapsOut.m_bottom : gapsIn.m_bottom / 2.f)}; - if (*PPRESERVESPLIT == 0 && *PSMARTSPLIT == 0) - splitTop = availableSize.y * *PFLMULT > availableSize.x; + splitTop = box.h * *PFLMULT > box.w; if (verticalOverride) splitTop = true; @@ -64,28 +27,14 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverrid if (SPLITSIDE) { // split left/right - const float gapsAppliedToChild1 = (edges.left ? gapsOut.m_left : gapsIn.m_left / 2.f) + gapsIn.m_right / 2.f; - const float gapsAppliedToChild2 = gapsIn.m_left / 2.f + (edges.right ? gapsOut.m_right : gapsIn.m_right / 2.f); - const float totalGaps = gapsAppliedToChild1 + gapsAppliedToChild2; - const float totalAvailable = box.w - totalGaps; - - const float child1Available = totalAvailable * (splitRatio / 2.f); - const float FIRSTSIZE = child1Available + gapsAppliedToChild1; - - children[0]->box = CBox{box.x, box.y, FIRSTSIZE, box.h}.noNegativeSize(); - children[1]->box = CBox{box.x + FIRSTSIZE, box.y, box.w - FIRSTSIZE, box.h}.noNegativeSize(); + const float FIRSTSIZE = box.w / 2.0 * splitRatio; + children[0]->box = CBox{box.x, box.y, FIRSTSIZE, box.h}.noNegativeSize(); + children[1]->box = CBox{box.x + FIRSTSIZE, box.y, box.w - FIRSTSIZE, box.h}.noNegativeSize(); } else { // split top/bottom - const float gapsAppliedToChild1 = (edges.top ? gapsOut.m_top : gapsIn.m_top / 2.f) + gapsIn.m_bottom / 2.f; - const float gapsAppliedToChild2 = gapsIn.m_top / 2.f + (edges.bottom ? gapsOut.m_bottom : gapsIn.m_bottom / 2.f); - const float totalGaps = gapsAppliedToChild1 + gapsAppliedToChild2; - const float totalAvailable = box.h - totalGaps; - - const float child1Available = totalAvailable * (splitRatio / 2.f); - const float FIRSTSIZE = child1Available + gapsAppliedToChild1; - - children[0]->box = CBox{box.x, box.y, box.w, FIRSTSIZE}.noNegativeSize(); - children[1]->box = CBox{box.x, box.y + FIRSTSIZE, box.w, box.h - FIRSTSIZE}.noNegativeSize(); + const float FIRSTSIZE = box.h / 2.0 * splitRatio; + children[0]->box = CBox{box.x, box.y, box.w, FIRSTSIZE}.noNegativeSize(); + children[1]->box = CBox{box.x, box.y + FIRSTSIZE, box.w, box.h - FIRSTSIZE}.noNegativeSize(); } children[0]->recalcSizePosRecursive(force); @@ -167,7 +116,10 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for } // for gaps outer - const auto edges = getNodeDisplayEdgeFlags(pNode->box, PMONITOR); + const bool DISPLAYLEFT = STICKS(pNode->box.x, PMONITOR->m_position.x + PMONITOR->m_reservedTopLeft.x); + const bool DISPLAYRIGHT = STICKS(pNode->box.x + pNode->box.w, PMONITOR->m_position.x + PMONITOR->m_size.x - PMONITOR->m_reservedBottomRight.x); + const bool DISPLAYTOP = STICKS(pNode->box.y, PMONITOR->m_position.y + PMONITOR->m_reservedTopLeft.y); + const bool DISPLAYBOTTOM = STICKS(pNode->box.y + pNode->box.h, PMONITOR->m_position.y + PMONITOR->m_size.y - PMONITOR->m_reservedBottomRight.y); const auto PWINDOW = pNode->pWindow.lock(); // get specific gaps and rules for this workspace, @@ -228,9 +180,9 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for } } - const auto GAPOFFSETTOPLEFT = Vector2D(sc(edges.left ? gapsOut.m_left : gapsIn.m_left), sc(edges.top ? gapsOut.m_top : gapsIn.m_top)); + const auto GAPOFFSETTOPLEFT = Vector2D(sc(DISPLAYLEFT ? gapsOut.m_left : gapsIn.m_left), sc(DISPLAYTOP ? gapsOut.m_top : gapsIn.m_top)); - const auto GAPOFFSETBOTTOMRIGHT = Vector2D(sc(edges.right ? gapsOut.m_right : gapsIn.m_right), sc(edges.bottom ? gapsOut.m_bottom : gapsIn.m_bottom)); + const auto GAPOFFSETBOTTOMRIGHT = Vector2D(sc(DISPLAYRIGHT ? gapsOut.m_right : gapsIn.m_right), sc(DISPLAYBOTTOM ? gapsOut.m_bottom : gapsIn.m_bottom)); calcPos = calcPos + GAPOFFSETTOPLEFT + ratioPadding / 2; calcSize = calcSize - GAPOFFSETTOPLEFT - GAPOFFSETBOTTOMRIGHT - ratioPadding; @@ -398,6 +350,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir } // get the node under our cursor + m_dwindleNodesData.emplace_back(); const auto NEWPARENT = &m_dwindleNodesData.back(); @@ -410,17 +363,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir static auto PWIDTHMULTIPLIER = CConfigValue("dwindle:split_width_multiplier"); - const auto edges = getNodeDisplayEdgeFlags(NEWPARENT->box, PMONITOR); - - const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PNODE->workspaceID); - auto [gapsIn, gapsOut] = getWorkspaceGaps(WORKSPACE); - // if cursor over first child, make it first, etc - const Vector2D availableSize = NEWPARENT->box.size() - - Vector2D{(edges.left ? gapsOut.m_left : gapsIn.m_left / 2.f) + (edges.right ? gapsOut.m_right : gapsIn.m_right / 2.f), - (edges.top ? gapsOut.m_top : gapsIn.m_top / 2.f) + (edges.bottom ? gapsOut.m_bottom : gapsIn.m_bottom / 2.f)}; - - const auto SIDEBYSIDE = availableSize.x > availableSize.y * *PWIDTHMULTIPLIER; + const auto SIDEBYSIDE = NEWPARENT->box.w > NEWPARENT->box.h * *PWIDTHMULTIPLIER; NEWPARENT->splitTop = !SIDEBYSIDE; static auto PFORCESPLIT = CConfigValue("dwindle:force_split"); @@ -675,8 +619,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn static auto PSMARTRESIZING = CConfigValue("dwindle:smart_resizing"); // get some data about our window - const auto PMONITOR = PWINDOW->m_monitor.lock(); - const auto edges = getNodeDisplayEdgeFlags(CBox{PWINDOW->m_position, PWINDOW->m_size}, PMONITOR); + const auto PMONITOR = PWINDOW->m_monitor.lock(); + const bool DISPLAYLEFT = STICKS(PWINDOW->m_position.x, PMONITOR->m_position.x + PMONITOR->m_reservedTopLeft.x); + const bool DISPLAYRIGHT = STICKS(PWINDOW->m_position.x + PWINDOW->m_size.x, PMONITOR->m_position.x + PMONITOR->m_size.x - PMONITOR->m_reservedBottomRight.x); + const bool DISPLAYTOP = STICKS(PWINDOW->m_position.y, PMONITOR->m_position.y + PMONITOR->m_reservedTopLeft.y); + const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_position.y + PWINDOW->m_size.y, PMONITOR->m_position.y + PMONITOR->m_size.y - PMONITOR->m_reservedBottomRight.y); if (PWINDOW->m_isPseudotiled) { if (!m_pseudoDragFlags.started) { @@ -724,10 +671,10 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn // construct allowed movement Vector2D allowedMovement = pixResize; - if (edges.left && edges.right) + if (DISPLAYLEFT && DISPLAYRIGHT) allowedMovement.x = 0; - if (edges.bottom && edges.top) + if (DISPLAYBOTTOM && DISPLAYTOP) allowedMovement.y = 0; if (*PSMARTRESIZING == 1) { @@ -737,10 +684,10 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn SDwindleNodeData* PHOUTER = nullptr; SDwindleNodeData* PHINNER = nullptr; - const auto LEFT = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT || edges.right; - const auto TOP = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT || edges.bottom; - const auto RIGHT = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT || edges.left; - const auto BOTTOM = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT || edges.top; + const auto LEFT = corner == CORNER_TOPLEFT || corner == CORNER_BOTTOMLEFT || DISPLAYRIGHT; + const auto TOP = corner == CORNER_TOPLEFT || corner == CORNER_TOPRIGHT || DISPLAYBOTTOM; + const auto RIGHT = corner == CORNER_TOPRIGHT || corner == CORNER_BOTTOMRIGHT || DISPLAYLEFT; + const auto BOTTOM = corner == CORNER_BOTTOMLEFT || corner == CORNER_BOTTOMRIGHT || DISPLAYTOP; const auto NONE = corner == CORNER_NONE; for (auto PCURRENT = PNODE; PCURRENT && PCURRENT->pParent; PCURRENT = PCURRENT->pParent) { diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index de80beedd..23f19956a 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -1,7 +1,6 @@ #pragma once #include "IHyprLayout.hpp" -#include "../config/ConfigDataValues.hpp" #include "../desktop/DesktopTypes.hpp" #include @@ -13,15 +12,6 @@ class CHyprDwindleLayout; enum eFullscreenMode : int8_t; -struct SNodeDisplayEdgeFlags { - bool top = false, bottom = false, left = false, right = false; -}; - -struct SWorkspaceGaps { - CCssGapData in; - CCssGapData out; -}; - struct SDwindleNodeData { SDwindleNodeData* pParent = nullptr; bool isNode = false; @@ -75,9 +65,6 @@ class CHyprDwindleLayout : public IHyprLayout { virtual void onDisable(); private: - SWorkspaceGaps getWorkspaceGaps(const PHLWORKSPACE& pWorkspace); - SNodeDisplayEdgeFlags getNodeDisplayEdgeFlags(const CBox& box, const PHLMONITOR& monitor); - std::list m_dwindleNodesData; struct {