diff --git a/daemon/powerdevilcore.h b/daemon/powerdevilcore.h --- a/daemon/powerdevilcore.h +++ b/daemon/powerdevilcore.h @@ -23,8 +23,9 @@ #include "powerdevilbackendinterface.h" -#include #include +#include +#include #include @@ -128,7 +129,7 @@ // Idle time management QHash< Action*, QList< int > > m_registeredActionTimeouts; - QList< Action* > m_pendingResumeFromIdleActions; + QSet m_pendingResumeFromIdleActions; bool m_pendingWakeupEvent; // Activity inhibition management diff --git a/daemon/powerdevilcore.cpp b/daemon/powerdevilcore.cpp --- a/daemon/powerdevilcore.cpp +++ b/daemon/powerdevilcore.cpp @@ -702,15 +702,22 @@ void Core::onKIdleTimeoutReached(int identifier, int msec) { + // Bug 354250: Only trigger actions if we're the currently active session + // although we simulate user activity when becoming the active session, + // after a user switch we get delivered all pending idle timeouts and may + // errorneously send the computer to sleep + if (!PolicyAgent::instance()->isSessionActive()) { + qCDebug(POWERDEVIL) << "Idle timeout reached but we're not the active session, not triggering actions"; + return; + } + // Find which action(s) requested this idle timeout - for (QHash< Action*, QList< int > >::const_iterator i = m_registeredActionTimeouts.constBegin(); - i != m_registeredActionTimeouts.constEnd(); ++i) { + for (auto i = m_registeredActionTimeouts.constBegin(), end = m_registeredActionTimeouts.constEnd(); i != end; ++i) { if (i.value().contains(identifier)) { i.key()->onIdleTimeout(msec); + // And it will need to be awaken - if (!m_pendingResumeFromIdleActions.contains(i.key())) { - m_pendingResumeFromIdleActions.append(i.key()); - } + m_pendingResumeFromIdleActions.insert(i.key()); break; } } @@ -761,11 +768,10 @@ void Core::onResumingFromIdle() { // Wake up the actions in which an idle action was triggered - QList< Action* >::iterator i = m_pendingResumeFromIdleActions.begin(); - while (i != m_pendingResumeFromIdleActions.end()) { - (*i)->onWakeupFromIdle(); - i = m_pendingResumeFromIdleActions.erase(i); + for (auto it = m_pendingResumeFromIdleActions.constBegin(), end = m_pendingResumeFromIdleActions.constEnd(); it != end; ++it) { + (*it)->onWakeupFromIdle(); } + m_pendingResumeFromIdleActions.clear(); } void Core::onNotificationTimeout() diff --git a/daemon/powerdevilpolicyagent.h b/daemon/powerdevilpolicyagent.h --- a/daemon/powerdevilpolicyagent.h +++ b/daemon/powerdevilpolicyagent.h @@ -79,6 +79,8 @@ void setupSystemdInhibition(); + bool isSessionActive() const; + public Q_SLOTS: // Exported slots uint AddInhibition(uint types, const QString &appName, const QString &reason); diff --git a/daemon/powerdevilpolicyagent.cpp b/daemon/powerdevilpolicyagent.cpp --- a/daemon/powerdevilpolicyagent.cpp +++ b/daemon/powerdevilpolicyagent.cpp @@ -612,4 +612,9 @@ qCWarning(POWERDEVIL) << "failed to inhibit systemd powersave handling"; } +bool PolicyAgent::isSessionActive() const +{ + return m_wasLastActiveSession; +} + }