diff options
author | Jef <[email protected]> | 2022-11-15 11:21:26 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2022-11-15 10:21:26 +0000 |
commit | dbb67327430574fc9c68a03bc6b896478560e95f (patch) | |
tree | b48bdc8463868eee0cb99dafa094f2a6f4f10e98 | |
parent | 4034aa2c60d7ed88cb64e7c36f42ec388c28cfb2 (diff) | |
download | Hyprland-dbb67327430574fc9c68a03bc6b896478560e95f.tar.gz Hyprland-dbb67327430574fc9c68a03bc6b896478560e95f.zip |
apply some rules dynamically when state of window changes (#1020)
Co-authored-by: Jef Steelant <[email protected]>
-rw-r--r-- | src/Compositor.cpp | 3 | ||||
-rw-r--r-- | src/Window.cpp | 72 | ||||
-rw-r--r-- | src/Window.hpp | 15 | ||||
-rw-r--r-- | src/config/ConfigManager.cpp | 34 | ||||
-rw-r--r-- | src/config/ConfigManager.hpp | 11 | ||||
-rw-r--r-- | src/events/Windows.cpp | 50 | ||||
-rw-r--r-- | src/managers/KeybindManager.cpp | 5 |
7 files changed, 130 insertions, 60 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp index b1bbe800..43bfbe78 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1732,6 +1732,9 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL); + pWindow->updateDynamicRules(); + g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); + // make all windows on the same workspace under the fullscreen window for (auto& w : g_pCompositor->m_vWindows) { if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) { diff --git a/src/Window.cpp b/src/Window.cpp index 9666b2dc..31cbb3ce 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -291,4 +291,74 @@ void CWindow::setHidden(bool hidden) { bool CWindow::isHidden() { return m_bHidden; -}
\ No newline at end of file +} + +void CWindow::applyDynamicRule(const SWindowRule& r) { + if (r.szRule == "noblur") { + m_sAdditionalConfigData.forceNoBlur = true; + } else if (r.szRule == "noborder") { + m_sAdditionalConfigData.forceNoBorder = true; + } else if (r.szRule == "noshadow") { + m_sAdditionalConfigData.forceNoShadow = true; + } else if (r.szRule == "opaque") { + m_sAdditionalConfigData.forceOpaque = true; + } else if (r.szRule.find("rounding") == 0) { + try { + m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); + } catch (std::exception& e) { + Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); + } + } else if (r.szRule.find("opacity") == 0) { + try { + std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); + + if (alphaPart.contains(' ')) { + // we have a space, 2 values + m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' '))); + m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1)); + } else { + m_sSpecialRenderData.alpha = std::stof(alphaPart); + } + } catch(std::exception& e) { + Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); + } + } else if (r.szRule == "noanim") { + m_sAdditionalConfigData.forceNoAnims = true; + } else if (r.szRule.find("animation") == 0) { + auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1); + m_sAdditionalConfigData.animationStyle = STYLE; + } else if (r.szRule.find("bordercolor") == 0) { + try { + std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); + + if (colorPart.contains(' ')) { + // we have a space, 2 values + m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' '))); + m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1)); + } else { + m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart); + } + } catch(std::exception& e) { + Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); + } + } +} + +void CWindow::updateDynamicRules() { + m_sSpecialRenderData.activeBorderColor = -1; + m_sSpecialRenderData.inactiveBorderColor = -1; + m_sSpecialRenderData.alpha = 1.f; + m_sSpecialRenderData.alphaInactive = -1.f; + m_sAdditionalConfigData.forceNoBlur = false; + m_sAdditionalConfigData.forceNoBorder = false; + m_sAdditionalConfigData.forceNoShadow = false; + m_sAdditionalConfigData.forceOpaque = false; + m_sAdditionalConfigData.forceNoAnims = false; + m_sAdditionalConfigData.animationStyle = ""; + m_sAdditionalConfigData.rounding = -1; + + const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this); + for (auto& r : WINDOWRULES) { + applyDynamicRule(r); + } +} diff --git a/src/Window.hpp b/src/Window.hpp index a8e1bd6b..b0014af9 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -39,6 +39,19 @@ struct SWindowAdditionalConfigData { bool windowDanceCompat = false; }; +struct SWindowRule { + std::string szRule; + std::string szValue; + + bool v2 = false; + std::string szTitle; + std::string szClass; + int bX11 = -1; // -1 means "ANY" + int bFloating = -1; + int bFullscreen = -1; + int bPinned = -1; +}; + class CWindow { public: CWindow(); @@ -189,6 +202,8 @@ public: void onMap(); void setHidden(bool hidden); bool isHidden(); + void applyDynamicRule(const SWindowRule& r); + void updateDynamicRules(); private: // For hidden windows and stuff diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 63227479..fae72be1 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -732,8 +732,12 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s const auto CLASSPOS = VALUE.find("class:"); const auto X11POS = VALUE.find("xwayland:"); const auto FLOATPOS = VALUE.find("floating:"); + const auto FULLSCREENPOS = VALUE.find("fullscreen:"); + const auto PINNEDPOS = VALUE.find("pinned:"); - if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos && X11POS == std::string::npos && FLOATPOS == std::string::npos) { + if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos && + X11POS == std::string::npos && FLOATPOS == std::string::npos && + FULLSCREENPOS == std::string::npos && PINNEDPOS == std::string::npos) { Debug::log(ERR, "Invalid rulev2 syntax: %s", VALUE.c_str()); parseError = "Invalid rulev2 syntax: " + VALUE; return; @@ -748,6 +752,8 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s if (CLASSPOS > pos && CLASSPOS < min) min = CLASSPOS; if (X11POS > pos && X11POS < min) min = X11POS; if (FLOATPOS > pos && FLOATPOS < min) min = FLOATPOS; + if (FULLSCREENPOS > pos && FULLSCREENPOS < min) min = FULLSCREENPOS; + if (PINNEDPOS > pos && PINNEDPOS < min) min = PINNEDPOS; result = result.substr(0, min - pos); @@ -775,6 +781,14 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s rule.bFloating = extract(FLOATPOS + 9) == "1" ? 1 : 0; } + if (FULLSCREENPOS != std::string::npos) { + rule.bFullscreen = extract(FULLSCREENPOS + 11) == "1" ? 1 : 0; + } + + if (PINNEDPOS != std::string::npos) { + rule.bPinned = extract(PINNEDPOS + 7) == "1" ? 1 : 0; + } + if (RULE == "unset") { std::erase_if(m_dWindowRules, [&](const SWindowRule& other) { if (!other.v2) { @@ -796,6 +810,14 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s return false; } + if (rule.bFullscreen != -1 && rule.bFullscreen != other.bFullscreen) { + return false; + } + + if (rule.bPinned != -1 && rule.bPinned != other.bPinned) { + return false; + } + return true; } }); @@ -1389,6 +1411,16 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) { if (pWindow->m_bIsFloating != rule.bFloating) continue; } + + if (rule.bFullscreen != -1) { + if (pWindow->m_bIsFullscreen != rule.bFullscreen) + continue; + } + + if (rule.bPinned != -1) { + if (pWindow->m_bPinned != rule.bPinned) + continue; + } } catch (...) { Debug::log(ERR, "Regex error at %s", rule.szValue.c_str()); continue; diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index b78cb273..58f020ba 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -48,17 +48,6 @@ struct SMonitorAdditionalReservedArea { int right = 0; }; -struct SWindowRule { - std::string szRule; - std::string szValue; - - bool v2 = false; - std::string szTitle; - std::string szClass; - int bX11 = -1; // -1 means "ANY" - int bFloating = -1; -}; - struct SAnimationPropertyConfig { bool overriden = true; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 3dcd7dc0..24a3fcd4 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -161,47 +161,14 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bIsPseudotiled = true; } else if (r.szRule.find("nofocus") == 0) { PWINDOW->m_bNoFocus = true; - } else if (r.szRule == "noblur") { - PWINDOW->m_sAdditionalConfigData.forceNoBlur = true; - } else if (r.szRule == "noborder") { - PWINDOW->m_sAdditionalConfigData.forceNoBorder = true; - } else if (r.szRule == "noshadow") { - PWINDOW->m_sAdditionalConfigData.forceNoShadow = true; } else if (r.szRule == "fullscreen") { requestsFullscreen = true; - } else if (r.szRule == "opaque") { - PWINDOW->m_sAdditionalConfigData.forceOpaque = true; } else if (r.szRule == "windowdance") { PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true; } else if (r.szRule == "forceinput") { PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true; } else if (r.szRule == "pin") { PWINDOW->m_bPinned = true; - } else if (r.szRule == "noanim") { - PWINDOW->m_sAdditionalConfigData.forceNoAnims = true; - } else if (r.szRule.find("rounding") == 0) { - try { - PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); - } catch (std::exception& e) { - Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); - } - } else if (r.szRule.find("opacity") == 0) { - try { - std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); - - if (alphaPart.contains(' ')) { - // we have a space, 2 values - PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' '))); - PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1)); - } else { - PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart); - } - } catch(std::exception& e) { - Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); - } - } else if (r.szRule.find("animation") == 0) { - auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1); - PWINDOW->m_sAdditionalConfigData.animationStyle = STYLE; } else if (r.szRule.find("idleinhibit") == 0) { auto IDLERULE = r.szRule.substr(r.szRule.find_first_of(' ') + 1); @@ -216,21 +183,8 @@ void Events::listener_mapWindow(void* owner, void* data) { } else { Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str()); } - } else if (r.szRule.find("bordercolor") == 0) { - try { - std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); - - if (colorPart.contains(' ')) { - // we have a space, 2 values - PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' '))); - PWINDOW->m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1)); - } else { - PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart); - } - } catch(std::exception& e) { - Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); - } } + PWINDOW->applyDynamicRule(r); } // disallow tiled pinned @@ -752,6 +706,8 @@ void Events::listener_setTitleWindow(void* owner, void* data) { if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle}); + PWINDOW->updateDynamicRules(); + g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); PWINDOW->updateToplevel(); Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str()); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a2f76d69..b27087ba 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -599,6 +599,8 @@ void CKeybindManager::toggleActiveFloating(std::string args) { PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; + PWINDOW->updateDynamicRules(); + g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); } @@ -1707,6 +1709,9 @@ void CKeybindManager::pinActive(std::string args) { g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned; g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace; + g_pCompositor->m_pLastWindow->updateDynamicRules(); + g_pCompositor->updateWindowAnimatedDecorationValues(g_pCompositor->m_pLastWindow); + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID); PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()); |