Ignore idle inhibition per-listener

Add `ignore_inhibit` option (bool) to listener section of config file,
to allow ignoring idle inhibition per-listener. When set to true, all
types of inhibitors are ignored (systemd, dbus/ScreenSaver, Wayland).
Default value: false (the rule will obey inhibition)

Example:

    listener {
        timeout = 5
        on-timeout = logger 'should obey idle inhibition'
    }

    listener {
        timeout = 6
        on-timeout = logger 'should ignore idle inhibition'
        ignore_inhibit = true
    }
This commit is contained in:
Chris Hixon 2025-05-29 23:34:16 -06:00
parent 4f6bc4dbab
commit 9e348c0628
4 changed files with 17 additions and 6 deletions

View file

@ -37,6 +37,7 @@ void CConfigManager::init() {
m_config.addSpecialConfigValue("listener", "timeout", Hyprlang::INT{-1});
m_config.addSpecialConfigValue("listener", "on-timeout", Hyprlang::STRING{""});
m_config.addSpecialConfigValue("listener", "on-resume", Hyprlang::STRING{""});
m_config.addSpecialConfigValue("listener", "ignore_inhibit", Hyprlang::INT{0});
m_config.addConfigValue("general:lock_cmd", Hyprlang::STRING{""});
m_config.addConfigValue("general:unlock_cmd", Hyprlang::STRING{""});
@ -86,6 +87,8 @@ Hyprlang::CParseResult CConfigManager::postParse() {
rule.onTimeout = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-timeout", k.c_str()));
rule.onResume = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("listener", "on-resume", k.c_str()));
rule.ignoreInhibit = std::any_cast<Hyprlang::INT>(m_config.getSpecialConfigValue("listener", "ignore_inhibit", k.c_str()));
if (timeout == -1) {
result.setError("Category has a missing timeout setting");
continue;
@ -95,7 +98,7 @@ Hyprlang::CParseResult CConfigManager::postParse() {
}
for (auto& r : m_vRules) {
Debug::log(LOG, "Registered timeout rule for {}s:\n on-timeout: {}\n on-resume: {}", r.timeout, r.onTimeout, r.onResume);
Debug::log(LOG, "Registered timeout rule for {}s:\n on-timeout: {}\n on-resume: {}\n ignore_inhibit: {}", r.timeout, r.onTimeout, r.onResume, r.ignoreInhibit);
}
return result;

View file

@ -17,6 +17,7 @@ class CConfigManager {
uint64_t timeout = 0;
std::string onTimeout = "";
std::string onResume = "";
bool ignoreInhibit = false;
};
std::vector<STimeoutRule> getRules();

View file

@ -55,7 +55,6 @@ void CHypridle::run() {
}
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
static const auto notificationFunc = *IGNOREWAYLANDINHIBIT ? &CCExtIdleNotifierV1::sendGetInputIdleNotification : &CCExtIdleNotifierV1::sendGetIdleNotification;
const auto RULES = g_pConfigManager->getRules();
m_sWaylandIdleState.listeners.resize(RULES.size());
@ -67,6 +66,11 @@ void CHypridle::run() {
const auto& r = RULES[i];
l.onRestore = r.onResume;
l.onTimeout = r.onTimeout;
l.ignoreInhibit = r.ignoreInhibit;
auto notificationFunc = (*IGNOREWAYLANDINHIBIT || r.ignoreInhibit) ?
&CCExtIdleNotifierV1::sendGetInputIdleNotification :
&CCExtIdleNotifierV1::sendGetIdleNotification;
l.notification = makeShared<CCExtIdleNotificationV1>(
(*(m_sWaylandIdleState.notifier).*(notificationFunc))
@ -254,7 +258,7 @@ static void spawn(const std::string& args) {
void CHypridle::onIdled(SIdleListener* pListener) {
Debug::log(LOG, "Idled: rule {:x}", (uintptr_t)pListener);
isIdled = true;
if (g_pHypridle->m_iInhibitLocks > 0) {
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
Debug::log(LOG, "Ignoring from onIdled(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
return;
}
@ -271,7 +275,7 @@ void CHypridle::onIdled(SIdleListener* pListener) {
void CHypridle::onResumed(SIdleListener* pListener) {
Debug::log(LOG, "Resumed: rule {:x}", (uintptr_t)pListener);
isIdled = false;
if (g_pHypridle->m_iInhibitLocks > 0) {
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
Debug::log(LOG, "Ignoring from onResumed(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
return;
}
@ -295,16 +299,18 @@ void CHypridle::onInhibit(bool lock) {
if (m_iInhibitLocks == 0 && isIdled) {
static const auto IGNOREWAYLANDINHIBIT = g_pConfigManager->getValue<Hyprlang::INT>("general:ignore_wayland_inhibit");
static const auto notificationFunc = *IGNOREWAYLANDINHIBIT ? &CCExtIdleNotifierV1::sendGetInputIdleNotification : &CCExtIdleNotifierV1::sendGetIdleNotification;
const auto RULES = g_pConfigManager->getRules();
for (size_t i = 0; i < RULES.size(); ++i) {
auto& l = m_sWaylandIdleState.listeners[i];
const auto& r = RULES[i];
l.notification->sendDestroy();
auto notificationFunc = (*IGNOREWAYLANDINHIBIT || r.ignoreInhibit) ?
&CCExtIdleNotifierV1::sendGetInputIdleNotification :
&CCExtIdleNotifierV1::sendGetIdleNotification;
l.notification = makeShared<CCExtIdleNotificationV1>(
(*(m_sWaylandIdleState.notifier).*(notificationFunc))
(r.timeout * 1000 /* ms */, m_sWaylandState.seat->resource()));

View file

@ -20,6 +20,7 @@ class CHypridle {
SP<CCExtIdleNotificationV1> notification = nullptr;
std::string onTimeout = "";
std::string onRestore = "";
bool ignoreInhibit = false;
};
struct SDbusInhibitCookie {