From 6bdb1f413e4c592f73d91bef33dfb202503ef7ab Mon Sep 17 00:00:00 2001 From: Viktor Date: Tue, 10 Jun 2025 09:20:31 +0200 Subject: [PATCH] dwindle: add the ability to specify an aspect ratio for a singular window (#10650) --- src/config/ConfigDescriptions.hpp | 12 +++++++++++ src/config/ConfigManager.cpp | 2 ++ src/layout/DwindleLayout.cpp | 36 +++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 1eff8c63c..7d62c8338 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1782,6 +1782,18 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "dwindle:single_window_aspect_ratio", + .description = "If specified, whenever only a single window is open, it will be coerced into the specified aspect ratio. Ignored if the y-value is zero.", + .type = CONFIG_OPTION_VECTOR, + .data = SConfigOptionDescription::SVectorData{{0, 0}, {0, 0}, {1000., 1000.}}, + }, + SConfigOptionDescription{ + .value = "dwindle:single_window_aspect_ratio_tolerance", + .description = "Minimum distance for single_window_aspect_ratio to take effect, in fractions of the monitor's size.", + .type = CONFIG_OPTION_FLOAT, + .data = SConfigOptionDescription::SFloatData{0.1f, 0.f, 1.f}, + }, /* * master: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 8dc06d77c..6759771c6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -595,6 +595,8 @@ CConfigManager::CConfigManager() { registerConfigVar("dwindle:smart_split", Hyprlang::INT{0}); registerConfigVar("dwindle:smart_resizing", Hyprlang::INT{1}); registerConfigVar("dwindle:precise_mouse_move", Hyprlang::INT{0}); + registerConfigVar("dwindle:single_window_aspect_ratio", Hyprlang::VEC2{0, 0}); + registerConfigVar("dwindle:single_window_aspect_ratio_tolerance", {0.1f}); registerConfigVar("master:special_scale_factor", {1.f}); registerConfigVar("master:mfact", {0.55f}); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 305f1feed..2f51b162b 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -152,15 +152,39 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for PWINDOW->updateWindowDecos(); - auto calcPos = PWINDOW->m_position; - auto calcSize = PWINDOW->m_size; + auto calcPos = PWINDOW->m_position; + auto calcSize = PWINDOW->m_size; - const auto OFFSETTOPLEFT = Vector2D((double)(DISPLAYLEFT ? gapsOut.m_left : gapsIn.m_left), (double)(DISPLAYTOP ? gapsOut.m_top : gapsIn.m_top)); + const static auto REQUESTEDRATIO = *CConfigValue("dwindle:single_window_aspect_ratio"); + const static auto REQUESTEDRATIOTOLERANCE = CConfigValue("dwindle:single_window_aspect_ratio_tolerance"); - const auto OFFSETBOTTOMRIGHT = Vector2D((double)(DISPLAYRIGHT ? gapsOut.m_right : gapsIn.m_right), (double)(DISPLAYBOTTOM ? gapsOut.m_bottom : gapsIn.m_bottom)); + Vector2D ratioPadding; - calcPos = calcPos + OFFSETTOPLEFT; - calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; + if (REQUESTEDRATIO.y != 0 && !pNode->pParent) { + const Vector2D originalSize = PMONITOR->m_size - PMONITOR->m_reservedTopLeft - PMONITOR->m_reservedBottomRight; + + const double requestedRatio = REQUESTEDRATIO.x / REQUESTEDRATIO.y; + const double originalRatio = originalSize.x / originalSize.y; + + if (requestedRatio > originalRatio) { + double padding = originalSize.y - (originalSize.x / requestedRatio); + + if (padding / 2 > (*REQUESTEDRATIOTOLERANCE) * originalSize.y) + ratioPadding = Vector2D{0., padding}; + } else if (requestedRatio < originalRatio) { + double padding = originalSize.x - (originalSize.y * requestedRatio); + + if (padding / 2 > (*REQUESTEDRATIOTOLERANCE) * originalSize.x) + ratioPadding = Vector2D{padding, 0.}; + } + } + + const auto GAPOFFSETTOPLEFT = Vector2D((double)(DISPLAYLEFT ? gapsOut.m_left : gapsIn.m_left), (double)(DISPLAYTOP ? gapsOut.m_top : gapsIn.m_top)); + + const auto GAPOFFSETBOTTOMRIGHT = Vector2D((double)(DISPLAYRIGHT ? gapsOut.m_right : gapsIn.m_right), (double)(DISPLAYBOTTOM ? gapsOut.m_bottom : gapsIn.m_bottom)); + + calcPos = calcPos + GAPOFFSETTOPLEFT + ratioPadding / 2; + calcSize = calcSize - GAPOFFSETTOPLEFT - GAPOFFSETBOTTOMRIGHT - ratioPadding; if (PWINDOW->m_isPseudotiled) { // Calculate pseudo