core: don't skip on-resume when on-timeout already fired

When on-timeout has executed (e.g. DPMS off) and a ScreenSaver inhibit
lock arrives afterward (e.g. from a notification sound), on-resume was
blocked by the inhibit check, leaving monitors stuck off.

Track per-listener whether on-timeout actually executed. On resume,
check this flag instead of the inhibit lock count: if on-timeout ran,
on-resume must run unconditionally. If on-timeout was itself inhibited,
skip on-resume symmetrically.

Fixes #128
This commit is contained in:
Martin Schrodt 2026-04-01 20:29:27 +03:00
parent d0f7778c4e
commit 0d0e57ce2b
2 changed files with 12 additions and 6 deletions

View file

@ -269,17 +269,22 @@ void CHypridle::onIdled(SIdleListener* pListener) {
}
Debug::log(LOG, "Running {}", pListener->onTimeout);
pListener->onTimeoutFired = true;
spawn(pListener->onTimeout);
}
void CHypridle::onResumed(SIdleListener* pListener) {
Debug::log(LOG, "Resumed: rule {:x}", (uintptr_t)pListener);
isIdled = false;
if (g_pHypridle->m_iInhibitLocks > 0 && !pListener->ignoreInhibit) {
Debug::log(LOG, "Ignoring from onResumed(), inhibit locks: {}", g_pHypridle->m_iInhibitLocks);
// If on-timeout never actually executed (was inhibited), skip on-resume too
if (!pListener->onTimeoutFired) {
Debug::log(LOG, "Skipping onResumed: onTimeout was inhibited for rule {:x}", (uintptr_t)pListener);
return;
}
pListener->onTimeoutFired = false;
if (pListener->onRestore.empty()) {
Debug::log(LOG, "Ignoring, onRestore is empty.");
return;

View file

@ -17,10 +17,11 @@ class CHypridle {
CHypridle();
struct SIdleListener {
SP<CCExtIdleNotificationV1> notification = nullptr;
std::string onTimeout = "";
std::string onRestore = "";
bool ignoreInhibit = false;
SP<CCExtIdleNotificationV1> notification = nullptr;
std::string onTimeout = "";
std::string onRestore = "";
bool ignoreInhibit = false;
bool onTimeoutFired = false;
};
struct SDbusInhibitCookie {