Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
kdebase4-wallpapers
fix-screensaver-dpms.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-screensaver-dpms.diff of Package kdebase4-wallpapers
Subject: Fix screensaving and DPMS activation From: Lubos Lunak Bug: bnc#462854 Patch-upstream: r916961, r916963, r916966 See comments below or commit log messages for details. This patch also includes syncing of the screensaving code with 4.2, as I find it safer to sync with the code I know that works rather than trying to backport. diff -u -p -N -r krunner/saverengine.cpp krunner/saverengine.cpp --- krunner/saverengine.cpp 2009-01-27 16:47:51.000000000 +0100 +++ krunner/saverengine.cpp 2009-01-27 16:48:02.000000000 +0100 @@ -46,7 +46,11 @@ SaverEngine::SaverEngine() // Save X screensaver parameters XGetScreenSaver(QX11Info::display(), &mXTimeout, &mXInterval, &mXBlanking, &mXExposures); - // ... and disable it + // And disable it. The internal X screensaver is not used at all, but we use its + // internal idle timer (and it is also used by DPMS support in X). This timer must not + // be altered by this code, since e.g. resetting the counter after activating our + // screensaver would prevent DPMS from activating. We use the timer merely to detect + // user activity. XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures); mState = Waiting; @@ -87,18 +91,9 @@ SaverEngine::~SaverEngine() void SaverEngine::Lock() { - bool ok = true; if (mState == Waiting) { - ok = startLockProcess( ForceLock ); -// It takes a while for krunner_lock to start and lock the screen. -// Therefore delay the DBus call until it tells krunner that the locking is in effect. -// This is done only for --forcelock . - if( ok && calledFromDBus()) - { - mLockTransactions.append(message().createReply()); - setDelayedReply(true); - } + startLockProcess( ForceLock ); } else { @@ -133,6 +128,7 @@ void SaverEngine::saverLockReady() void SaverEngine::SimulateUserActivity() { + XForceScreenSaver( QX11Info::display(), ScreenSaverReset ); if ( mXAutoLock && mState == Waiting ) { mXAutoLock->resetTrigger(); @@ -274,6 +282,14 @@ bool SaverEngine::startLockProcess( Lock emit ActiveChanged(true); // DBus signal mState = Preparing; + // It takes a while for krunner_lock to start and lock the screen. + // Therefore delay the DBus call until it tells krunner that the locking is in effect. + // This is done only for --forcelock . + if (lock_type == ForceLock && calledFromDBus()) { + mLockTransactions.append(message().createReply()); + setDelayedReply(true); + } + return true; } @@ -311,6 +327,8 @@ void SaverEngine::lockProcessExited() // void SaverEngine::idleTimeout() { + if( mState != Waiting ) + return; // already saving startLockProcess( DefaultLock ); } diff -u -p -N -r krunner/xautolock_c.h krunner/xautolock_c.h --- krunner/xautolock_c.h 2009-01-27 16:47:51.000000000 +0100 +++ krunner/xautolock_c.h 2009-01-27 16:48:02.000000000 +0100 @@ -21,12 +21,7 @@ #ifndef __xautolock_c_h #define __xautolock_c_h -#include <config-xautolock.h> - #include <X11/Xlib.h> -#ifdef HAVE_XSCREENSAVER -# include <X11/extensions/scrnsaver.h> -#endif #ifdef __cplusplus # include <fixx11h.h> #endif @@ -55,19 +50,12 @@ extern "C" { #endif void xautolock_processEvent( XEvent* ev ); -void xautolock_queryIdleTime( Display* d); void xautolock_processQueue( void ); void xautolock_queryPointer (Display* d); void xautolock_initDiy (Display* d); void xautolock_resetTriggers( void ); void xautolock_setTrigger( int ); int xautolock_ignoreWindow( Window ); -#ifdef HAVE_XSCREENSAVER -extern int xautolock_useMit; -extern unsigned long xautolock_lastIdleTime; -#else -# define xautolock_useMit 0 -#endif extern xautolock_corner_t xautolock_corners[ 4 ]; #ifdef __cplusplus } diff -u -p -N -r krunner/xautolock.cpp krunner/xautolock.cpp --- krunner/xautolock.cpp 2009-01-27 16:47:51.000000000 +0100 +++ krunner/xautolock.cpp 2009-01-27 16:48:02.000000000 +0100 @@ -38,10 +38,6 @@ Status DPMSInfo ( Display *, CARD16 *, B #include <ctime> -#ifdef HAVE_XSCREENSAVER -int xautolock_useMit; -unsigned long xautolock_lastIdleTime; -#endif xautolock_corner_t xautolock_corners[ 4 ]; static XAutoLock* self = NULL; @@ -62,10 +58,14 @@ XAutoLock::XAutoLock() { self = this; #ifdef HAVE_XSCREENSAVER + mMitInfo = 0; int dummy; - xautolock_useMit = XScreenSaverQueryExtension( QX11Info::display(), &dummy, &dummy ); + if (XScreenSaverQueryExtension( QX11Info::display(), &dummy, &dummy )) + { + mMitInfo = XScreenSaverAllocInfo(); + } + else #endif - if( !xautolock_useMit ) { kapp->installX11EventFilter( this ); int (*oldHandler)(Display *, XErrorEvent *); @@ -83,8 +83,10 @@ XAutoLock::XAutoLock() mActive = false; mTimerId = startTimer( CHECK_INTERVAL ); + // This is an internal clock timer (in seconds), used instead of querying system time. + // It is incremented manually, preventing from problems with clock jumps. + // In other words, this is the 'now' time and the reference point for other times here. mElapsed = 0; - } //--------------------------------------------------------------------------- @@ -126,8 +128,6 @@ void XAutoLock::start() { mActive = true; resetTrigger(); - XSetScreenSaver(QX11Info::display(), mTimeout + 10, 100, PreferBlanking, DontAllowExposures); // We'll handle blanking - kDebug() << "XSetScreenSaver" << mTimeout + 10; } //--------------------------------------------------------------------------- @@ -138,8 +138,6 @@ void XAutoLock::stop() { mActive = false; resetTrigger(); - XSetScreenSaver(QX11Info::display(), 0, 100, PreferBlanking, DontAllowExposures); // No blanking at all - kDebug() << "XSetScreenSaver 0"; } //--------------------------------------------------------------------------- @@ -148,12 +146,15 @@ void XAutoLock::stop() // void XAutoLock::resetTrigger() { + // Time of the last user activity (used only when the internal XScreensaver + // idle counter is not available). mLastReset = mElapsed; + // Time when screensaver should be activated. mTrigger = mElapsed + mTimeout; #ifdef HAVE_XSCREENSAVER - xautolock_lastIdleTime = 0; + mLastIdle = 0; #endif - XForceScreenSaver( QX11Info::display(), ScreenSaverReset ); + // Do not reset the internal X screensaver here (no XForceScreenSaver()) } //--------------------------------------------------------------------------- @@ -188,57 +189,79 @@ void XAutoLock::timerEvent(QTimerEvent * } mElapsed += CHECK_INTERVAL / 1000; - int (*oldHandler)(Display *, XErrorEvent *) = NULL; - if( !xautolock_useMit ) +#ifdef HAVE_XSCREENSAVER + if (!mMitInfo) +#endif { // only the diy way needs special X handler XSync( QX11Info::display(), False ); - oldHandler = XSetErrorHandler(catchFalseAlarms); + int (*oldHandler)(Display *, XErrorEvent *) = + XSetErrorHandler(catchFalseAlarms); + + xautolock_processQueue(); + + XSetErrorHandler(oldHandler); } - xautolock_processQueue(); +#ifdef HAVE_XSCREENSAVER + if (mMitInfo) + { + Display *d = QX11Info::display(); + // Check user idle time. If it is smaller than before, it is either + // clock jump or user activity, so reset the trigger time. Checking whether + // there is user inactivity timeout is done below using mTrigger and mElapsed. + XScreenSaverQueryInfo(d, DefaultRootWindow(d), mMitInfo); + if (mLastIdle < mMitInfo->idle) + mLastIdle = mMitInfo->idle; + else + resetTrigger(); + } +#endif /* HAVE_XSCREENSAVER */ - xautolock_queryIdleTime( QX11Info::display()); + // This needs to be after the above check, so it overrides it. xautolock_queryPointer( QX11Info::display()); - if( !xautolock_useMit ) - XSetErrorHandler(oldHandler); - bool activate = false; - // kDebug() << now << mTrigger; + // This is the test whether to activate screensaver. If we have reached the time + // and for the whole timeout period there was no activity (which would change mTrigger + // again), activate. if (mElapsed >= mTrigger) - { - resetTrigger(); activate = true; - } #ifdef HAVE_DPMS BOOL on; CARD16 state; + CARD16 timeout1, timeout2, timeout3; DPMSInfo( QX11Info::display(), &state, &on ); + DPMSGetTimeouts( QX11Info::display(), &timeout1, &timeout2, &timeout3 ); // kDebug() << "DPMSInfo " << state << on; // If DPMS is active, it makes XScreenSaverQueryInfo() report idle time // that is always smaller than DPMS timeout (X bug I guess). So if DPMS // saving is active, simply always activate our saving too, otherwise // this could prevent locking from working. + // X.Org 7.4: With this version activating DPMS resets the screensaver idle timer, + // so keep this. It probably makes sense to always do this anyway. if(state == DPMSModeStandby || state == DPMSModeSuspend || state == DPMSModeOff) activate = true; - if(!on && mDPMS) { + // If we are DPMS-dependent and either DPMS is turned off completely or all + // three DPMS modes are turned off, don't activate (apps use this to turn off + // screensavers). + if(mDPMS && (!on || (timeout1 == 0 && timeout2 == 0 && timeout3 == 0 ))) { activate = false; resetTrigger(); } #endif -#ifdef HAVE_XSCREENSAVER - static XScreenSaverInfo* mitInfo = 0; - if (!mitInfo) mitInfo = XScreenSaverAllocInfo (); - if (XScreenSaverQueryInfo (QX11Info::display(), QX11Info::appRootWindow(), mitInfo)) { - // kDebug() << "XScreenSaverQueryInfo " << mitInfo->state << ScreenSaverDisabled; - if (mitInfo->state == ScreenSaverDisabled) - activate = false; - } -#endif + // Do not check whether internal X screensaver is enabled or disabled, since we + // have disabled it ourselves. Some apps might try to disable it too to prevent + // screensavers, but then our logic breaks[*]. Those apps need to disable DPMS anyway, + // or they will still have problems, so the DPMS code above should be enough. + // Besides, I doubt other screensaver implementations check this either. + // [*] We can't run with X screensaver enabled, since then sooner or later + // the internal screensaver will activate instead of our screensaver and we cannot + // prevent its activation by resetting the idle counter since that would also + // reset DPMS saving. if(mActive && activate) emit timeout(); @@ -249,7 +272,9 @@ bool XAutoLock::x11Event( XEvent* ev ) xautolock_processEvent( ev ); // don't futher process key events that were received only because XAutoLock wants them if( ev->type == KeyPress && !ev->xkey.send_event - && !xautolock_useMit +#ifdef HAVE_XSCREENSAVER + && !mMitInfo +#endif && !QWidget::find( ev->xkey.window )) return true; return false; @@ -265,10 +290,8 @@ bool XAutoLock::ignoreWindow( WId w ) time_t XAutoLock::idleTime() { #ifdef HAVE_XSCREENSAVER - static XScreenSaverInfo* mitInfo = 0; - if (!mitInfo) mitInfo = XScreenSaverAllocInfo (); - if (XScreenSaverQueryInfo (QX11Info::display(), QX11Info::appRootWindow(), mitInfo)) - return mitInfo->idle / 1000; + if (mMitInfo) + return mMitInfo->idle / 1000; #endif return mElapsed - mLastReset; } diff -u -p -N -r krunner/xautolock_engine.c krunner/xautolock_engine.c --- krunner/xautolock_engine.c 2009-01-27 16:47:51.000000000 +0100 +++ krunner/xautolock_engine.c 2009-01-27 16:48:02.000000000 +0100 @@ -20,30 +20,6 @@ #include "xautolock_c.h" /* - * Function for querying the idle time from the server. - * Only used if the Xscreensaver - * extension is present. - */ -void -xautolock_queryIdleTime (Display* d) -{ -#ifdef HAVE_XSCREENSAVER - if( xautolock_useMit ) - { - static XScreenSaverInfo* mitInfo = 0; - if (!mitInfo) mitInfo = XScreenSaverAllocInfo (); - XScreenSaverQueryInfo (d, DefaultRootWindow (d), mitInfo); - if (xautolock_lastIdleTime < mitInfo->idle) - xautolock_lastIdleTime = mitInfo->idle; - else - xautolock_resetTriggers (); - } -#else - (void)d; -#endif /* HAVE_XSCREENSAVER */ -} - -/* * Function for monitoring pointer movements. This implements the * `corners' feature and as a side effect also tracks pointer * related user activity. The latter actually is only needed when diff -u -p -N -r krunner/xautolock.h krunner/xautolock.h --- krunner/xautolock.h 2009-01-27 16:47:51.000000000 +0100 +++ krunner/xautolock.h 2009-01-27 16:48:01.000000000 +0100 @@ -8,10 +8,16 @@ #ifndef __XAUTOLOCK_H__ #define __XAUTOLOCK_H__ +#include <config-xautolock.h> + #include <QWidget> #include <X11/Xlib.h> +#ifdef HAVE_XSCREENSAVER +# include <X11/extensions/scrnsaver.h> +#endif #include <fixx11h.h> + //=========================================================================== // // Detect user inactivity. @@ -76,6 +82,10 @@ protected: time_t mLastReset; time_t mElapsed; bool mDPMS; +#ifdef HAVE_XSCREENSAVER + XScreenSaverInfo *mMitInfo; + ulong mLastIdle; +#endif }; #endif Index: krunner/lock/lockprocess.cc =================================================================== --- krunner/lock/lockprocess.cc (revision 916960) +++ krunner/lock/lockprocess.cc (revision 916966) @@ -1103,7 +1103,6 @@ return; // no resuming with dialog visible or when not visible if( mSuspended && mHackProc.state() == QProcess::Running ) { - XForceScreenSaver(QX11Info::display(), ScreenSaverReset ); QPainter p( this ); p.drawPixmap( 0, 0, mSavedScreen ); p.end();
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor