summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2025-04-29 18:14:02 +0100
committerVaxry <vaxry@vaxry.net>2025-04-29 18:14:02 +0100
commitb10a43dabc0d65a03a3a169ff292f0f18d9c6640 (patch)
treeba93bdd1b1a1235ae0bd16f7569815dd8d224250 /src
parent5bd7ff884dc613ad22ecd227d41ce6ad7ee336df (diff)
windowrules: add noclosefor
fixes #10027
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp3
-rw-r--r--src/desktop/Window.hpp3
-rw-r--r--src/desktop/WindowRule.cpp8
-rw-r--r--src/desktop/WindowRule.hpp3
-rw-r--r--src/events/Windows.cpp6
-rw-r--r--src/managers/KeybindManager.cpp6
6 files changed, 23 insertions, 6 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index be03edac..212e514b 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -2547,9 +2547,8 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
}
void CCompositor::closeWindow(PHLWINDOW pWindow) {
- if (pWindow && validMapped(pWindow)) {
+ if (pWindow && validMapped(pWindow))
g_pXWaylandManager->sendCloseWindow(pWindow);
- }
}
PHLLS CCompositor::getLayerSurfaceFromSurface(SP<CWLSurfaceResource> pSurface) {
diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp
index 8a6590bd..cc62dd3b 100644
--- a/src/desktop/Window.hpp
+++ b/src/desktop/Window.hpp
@@ -311,6 +311,9 @@ class CWindow {
// ANR
PHLANIMVAR<float> m_notRespondingTint;
+ // For the noclosefor windowrule
+ Time::steady_tp m_closeableSince = Time::steadyNow();
+
// For the list lookup
bool operator==(const CWindow& rhs) const {
return m_xdgSurface == rhs.m_xdgSurface && m_xwaylandSurface == rhs.m_xwaylandSurface && m_position == rhs.m_position && m_size == rhs.m_size &&
diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp
index 245d1583..db1b0dde 100644
--- a/src/desktop/WindowRule.cpp
+++ b/src/desktop/WindowRule.cpp
@@ -8,9 +8,9 @@ static const auto RULES = std::unordered_set<std::string>{
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", "persistentsize",
};
static const auto RULES_PREFIX = std::unordered_set<std::string>{
- "animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize",
- "monitor", "move", "opacity", "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad",
- "size", "suppressevent", "tag", "workspace", "xray",
+ "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",
};
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) {
@@ -79,6 +79,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool
m_ruleType = RULE_PROP;
else if (rule.starts_with("content"))
m_ruleType = RULE_CONTENT;
+ else if (rule.starts_with("noclosefor"))
+ m_ruleType = RULE_NOCLOSEFOR;
else {
// check if this is a prop.
const CVarList VARS(rule, 0, 's', true);
diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp
index 084c67f9..9af3909a 100644
--- a/src/desktop/WindowRule.hpp
+++ b/src/desktop/WindowRule.hpp
@@ -37,7 +37,8 @@ class CWindowRule {
RULE_WORKSPACE,
RULE_PROP,
RULE_CONTENT,
- RULE_PERSISTENTSIZE
+ RULE_PERSISTENTSIZE,
+ RULE_NOCLOSEFOR,
};
eRuleType m_ruleType = RULE_INVALID;
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index 3cff2516..9e0d2be5 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -315,6 +315,12 @@ void Events::listener_mapWindow(void* owner, void* data) {
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
break;
}
+ case CWindowRule::RULE_NOCLOSEFOR: {
+ const CVarList VARS(r->m_rule, 0, ' ');
+ 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()); }
+ }
default: break;
}
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index f30f65a1..7f0045e0 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -1037,6 +1037,9 @@ SDispatchResult CKeybindManager::killActive(std::string args) {
}
SDispatchResult CKeybindManager::closeActive(std::string args) {
+ if (g_pCompositor->m_lastWindow && g_pCompositor->m_lastWindow->m_closeableSince > Time::steadyNow())
+ return {.success = false, .error = "can't close window, it's not closeable yet (noclosefor)"};
+
g_pCompositor->closeWindow(g_pCompositor->m_lastWindow.lock());
return {};
@@ -1050,6 +1053,9 @@ SDispatchResult CKeybindManager::closeWindow(std::string args) {
return {.success = false, .error = "closeWindow: no window found"};
}
+ if (PWINDOW->m_closeableSince > Time::steadyNow())
+ return {.success = false, .error = "can't close window, it's not closeable yet (noclosefor)"};
+
g_pCompositor->closeWindow(PWINDOW);
return {};