Summary: | Can never be idle if compiled without libxss | ||
---|---|---|---|
Product: | [Unmaintained] kopete | Reporter: | Isaac Wilcox <iwilcox> |
Component: | libkopete | Assignee: | Kopete Developers <kopete-bugs-null> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Compiled Sources | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Isaac Wilcox
2006-01-29 18:23:03 UTC
SVN commit 511207 by mattr: Apply the patch from bug 117513 to fix several auto away issues with the code that does this. Patch by Issac Wilcox. Thanks so much for the patch! BUG: 120989 BUG: 92949 BUG: 117513 M +3 -0 kopete/kopeteiface.cpp M +74 -15 libkopete/kopeteaway.cpp M +11 -3 libkopete/kopeteaway.h --- branches/kopete/0.12/kopete/kopete/kopeteiface.cpp #511206:511207 @@ -48,6 +48,9 @@ disconnectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "setAutoAway()"); } + // FIXME: AFAICT, this never seems to fire. + connectDCOPSignal("kdesktop", "KScreensaverIface", + "KDE_stop_screensaver()", "setActive()", false); } QStringList KopeteIface::contacts() --- branches/kopete/0.12/kopete/libkopete/kopeteaway.cpp #511206:511207 @@ -32,6 +32,7 @@ #include <kconfig.h> #include <qtimer.h> #include <kapplication.h> +#include <dcopref.h> #include <klocale.h> #include <kglobal.h> @@ -122,10 +123,19 @@ #ifdef Q_WS_X11 d->xIdleTime = 0; #endif + kdDebug(14010) << k_funcinfo << "Idle detection methods:" << endl; + kdDebug(14010) << k_funcinfo << "\tKScreensaverIface::isBlanked()" << endl; +#ifdef Q_WS_X11 + kdDebug(14010) << k_funcinfo << "\tX11 XQueryPointer()" << endl; +#endif if (d->useXidle) - kdDebug(14010) << "using X11 Xidle extension" << endl; - if(d->useMit) - kdDebug(14010) << "using X11 MIT Screensaver extension" << endl; + { + kdDebug(14010) << k_funcinfo << "\tX11 Xidle extension" << endl; + } + if (d->useMit) + { + kdDebug(14010) << k_funcinfo << "\tX11 MIT Screensaver extension" << endl; + } load(); @@ -165,7 +175,7 @@ d->timer->start(4000); //init the time and other - setActivity(); + setActive(); } Kopete::Away::~Away() @@ -264,6 +274,42 @@ void Kopete::Away::slotTimerTimeout() { + // Time to check whether we're active or autoaway. We basically have two + // bits of info to go on - KDE's screensaver status + // (KScreenSaverIface::isBlanked()) and the X11 activity detection. + // + // Note that isBlanked() is a slight of a misnomer. It returns true if we're: + // - using a non-locking screensaver, which is running, or + // - using a locking screensaver which is still locked, regardless of + // whether the user is trying to unlock it right now + // Either way, it's only worth checking for activity if the screensaver + // isn't blanked/locked, because activity while blanked is impossible and + // activity while locked never matters (if there is any, it's probably just + // the cleaner wiping the keyboard :). + + DCOPRef screenSaver("kdesktop", "KScreensaverIface"); + DCOPReply isBlanked = screenSaver.call("isBlanked"); + if (!(isBlanked.isValid() && isBlanked.type == "bool" && ((bool)isBlanked))) + { + // DCOP failed, or returned something odd, or the screensaver is + // inactive, so check for activity the X11 way. It's only worth + // checking for autoaway if there's no activity, and because + // Screensaver blanking/locking implies autoAway activation (see + // KopeteIface::KopeteIface()), only worth checking autoAway when the + // screensaver isn't running. + if (isActivity()) + { + setActive(); + } + else if (!d->autoaway && d->useAutoAway && idleTime() > d->awayTimeout) + { + setAutoAway(); + } + } +} + +bool Kopete::Away::isActivity() +{ // Copyright (c) 1999 Martin R. Jones <mjones@kde.org> // // KDE screensaver engine @@ -271,6 +317,8 @@ // This module is a heavily modified xautolock. // In fact as of KDE 2.0 this code is practically unrecognisable as xautolock. + bool activity = false; + #ifdef Q_WS_X11 Display *dsp = qt_xdisplay(); Window dummy_w; @@ -305,9 +353,9 @@ } } } -#endif + // ================================================================================= -#ifdef Q_WS_X11 + Time xIdleTime = 0; // millisecs since last input event #ifdef HasXidle @@ -332,10 +380,19 @@ // ================================================================================= - if (root_x != d->mouse_x || root_y != d->mouse_y || mask != d->mouse_mask || xIdleTime < d->xIdleTime+2000) + // Only check idle time if we have some way of measuring it, otherwise if + // we've neither Mit nor Xidle it'll still be zero and we'll always appear active. + // FIXME: what problem does the 2000ms fudge solve? + if (root_x != d->mouse_x || root_y != d->mouse_y || mask != d->mouse_mask + || ((d->useXidle || d->useMit) && xIdleTime < d->xIdleTime + 2000)) { - if(d->mouse_x!=-1) //we just gone autoaway, not activity this time - setActivity(); + // -1 => just gone autoaway, ignore apparent activity this time round + // anything else => genuine activity + // See setAutoAway(). + if (d->mouse_x != -1) + { + activity = true; + } d->mouse_x = root_x; d->mouse_y = root_y; d->mouse_mask = mask; @@ -344,13 +401,10 @@ #endif // Q_WS_X11 // ================================================================================= - if(!d->autoaway && d->useAutoAway && idleTime() > d->awayTimeout) - { - setAutoAway(); - } + return activity; } -void Kopete::Away::setActivity() +void Kopete::Away::setActive() { // kdDebug(14010) << k_funcinfo << "Found activity on desktop, resetting away timer" << endl; d->idleTime.start(); @@ -381,7 +435,12 @@ void Kopete::Away::setAutoAway() { - d->mouse_x=-1; //do not go availiable automaticaly after + // A value of -1 in mouse_x indicates to checkActivity() that next time it + // fires it should ignore any apparent idle/mouse/keyboard changes. + // I think the point of this is that if you manually start the screensaver + // then there'll unavoidably be some residual mouse/keyboard activity + // that should be ignored. + d->mouse_x = -1; // kdDebug(14010) << k_funcinfo << "Going AutoAway!" << endl; d->autoaway = true; --- branches/kopete/0.12/kopete/libkopete/kopeteaway.h #511206:511207 @@ -139,6 +139,14 @@ */ void save(); + /** + * @brief Check for activity using X11 methods + * @return true if activity was detected, otherwise false + * + * Attempt to detect activity using a variety of X11 methods. + */ + bool isActivity(); + //Away( const Away &rhs ); //Away &operator=( const Away &rhs ); static Away *instance; @@ -150,14 +158,14 @@ public slots: /** - * @brief Set the activity + * @brief Mark the user active * - * Plugins can set the activity if they discover activity by another way than the mouse or the keyboard + * Plugins can mark the user active if they discover activity by another way than the mouse or the keyboard * (example, the motion auto away plugin) * this will reset the @ref idleTime to 0, and set all protocols to available (online) if the state was * set automatically to away because of idleness, and if they was previously online */ - void setActivity(); + void setActive(); /** * Use this method if you want to go in the autoaway mode. SVN commit 511336 by mattr: backport patches for bugs 120989, 92949, and 117513 Should be in KDE 3.5.2 and the upcoming 0.12 release. CCBUG: 120989, 92949, 117513 M +3 -0 kopete/kopeteiface.cpp M +74 -15 libkopete/kopeteaway.cpp M +11 -3 libkopete/kopeteaway.h --- branches/KDE/3.5/kdenetwork/kopete/kopete/kopeteiface.cpp #511335:511336 @@ -48,6 +48,9 @@ disconnectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "setAutoAway()"); } + // FIXME: AFAICT, this never seems to fire. + connectDCOPSignal("kdesktop", "KScreensaverIface", + "KDE_stop_screensaver()", "setActive()", false); } QStringList KopeteIface::contacts() --- branches/KDE/3.5/kdenetwork/kopete/libkopete/kopeteaway.cpp #511335:511336 @@ -32,6 +32,7 @@ #include <kconfig.h> #include <qtimer.h> #include <kapplication.h> +#include <dcopref.h> #include <klocale.h> #include <kglobal.h> @@ -122,10 +123,19 @@ #ifdef Q_WS_X11 d->xIdleTime = 0; #endif + kdDebug(14010) << k_funcinfo << "Idle detection methods:" << endl; + kdDebug(14010) << k_funcinfo << "\tKScreensaverIface::isBlanked()" << endl; +#ifdef Q_WS_X11 + kdDebug(14010) << k_funcinfo << "\tX11 XQueryPointer()" << endl; +#endif if (d->useXidle) - kdDebug(14010) << "using X11 Xidle extension" << endl; - if(d->useMit) - kdDebug(14010) << "using X11 MIT Screensaver extension" << endl; + { + kdDebug(14010) << k_funcinfo << "\tX11 Xidle extension" << endl; + } + if (d->useMit) + { + kdDebug(14010) << k_funcinfo << "\tX11 MIT Screensaver extension" << endl; + } load(); @@ -165,7 +175,7 @@ d->timer->start(4000); //init the time and other - setActivity(); + setActive(); } Kopete::Away::~Away() @@ -264,6 +274,42 @@ void Kopete::Away::slotTimerTimeout() { + // Time to check whether we're active or autoaway. We basically have two + // bits of info to go on - KDE's screensaver status + // (KScreenSaverIface::isBlanked()) and the X11 activity detection. + // + // Note that isBlanked() is a slight of a misnomer. It returns true if we're: + // - using a non-locking screensaver, which is running, or + // - using a locking screensaver which is still locked, regardless of + // whether the user is trying to unlock it right now + // Either way, it's only worth checking for activity if the screensaver + // isn't blanked/locked, because activity while blanked is impossible and + // activity while locked never matters (if there is any, it's probably just + // the cleaner wiping the keyboard :). + + DCOPRef screenSaver("kdesktop", "KScreensaverIface"); + DCOPReply isBlanked = screenSaver.call("isBlanked"); + if (!(isBlanked.isValid() && isBlanked.type == "bool" && ((bool)isBlanked))) + { + // DCOP failed, or returned something odd, or the screensaver is + // inactive, so check for activity the X11 way. It's only worth + // checking for autoaway if there's no activity, and because + // Screensaver blanking/locking implies autoAway activation (see + // KopeteIface::KopeteIface()), only worth checking autoAway when the + // screensaver isn't running. + if (isActivity()) + { + setActive(); + } + else if (!d->autoaway && d->useAutoAway && idleTime() > d->awayTimeout) + { + setAutoAway(); + } + } +} + +bool Kopete::Away::isActivity() +{ // Copyright (c) 1999 Martin R. Jones <mjones@kde.org> // // KDE screensaver engine @@ -271,6 +317,8 @@ // This module is a heavily modified xautolock. // In fact as of KDE 2.0 this code is practically unrecognisable as xautolock. + bool activity = false; + #ifdef Q_WS_X11 Display *dsp = qt_xdisplay(); Window dummy_w; @@ -305,9 +353,9 @@ } } } -#endif + // ================================================================================= -#ifdef Q_WS_X11 + Time xIdleTime = 0; // millisecs since last input event #ifdef HasXidle @@ -332,10 +380,19 @@ // ================================================================================= - if (root_x != d->mouse_x || root_y != d->mouse_y || mask != d->mouse_mask || xIdleTime < d->xIdleTime+2000) + // Only check idle time if we have some way of measuring it, otherwise if + // we've neither Mit nor Xidle it'll still be zero and we'll always appear active. + // FIXME: what problem does the 2000ms fudge solve? + if (root_x != d->mouse_x || root_y != d->mouse_y || mask != d->mouse_mask + || ((d->useXidle || d->useMit) && xIdleTime < d->xIdleTime + 2000)) { - if(d->mouse_x!=-1) //we just gone autoaway, not activity this time - setActivity(); + // -1 => just gone autoaway, ignore apparent activity this time round + // anything else => genuine activity + // See setAutoAway(). + if (d->mouse_x != -1) + { + activity = true; + } d->mouse_x = root_x; d->mouse_y = root_y; d->mouse_mask = mask; @@ -344,13 +401,10 @@ #endif // Q_WS_X11 // ================================================================================= - if(!d->autoaway && d->useAutoAway && idleTime() > d->awayTimeout) - { - setAutoAway(); - } + return activity; } -void Kopete::Away::setActivity() +void Kopete::Away::setActive() { // kdDebug(14010) << k_funcinfo << "Found activity on desktop, resetting away timer" << endl; d->idleTime.start(); @@ -381,7 +435,12 @@ void Kopete::Away::setAutoAway() { - d->mouse_x=-1; //do not go availiable automaticaly after + // A value of -1 in mouse_x indicates to checkActivity() that next time it + // fires it should ignore any apparent idle/mouse/keyboard changes. + // I think the point of this is that if you manually start the screensaver + // then there'll unavoidably be some residual mouse/keyboard activity + // that should be ignored. + d->mouse_x = -1; // kdDebug(14010) << k_funcinfo << "Going AutoAway!" << endl; d->autoaway = true; --- branches/KDE/3.5/kdenetwork/kopete/libkopete/kopeteaway.h #511335:511336 @@ -139,6 +139,14 @@ */ void save(); + /** + * @brief Check for activity using X11 methods + * @return true if activity was detected, otherwise false + * + * Attempt to detect activity using a variety of X11 methods. + */ + bool isActivity(); + //Away( const Away &rhs ); //Away &operator=( const Away &rhs ); static Away *instance; @@ -150,14 +158,14 @@ public slots: /** - * @brief Set the activity + * @brief Mark the user active * - * Plugins can set the activity if they discover activity by another way than the mouse or the keyboard + * Plugins can mark the user active if they discover activity by another way than the mouse or the keyboard * (example, the motion auto away plugin) * this will reset the @ref idleTime to 0, and set all protocols to available (online) if the state was * set automatically to away because of idleness, and if they was previously online */ - void setActivity(); + void setActive(); /** * Use this method if you want to go in the autoaway mode. |