aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJef <[email protected]>2022-11-15 11:21:26 +0100
committerGitHub <[email protected]>2022-11-15 10:21:26 +0000
commitdbb67327430574fc9c68a03bc6b896478560e95f (patch)
treeb48bdc8463868eee0cb99dafa094f2a6f4f10e98
parent4034aa2c60d7ed88cb64e7c36f42ec388c28cfb2 (diff)
downloadHyprland-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.cpp3
-rw-r--r--src/Window.cpp72
-rw-r--r--src/Window.hpp15
-rw-r--r--src/config/ConfigManager.cpp34
-rw-r--r--src/config/ConfigManager.hpp11
-rw-r--r--src/events/Windows.cpp50
-rw-r--r--src/managers/KeybindManager.cpp5
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());