From 12c1bb936dd463c4188def1c73c2bb786433a6dc Mon Sep 17 00:00:00 2001 From: MightyPlaza <123664421+MightyPlaza@users.noreply.github.com> Date: Wed, 30 Oct 2024 18:58:36 +0000 Subject: [PATCH] internal: check size limit in layouts (#8298) modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/helpers/MiscFunctions.cpp modified: src/helpers/MiscFunctions.hpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/macros.hpp --- src/desktop/Window.cpp | 2 +- src/desktop/Window.hpp | 7 +++++++ src/events/Windows.cpp | 32 +++++++++++--------------------- src/helpers/MiscFunctions.cpp | 7 +++++++ src/helpers/MiscFunctions.hpp | 1 + src/layout/DwindleLayout.cpp | 4 +++- src/layout/IHyprLayout.cpp | 19 +++++++++---------- src/layout/MasterLayout.cpp | 4 +++- src/macros.hpp | 2 ++ 9 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 60f3b79d..20fed565 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1255,7 +1255,7 @@ int CWindow::surfacesCount() { void CWindow::clampWindowSize(const std::optional minSize, const std::optional maxSize) { const Vector2D REALSIZE = m_vRealSize.goal(); - const Vector2D NEWSIZE = REALSIZE.clamp(minSize.value_or(Vector2D{0.f, 0.f}), maxSize.value_or(Vector2D{INFINITY, INFINITY})); + const Vector2D NEWSIZE = REALSIZE.clamp(minSize.value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), maxSize.value_or(Vector2D{INFINITY, INFINITY})); const Vector2D DELTA = REALSIZE - NEWSIZE; m_vRealPosition = m_vRealPosition.goal() + DELTA / 2.0; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 825e8ca2..b8dd3cf7 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -144,6 +144,13 @@ class CWindowOverridableVar { unset(priority); } + operator std::optional() { + if (hasValue()) + return value(); + else + return std::nullopt; + } + private: std::map values; T defaultValue; // used for toggling, so required for bool diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 30d982fb..f946ce03 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -334,13 +334,6 @@ void Events::listener_mapWindow(void* owner, void* data) { try { auto stringToFloatClamp = [](const std::string& VALUE, const float CURR, const float REL) { - auto stringToPercentage = [](const std::string& VALUE, const float REL) { - if (VALUE.ends_with('%')) - return (std::stof(VALUE.substr(0, VALUE.length() - 1)) * REL) / 100; - else - return std::stof(VALUE); - }; - if (VALUE.starts_with('<')) return std::min(CURR, stringToPercentage(VALUE.substr(1, VALUE.length() - 1), REL)); else if (VALUE.starts_with('>')) @@ -355,11 +348,11 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW); - const float SIZEX = - SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) : stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize.goal().x, PMONITOR->vecSize.x); + const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : + stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize.goal().x, PMONITOR->vecSize.x); - const float SIZEY = - SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) : stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize.goal().y, PMONITOR->vecSize.y); + const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, PMONITOR->vecSize.y) : + stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize.goal().y, PMONITOR->vecSize.y); Debug::log(LOG, "Rule size, applying to {}", PWINDOW); @@ -472,18 +465,15 @@ void Events::listener_mapWindow(void* owner, void* data) { for (auto const& r : PWINDOW->m_vMatchedRules) { if (r.szRule.starts_with("size")) { try { - const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1); - const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); - const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); + const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1); + const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); + const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); - const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW); + const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW); - const auto SIZEX = SIZEXSTR == "max" ? - std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) : - (!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x); - const auto SIZEY = SIZEYSTR == "max" ? - std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) : - (!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y); + const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : stringToPercentage(SIZEXSTR, PMONITOR->vecSize.x); + + const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, PMONITOR->vecSize.y) : stringToPercentage(SIZEYSTR, PMONITOR->vecSize.y); Debug::log(LOG, "Rule size (tiled), applying to {}", PWINDOW); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 29861af7..878f5ca1 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -863,3 +863,10 @@ bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) { *ro_fd_ptr = ro_fd; return true; } + +float stringToPercentage(const std::string& VALUE, const float REL) { + if (VALUE.ends_with('%')) + return (std::stof(VALUE.substr(0, VALUE.length() - 1)) * REL) / 100.f; + else + return std::stof(VALUE); +}; diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index f696fc5d..34b23746 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -40,6 +40,7 @@ void throwError(const std::string& err); bool envEnabled(const std::string& env); int allocateSHMFile(size_t len); bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr); +float stringToPercentage(const std::string& VALUE, const float REL); template [[deprecated("use std::format instead")]] std::string getFormat(std::format_string fmt, Args&&... args) { diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 059dda99..32f64e4e 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -568,7 +568,9 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) { - PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0)); + PWINDOW->m_vRealSize = + (PWINDOW->m_vRealSize.goal() + pixResize) + .clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY})); PWINDOW->updateWindowDecos(); return; } diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index f2616668..73e7a125 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -881,18 +881,17 @@ Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // ge for (auto const& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) { if (r.szRule.starts_with("size")) { try { - const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1); - const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); - const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); + const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1); + const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); + const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); - const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); + const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); - const auto SIZEX = SIZEXSTR == "max" ? - std::clamp(MAXSIZE.x, 20.0, g_pCompositor->m_pLastMonitor->vecSize.x) : - (!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.x); - const auto SIZEY = SIZEYSTR == "max" ? - std::clamp(MAXSIZE.y, 20.0, g_pCompositor->m_pLastMonitor->vecSize.y) : - (!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.y); + const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, g_pCompositor->m_pLastMonitor->vecSize.x) : + stringToPercentage(SIZEXSTR, g_pCompositor->m_pLastMonitor->vecSize.x); + + const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, g_pCompositor->m_pLastMonitor->vecSize.y) : + stringToPercentage(SIZEYSTR, g_pCompositor->m_pLastMonitor->vecSize.y); sizeOverride = {SIZEX, SIZEY}; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index a2321a41..afe79ecf 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -706,7 +706,9 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) { - PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0)); + PWINDOW->m_vRealSize = + (PWINDOW->m_vRealSize.goal() + pixResize) + .clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY})); PWINDOW->updateWindowDecos(); return; } diff --git a/src/macros.hpp b/src/macros.hpp index 44014085..8915e12d 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -29,6 +29,8 @@ #define MONITOR_INVALID -1L +#define MIN_WINDOW_SIZE 20.0 + #define LISTENER(name) \ void listener_##name(wl_listener*, void*); \ inline wl_listener listen_##name = {.notify = listener_##name}