summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHleb Shauchenka <me@marleb.org>2025-08-22 11:48:42 +0200
committerGitHub <noreply@github.com>2025-08-22 10:48:42 +0100
commitfdf1612f0f0c3a1ffc221a0d9d589a9b4a2af982 (patch)
treecc644f9e81ed3cb9df3fd7fbdbdaaf47f8f3286d /src
parent42caff5587b6c43703b3c3d51878f156448994f6 (diff)
windowrules: Add `novrr` dynamic window rule (#11370)
Diffstat (limited to 'src')
-rw-r--r--src/config/ConfigManager.cpp3
-rw-r--r--src/desktop/Window.cpp5
-rw-r--r--src/desktop/Window.hpp2
-rw-r--r--src/desktop/WindowRule.cpp4
-rw-r--r--src/desktop/WindowRule.hpp1
-rw-r--r--src/events/Windows.cpp1
-rw-r--r--src/managers/KeybindManager.cpp3
7 files changed, 18 insertions, 1 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 951a5429..7f812a04 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -1848,6 +1848,9 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) {
return; // ???
bool wantVRR = PWORKSPACE->m_hasFullscreenWindow && (PWORKSPACE->m_fullscreenMode & FSMODE_FULLSCREEN);
+ if (wantVRR && PWORKSPACE->getFullscreenWindow()->m_windowData.noVRR.valueOrDefault())
+ wantVRR = false;
+
if (wantVRR && USEVRR == 3) {
const auto contentType = PWORKSPACE->getFullscreenWindow()->getContentType();
wantVRR = contentType == CONTENT_TYPE_GAME || contentType == CONTENT_TYPE_VIDEO;
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp
index 861fc2b2..c7fd6b0b 100644
--- a/src/desktop/Window.cpp
+++ b/src/desktop/Window.cpp
@@ -802,6 +802,10 @@ void CWindow::applyDynamicRule(const SP<CWindowRule>& r) {
m_windowData.persistentSize = CWindowOverridableVar(true, PRIORITY_WINDOW_RULE);
break;
}
+ case CWindowRule::RULE_NOVRR: {
+ m_windowData.noVRR = CWindowOverridableVar(true, priority);
+ break;
+ }
default: break;
}
}
@@ -821,6 +825,7 @@ void CWindow::updateDynamicRules() {
m_windowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
m_windowData.renderUnfocused.unset(PRIORITY_WINDOW_RULE);
+ m_windowData.noVRR.unset(PRIORITY_WINDOW_RULE);
m_idleInhibitMode = IDLEINHIBIT_NONE;
diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp
index 8f234a4b..7014ac2f 100644
--- a/src/desktop/Window.hpp
+++ b/src/desktop/Window.hpp
@@ -105,6 +105,7 @@ struct SWindowData {
CWindowOverridableVar<bool> renderUnfocused = false;
CWindowOverridableVar<bool> noFollowMouse = false;
CWindowOverridableVar<bool> noScreenShare = false;
+ CWindowOverridableVar<bool> noVRR = false;
CWindowOverridableVar<Hyprlang::INT> borderSize = {std::string("general:border_size"), sc<Hyprlang::INT>(0), std::nullopt};
CWindowOverridableVar<Hyprlang::INT> rounding = {std::string("decoration:rounding"), sc<Hyprlang::INT>(0), std::nullopt};
@@ -488,6 +489,7 @@ namespace NWindowProperties {
{"opaque", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.opaque; }},
{"forcergbx", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.RGBX; }},
{"syncfullscreen", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.syncFullscreen; }},
+ {"novrr", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.noVRR; }},
{"immediate", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.tearing; }},
{"xray", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.xray; }},
{"nofollowmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_windowData.noFollowMouse; }},
diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp
index 48bf2ff0..dc6564ca 100644
--- a/src/desktop/WindowRule.cpp
+++ b/src/desktop/WindowRule.cpp
@@ -10,7 +10,7 @@ static const auto RULES = std::unordered_set<std::string>{
static const auto RULES_PREFIX = std::unordered_set<std::string>{
"animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
"move", "noclosefor", "opacity", "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size",
- "suppressevent", "tag", "workspace", "xray",
+ "suppressevent", "tag", "workspace", "xray", "novrr",
};
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : m_value(value), m_rule(rule), m_v2(isV2), m_execRule(isExecRule) {
@@ -70,6 +70,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool
m_ruleType = RULE_SIZE;
else if (rule.starts_with("suppressevent"))
m_ruleType = RULE_SUPPRESSEVENT;
+ else if (rule.starts_with("novrr"))
+ m_ruleType = RULE_NOVRR;
else if (rule.starts_with("tag"))
m_ruleType = RULE_TAG;
else if (rule.starts_with("workspace"))
diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp
index b828c8ee..2efeba0f 100644
--- a/src/desktop/WindowRule.hpp
+++ b/src/desktop/WindowRule.hpp
@@ -39,6 +39,7 @@ class CWindowRule {
RULE_CONTENT,
RULE_PERSISTENTSIZE,
RULE_NOCLOSEFOR,
+ RULE_NOVRR,
};
eRuleType m_ruleType = RULE_INVALID;
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index 99a9c038..37982458 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -321,6 +321,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
try {
PWINDOW->m_closeableSince = Time::steadyNow() + std::chrono::milliseconds(std::stoull(VARS[1]));
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
+ break;
}
default: break;
}
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index ef0d3da7..1e4e5710 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -3250,6 +3250,9 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
g_pCompositor->focusWindow(PLASTWINDOW);
}
+ if (PROP == "novrr")
+ g_pConfigManager->ensureVRR(PWINDOW->m_monitor.lock());
+
for (auto const& m : g_pCompositor->m_monitors)
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->m_id);