From 074bd2be4f5b5b6c858d9b637fbff583ab7f54fa Mon Sep 17 00:00:00 2001 From: nnyyxxxx Date: Tue, 25 Feb 2025 12:01:53 -0500 Subject: [PATCH 1/4] feat(window): add option to allow size persistence between app launches --- src/config/ConfigManager.cpp | 14 ++++++++++++++ src/config/ConfigManager.hpp | 27 ++++++++++++++++----------- src/desktop/Window.cpp | 9 +++++++++ src/desktop/Window.hpp | 2 ++ src/layout/IHyprLayout.cpp | 12 ++++++++++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 00dba2003c7..87ca3b7ff53 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2867,3 +2867,17 @@ std::string SConfigOptionDescription::jsonify() const { void CConfigManager::ensurePersistentWorkspacesPresent() { g_pCompositor->ensurePersistentWorkspacesPresent(m_vWorkspaceRules); } + +void CConfigManager::storeFloatingSize(const std::string& szClass, const std::string& szTitle, const Vector2D& size) { + Debug::log(LOG, "storing floating size {}x{} for window {}::{}", size.x, size.y, szClass, szTitle); + m_mStoredFloatingSizes[szClass + "|||" + szTitle] = size; +} + +std::optional CConfigManager::getStoredFloatingSize(const std::string& szClass, const std::string& szTitle) { + const auto KEY = szClass + "|||" + szTitle; + if (m_mStoredFloatingSizes.contains(KEY)) { + Debug::log(LOG, "got stored size {}x{} for window {}::{}", m_mStoredFloatingSizes[KEY].x, m_mStoredFloatingSizes[KEY].y, szClass, szTitle); + return m_mStoredFloatingSizes[KEY]; + } + return std::nullopt; +} diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index b914a3a35c2..9ca5549d5d8 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -260,10 +260,13 @@ class CConfigManager { {"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }}, {"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}}; - bool m_bWantsMonitorReload = false; - bool m_bNoMonitorReload = false; - bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking - bool m_bLastConfigVerificationWasSuccessful = true; + bool m_bWantsMonitorReload = false; + bool m_bNoMonitorReload = false; + bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking + bool m_bLastConfigVerificationWasSuccessful = true; + + void storeFloatingSize(const std::string& szClass, const std::string& szTitle, const Vector2D& size); + std::optional getStoredFloatingSize(const std::string& szClass, const std::string& szTitle); private: UP m_pConfig; @@ -298,13 +301,15 @@ class CConfigManager { std::string m_szConfigErrors = ""; // internal methods - void updateBlurredLS(const std::string&, const bool); - void setDefaultAnimationVars(); - std::optional resetHLConfig(); - std::optional generateConfig(std::string configPath); - std::optional verifyConfigExists(); - void postConfigReload(const Hyprlang::CParseResult& result); - SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); + void updateBlurredLS(const std::string&, const bool); + void setDefaultAnimationVars(); + std::optional resetHLConfig(); + std::optional generateConfig(std::string configPath); + std::optional verifyConfigExists(); + void postConfigReload(const Hyprlang::CParseResult& result); + SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); + + std::unordered_map m_mStoredFloatingSizes; }; inline UP g_pConfigManager; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 7b7f954db40..28866bc3950 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -789,6 +789,10 @@ void CWindow::applyDynamicRule(const SP& r) { } break; } + case CWindowRule::RULE_PERSISTENTSIZE: { + m_sWindowData.persistentSize = CWindowOverridableVar(true, PRIORITY_WINDOW_RULE); + break; + } default: break; } } @@ -1321,6 +1325,11 @@ void CWindow::clampWindowSize(const std::optional minSize, const std:: *m_vRealPosition = m_vRealPosition->goal() + DELTA / 2.0; *m_vRealSize = NEWSIZE; + + if (m_bIsFloating && !m_bIsX11 && std::any_of(m_vMatchedRules.begin(), m_vMatchedRules.end(), [](const auto& r) { return r->ruleType == CWindowRule::RULE_PERSISTENTSIZE; })) { + Debug::log(LOG, "clamped window {}::{} to {}x{} (persistentsize)", m_szClass, m_szTitle, m_vRealSize->value().x, m_vRealSize->value().y); + g_pConfigManager->storeFloatingSize(m_szClass, m_szTitle, m_vRealSize->value()); + } } bool CWindow::isFullscreen() { diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index bc32bab47e0..23d47d695fd 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -198,6 +198,8 @@ struct SWindowData { CWindowOverridableVar activeBorderColor; CWindowOverridableVar inactiveBorderColor; + + CWindowOverridableVar persistentSize; }; struct SInitialWorkspaceToken { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index e84ffb2130d..849cd2b6c1e 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -14,9 +14,17 @@ #include "../managers/HookSystemManager.hpp" void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { - CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow); + CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow); - if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) { + const bool HASPERSISTENTSIZE = + std::any_of(pWindow->m_vMatchedRules.begin(), pWindow->m_vMatchedRules.end(), [](const auto& rule) { return rule->ruleType == CWindowRule::RULE_PERSISTENTSIZE; }); + + const auto STOREDSIZE = HASPERSISTENTSIZE ? g_pConfigManager->getStoredFloatingSize(pWindow->m_szClass, pWindow->m_szTitle) : std::nullopt; + + if (STOREDSIZE.has_value()) { + Debug::log(LOG, "using stored size {}x{} for new window {}::{}", STOREDSIZE->x, STOREDSIZE->y, pWindow->m_szClass, pWindow->m_szTitle); + pWindow->m_vLastFloatingSize = STOREDSIZE.value(); + } else if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) { const auto PMONITOR = pWindow->m_pMonitor.lock(); pWindow->m_vLastFloatingSize = PMONITOR->vecSize / 2.f; } else From 23cd6a7e7e7359b30150e27ed6ff5f99c224170d Mon Sep 17 00:00:00 2001 From: nnyyxxxx Date: Tue, 25 Feb 2025 12:12:53 -0500 Subject: [PATCH 2/4] e --- src/config/ConfigManager.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 9ca5549d5d8..9a6b7ef7368 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -309,7 +309,15 @@ class CConfigManager { void postConfigReload(const Hyprlang::CParseResult& result); SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); + void registerConfigVar(const char* name, const Hyprlang::INT& val); + void registerConfigVar(const char* name, const Hyprlang::FLOAT& val); + void registerConfigVar(const char* name, const Hyprlang::VEC2& val); + void registerConfigVar(const char* name, const Hyprlang::STRING& val); + void registerConfigVar(const char* name, Hyprlang::CUSTOMTYPE&& val); + std::unordered_map m_mStoredFloatingSizes; + + friend struct SConfigOptionDescription; }; inline UP g_pConfigManager; From b4463e130af349c3a3abbc5d8ffaba23899e545b Mon Sep 17 00:00:00 2001 From: nnyyxxxx Date: Tue, 25 Feb 2025 12:15:25 -0500 Subject: [PATCH 3/4] e --- src/desktop/WindowRule.cpp | 2 +- src/desktop/WindowRule.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index fea2d43b2cf..d767e60fc21 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -5,7 +5,7 @@ #include "../config/ConfigManager.hpp" static const auto RULES = std::unordered_set{ - "float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", + "float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", "persistentsize", }; static const auto RULES_PREFIX = std::unordered_set{ "animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp index 50e221f3e8d..192d8aa7125 100644 --- a/src/desktop/WindowRule.hpp +++ b/src/desktop/WindowRule.hpp @@ -37,6 +37,7 @@ class CWindowRule { RULE_WORKSPACE, RULE_PROP, RULE_CONTENT, + RULE_PERSISTENTSIZE, }; eRuleType ruleType = RULE_INVALID; From 4d7b35591b1e7d9ccf49fad75fdba1d45e3b2d2e Mon Sep 17 00:00:00 2001 From: nnyyxxxx Date: Tue, 25 Feb 2025 12:21:50 -0500 Subject: [PATCH 4/4] e --- src/desktop/WindowRule.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index d767e60fc21..2f6895d54c3 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -39,6 +39,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_TILE; else if (rule == "renderunfocused") ruleType = RULE_RENDERUNFOCUSED; + else if (rule == "persistentsize") + ruleType = RULE_PERSISTENTSIZE; else if (rule.starts_with("animation")) ruleType = RULE_ANIMATION; else if (rule.starts_with("bordercolor"))