From 64e7d5345dddd755e361a6fce5a7f58b06a8b546 Mon Sep 17 00:00:00 2001 From: Daniel Adolfsson Date: Tue, 11 Jul 2023 13:37:25 +0200 Subject: [PATCH] Add support for smart splitting (#2676) * Add support for smart splitting * clang-format * smart_split default to 0, and make smart_split behave like preserve_split --- src/config/ConfigManager.cpp | 1 + src/helpers/Vector2D.cpp | 8 ++++++++ src/helpers/Vector2D.hpp | 2 ++ src/layout/DwindleLayout.cpp | 27 ++++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 56c55f3b..27ecf58a 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -157,6 +157,7 @@ void CConfigManager::setDefaultVars() { configValues["dwindle:no_gaps_when_only"].intValue = 0; configValues["dwindle:use_active_for_splits"].intValue = 1; configValues["dwindle:default_split_ratio"].floatValue = 1.f; + configValues["dwindle:smart_split"].intValue = 0; configValues["master:special_scale_factor"].floatValue = 0.8f; configValues["master:mfact"].floatValue = 0.55f; diff --git a/src/helpers/Vector2D.cpp b/src/helpers/Vector2D.cpp index 21701c97..118ba9d9 100644 --- a/src/helpers/Vector2D.cpp +++ b/src/helpers/Vector2D.cpp @@ -37,3 +37,11 @@ double Vector2D::distance(const Vector2D& other) const { double dy = y - other.y; return std::sqrt(dx * dx + dy * dy); } + +bool Vector2D::inTriangle(const Vector2D& p1, const Vector2D& p2, const Vector2D& p3) const { + const auto a = ((p2.y - p3.y) * (x - p3.x) + (p3.x - p2.x) * (y - p3.y)) / ((p2.y - p3.y) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.y - p3.y)); + const auto b = ((p3.y - p1.y) * (x - p3.x) + (p1.x - p3.x) * (y - p3.y)) / ((p2.y - p3.y) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.y - p3.y)); + const auto c = 1 - a - b; + + return 0 <= a && a <= 1 && 0 <= b && b <= 1 && 0 <= c && c <= 1; +} diff --git a/src/helpers/Vector2D.hpp b/src/helpers/Vector2D.hpp index 1178f734..3ba06de7 100644 --- a/src/helpers/Vector2D.hpp +++ b/src/helpers/Vector2D.hpp @@ -48,4 +48,6 @@ class Vector2D { Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()) const; Vector2D floor() const; + + bool inTriangle(const Vector2D& p1, const Vector2D& p2, const Vector2D& p3) const; }; diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index dda9a53f..adf597ff 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -6,10 +6,11 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverrid const auto REVERSESPLITRATIO = 2.f - splitRatio; + static auto* const PSMARTSPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:smart_split")->intValue; static auto* const PPRESERVESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:preserve_split")->intValue; static auto* const PFLMULT = &g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier")->floatValue; - if (*PPRESERVESPLIT == 0) { + if (*PPRESERVESPLIT == 0 && *PSMARTSPLIT == 0) { splitTop = size.y * *PFLMULT > size.x; } @@ -363,6 +364,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { static auto* const PFORCESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:force_split")->intValue; static auto* const PERMANENTDIRECTIONOVERRIDE = &g_pConfigManager->getConfigValuePtr("dwindle:permanent_direction_override")->intValue; + static auto* const PSMARTSPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:smart_split")->intValue; bool horizontalOverride = false; bool verticalOverride = false; @@ -388,7 +390,30 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { // whether or not the override persists after opening one window if (*PERMANENTDIRECTIONOVERRIDE == 0) overrideDirection = OneTimeFocus::NOFOCUS; + } else if (*PSMARTSPLIT == 1) { + const auto tl = NEWPARENT->position; + const auto tr = NEWPARENT->position + Vector2D(NEWPARENT->size.x, 0); + const auto bl = NEWPARENT->position + Vector2D(0, NEWPARENT->size.y); + const auto br = NEWPARENT->position + NEWPARENT->size; + const auto cc = NEWPARENT->position + NEWPARENT->size / 2; + if (MOUSECOORDS.inTriangle(tl, tr, cc)) { + NEWPARENT->splitTop = true; + NEWPARENT->children[0] = PNODE; + NEWPARENT->children[1] = OPENINGON; + } else if (MOUSECOORDS.inTriangle(tr, cc, br)) { + NEWPARENT->splitTop = false; + NEWPARENT->children[0] = OPENINGON; + NEWPARENT->children[1] = PNODE; + } else if (MOUSECOORDS.inTriangle(br, bl, cc)) { + NEWPARENT->splitTop = true; + NEWPARENT->children[0] = OPENINGON; + NEWPARENT->children[1] = PNODE; + } else { + NEWPARENT->splitTop = false; + NEWPARENT->children[0] = PNODE; + NEWPARENT->children[1] = OPENINGON; + } } else if (*PFORCESPLIT == 0 || !pWindow->m_bFirstMap) { if ((SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / *PWIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x / 2.f,