diff --git a/lib/platform/CXWindowsScreenSaver.cpp b/lib/platform/CXWindowsScreenSaver.cpp index c712f826..e421cf09 100644 --- a/lib/platform/CXWindowsScreenSaver.cpp +++ b/lib/platform/CXWindowsScreenSaver.cpp @@ -35,7 +35,9 @@ CXWindowsScreenSaver::CXWindowsScreenSaver( m_notify(None), m_xscreensaver(None), m_xscreensaverActive(false), - m_disabled(false) + m_disabled(false), + m_suppressDisable(false), + m_disableJobInstalled(false) { // screen saver disable callback m_disableJob = new TMethodJob(this, @@ -184,7 +186,7 @@ CXWindowsScreenSaver::enable() { // for xscreensaver m_disabled = false; - m_screen->removeTimer(m_disableJob); + updateDisableJob(); // for built-in X screen saver XSetScreenSaver(m_display, m_timeout, m_interval, @@ -197,7 +199,7 @@ CXWindowsScreenSaver::disable() // for xscreensaver. 5 seconds should be plenty often to // suppress the screen saver. m_disabled = true; - m_screen->addTimer(m_disableJob, 5.0); + updateDisableJob(); // use built-in X screen saver XGetScreenSaver(m_display, &m_timeout, &m_interval, @@ -211,9 +213,8 @@ void CXWindowsScreenSaver::activate() { // remove disable job timer - if (m_disabled) { - m_screen->removeTimer(m_disableJob); - } + m_suppressDisable = true; + updateDisableJob(); // try xscreensaver findXScreenSaver(); @@ -230,9 +231,8 @@ void CXWindowsScreenSaver::deactivate() { // reinstall disable job timer - if (m_disabled) { - m_screen->addTimer(m_disableJob, 5.0); - } + m_suppressDisable = false; + updateDisableJob(); // try xscreensaver findXScreenSaver(); @@ -346,6 +346,14 @@ CXWindowsScreenSaver::setXScreenSaverActive(bool activated) if (m_xscreensaverActive != activated) { LOG((CLOG_DEBUG "xscreensaver %s on window 0x%08x", activated ? "activated" : "deactivated", m_xscreensaver)); m_xscreensaverActive = activated; + + // if screen saver was activated forcefully (i.e. against + // our will) then just accept it. don't try to keep it + // from activating since that'll just pop up the password + // dialog if locking is enabled. + m_suppressDisable = activated; + updateDisableJob(); + sendNotify(activated); } } @@ -433,6 +441,21 @@ CXWindowsScreenSaver::addWatchXScreenSaver(Window window) } } +void +CXWindowsScreenSaver::updateDisableJob() +{ + assert(m_disableJob != NULL); + + if (m_disabled && !m_suppressDisable && !m_disableJobInstalled) { + m_disableJobInstalled = true; + m_screen->addTimer(m_disableJob, 5.0); + } + else if ((!m_disabled || m_suppressDisable) && m_disableJobInstalled) { + m_disableJobInstalled = false; + m_screen->removeTimer(m_disableJob); + } +} + void CXWindowsScreenSaver::disableCallback(void*) { diff --git a/lib/platform/CXWindowsScreenSaver.h b/lib/platform/CXWindowsScreenSaver.h index dd1050cb..3285a1b7 100644 --- a/lib/platform/CXWindowsScreenSaver.h +++ b/lib/platform/CXWindowsScreenSaver.h @@ -97,6 +97,9 @@ private: // add window to the watch list void addWatchXScreenSaver(Window window); + // install/uninstall the job used to suppress the screensaver + void updateDisableJob(); + // called periodically to prevent the screen saver from starting void disableCallback(void*); @@ -140,9 +143,17 @@ private: int m_preferBlanking; int m_allowExposures; - // true iff the disabled job timer is installed + // true iff the client wants the screen saver suppressed bool m_disabled; + // true iff we're ignoring m_disabled. this is true, for example, + // when the client has called activate() and so presumably wants + // to activate the screen saver even if disabled. + bool m_suppressDisable; + + // true iff the disabled job timer is installed + bool m_disableJobInstalled; + // the job used to invoke disableCallback IJob* m_disableJob; };