hamster-applet r826 - trunk/hamster
- From: tbaugis svn gnome org
- To: svn-commits-list gnome org
- Subject: hamster-applet r826 - trunk/hamster
- Date: Mon, 2 Mar 2009 10:06:37 +0000 (UTC)
Author: tbaugis
Date: Mon Mar 2 10:06:37 2009
New Revision: 826
URL: http://svn.gnome.org/viewvc/hamster-applet?rev=826&view=rev
Log:
respect session lock and do not stop timer
(sometimes locking computer is not the same as
stopping working on a task)
Patch by Uri Okrent
Fixes bug 561454
Modified:
trunk/hamster/applet.py
trunk/hamster/idle.py
Modified: trunk/hamster/applet.py
==============================================================================
--- trunk/hamster/applet.py (original)
+++ trunk/hamster/applet.py Mon Mar 2 10:06:37 2009
@@ -210,6 +210,9 @@
name = dbus.service.BusName(HAMSTER_URI, dbus.SessionBus())
self.dbusController = HamsterDbusController(bus_name = name)
+ # Set up connection to the screensaver
+ self.dbusIdleListener = idle.DbusIdleListener()
+
# let's also attach our listeners here
bus = dbus.SessionBus()
bus.add_signal_receiver(self.on_idle_changed,
@@ -375,8 +378,13 @@
# stop tracking task if computer is idle for X minutes
if self.timeout_enabled and self.last_activity and \
self.last_activity['end_time'] == None:
- idle_minutes = idle.getIdleSec() / 60.0
- if idle_minutes > 0:
+ if self.dbusIdleListener.is_idle:
+ # Only subtract idle time from the running task when
+ # idleness is due to time out, not a screen lock.
+ if self.dbusIdleListener.is_screen_locked:
+ idle_minutes = 0
+ else:
+ idle_minutes = idle.getIdleSec() / 60.0
current_time = datetime.datetime.now()
idle_from = current_time - datetime.timedelta(minutes = idle_minutes)
storage.touch_fact(self.last_activity, end_time = idle_from)
Modified: trunk/hamster/idle.py
==============================================================================
--- trunk/hamster/idle.py (original)
+++ trunk/hamster/idle.py Mon Mar 2 10:06:37 2009
@@ -18,10 +18,9 @@
# along with Project Hamster. If not, see <http://www.gnu.org/licenses/>.
import dbus
+from dbus.lowlevel import Message
import gconf
-# TODO - since we don't allow to specify idle minutes, we should just listen
-# to the SessionIdleChanged signal from org.gnome.Screensaver
def getIdleSec():
try:
bus = dbus.SessionBus()
@@ -38,4 +37,88 @@
return idle_time
-
\ No newline at end of file
+
+class DbusIdleListener(object):
+ """
+ Listen for idleness coming from org.gnome.ScreenSaver
+
+ Monitors org.gnome.ScreenSaver for idleness. There are two types
+ (that I know of), implicit (due to inactivity) and explicit (lock
+ screen), that need to be handled differently. An implicit idle
+ state should subtract the time-to-become-idle (as specified in the
+ gconf) from the last activity, but an explicit idle state should
+ not.
+
+ The signals are inspected for the "SessionIdleChanged" and "Lock"
+ members coming from the org.gnome.ScreenSaver interface and the
+ is_idle, and is_screen_locked members are updated appropriately.
+ """
+ def __init__(self):
+ self.screensaver_uri = "org.gnome.ScreenSaver"
+
+ self.is_idle = False
+ self.is_screen_locked = False
+
+ try:
+ self.bus = dbus.SessionBus()
+ except:
+ return 0
+ # Listen for chatter on the screensaver interface.
+ # We cannot just add additional match strings to narrow down
+ # what we hear because match strings are ORed together.
+ # E.g., if we were to make the match string
+ # "interface='org.gnome.ScreenSaver', type='method_call'",
+ # we would not get only screensaver's method calls, rather
+ # we would get anything on the screensaver interface, as well
+ # as any method calls on *any* interface. Therefore the
+ # bus_inspector needs to do some additional filtering.
+ self.bus.add_match_string_non_blocking(
+ "interface='" + self.screensaver_uri + "'")
+
+ self.bus.add_message_filter(self.bus_inspector)
+
+
+ def bus_inspector(self, bus, message):
+ """
+ Inspect the bus for screensaver messages of interest
+
+ Namely, we are watching for messages on the screensaver
+ interface. If it's a signal type for SessionIdleChanged,
+ we set our internal is_idle state to that value (the signal
+ is a boolean). If its a method call with type "Lock" then
+ the user requested to lock the screen so we set our internal
+ lock state to true.
+
+ When the SessionIdleChanged signal is false, it means we are
+ returning from the locked/idle state, so both is_idle and
+ is_screen_locked are reset to False.
+ """
+ # We only care about stuff on this interface. Yes we did filter
+ # for it above, but even so we still hear from ourselves
+ # (hamster messages).
+ if not message.get_interface() == self.screensaver_uri:
+ return
+
+ # Signal type messages have a value of 4, and method_call type
+ # ones have a value of 1. I'm not sure how important it is to
+ # verify that SessionIdleChanged on the screensaver interface
+ # is actually a "signal" and not some other type of message
+ # but I'll make sure just to be safe. Same goes for the Lock
+ # member.
+ if message.get_member() == "SessionIdleChanged" and \
+ message.get_type() == 4:
+ if __debug__:
+ print "SessionIdleChanged ->", message.get_args_list()
+ idle_state = message.get_args_list()[0]
+ if idle_state:
+ self.is_idle = True
+ else:
+ self.is_idle = False
+ self.is_screen_locked = False
+ elif message.get_member() == "Lock" and \
+ message.get_type() == 1:
+ if __debug__:
+ print "Screen Lock Requested"
+ self.is_screen_locked = True
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]