[hamster-applet] fixed idle detection so that it works with gnome-screensaver 2.27. Patch by Rex with a temporal hack
- From: Toms Baugis <tbaugis src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [hamster-applet] fixed idle detection so that it works with gnome-screensaver 2.27. Patch by Rex with a temporal hack
- Date: Wed, 29 Jul 2009 14:06:35 +0000 (UTC)
commit 02ff88f4b874c9b83ca71ae0cc5a9be75a9e1ecb
Author: Rex Tsai <chihchun kalug linux org tw>
Date: Wed Jul 29 17:06:14 2009 +0300
fixed idle detection so that it works with gnome-screensaver 2.27. Patch by Rex with a temporal hack by me. fixes bug 589835
hamster/applet.py | 50 ++++++++------------
hamster/idle.py | 131 +++++++++++++++++++++++++++++------------------------
2 files changed, 92 insertions(+), 89 deletions(-)
---
diff --git a/hamster/applet.py b/hamster/applet.py
index 0816f44..71c48cc 100755
--- a/hamster/applet.py
+++ b/hamster/applet.py
@@ -244,13 +244,9 @@ class HamsterApplet(object):
self.dbusController = HamsterDbusController(bus_name = name)
# Set up connection to the screensaver
- self.dbusIdleListener = idle.DbusIdleListener()
+ self.dbusIdleListener = idle.DbusIdleListener(runtime.dispatcher)
+ runtime.dispatcher.add_handler('active_changed', self.on_idle_changed)
- # let's also attach our listeners here
- bus = dbus.SessionBus()
- bus.add_signal_receiver(self.on_idle_changed,
- dbus_interface="org.gnome.ScreenSaver",
- signal_name="SessionIdleChanged")
except dbus.DBusException, e:
print "can't init dbus: %s" % e
@@ -473,25 +469,11 @@ class HamsterApplet(object):
"""UI functions"""
def refresh_hamster(self):
"""refresh hamster every x secs - load today, check last activity etc."""
- # stop tracking task if computer is idle for X minutes
- if self.timeout_enabled and self.last_activity and \
- self.last_activity['end_time'] is None:
- 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 = dt.datetime.now()
- idle_from = current_time - dt.timedelta(minutes = idle_minutes)
- runtime.storage.touch_fact(self.last_activity, end_time = idle_from)
-
- # if we have date change - let's finish previous task and start a new one
- if self.button.get_active(): # otherwise if we the day view is visible - update day's durations
- self.load_day()
-
+ #if we the day view is visible - update day's durations
+ if self.button.get_active():
+ self.load_day()
+
self.update_label()
self.check_user()
return True
@@ -666,12 +648,6 @@ class HamsterApplet(object):
"""events"""
- def on_idle_changed(self, state):
- print "Idle state changed. Idle: ", state
- # refresh when we are out of idle
- # (like, instantly after computer has been turned on!
- if state == 0:
- self.refresh_hamster()
def on_today_release_event(self, tree, event):
# a hackish solution to make edit icon keyboard accessible
@@ -814,6 +790,20 @@ class HamsterApplet(object):
self.update_label()
self.__update_fact()
+ def on_idle_changed(self, event, state):
+ # state values: 0 = active, 1 = idle
+
+ # refresh when we are out of idle
+ # (like, instantly after computer has been turned on!
+ if state == 0:
+ self.refresh_hamster()
+ elif self.timeout_enabled and self.last_activity and \
+ self.last_activity['end_time'] is None:
+
+ runtime.storage.touch_fact(self.last_activity,
+ end_time = self.dbusIdleListener.getIdleFrom())
+
+
"""global shortcuts"""
def on_keybinding_activated(self, event, data):
self.__show_toggle(None, not self.button.get_active())
diff --git a/hamster/idle.py b/hamster/idle.py
index 06313bc..cc8a4d0 100644
--- a/hamster/idle.py
+++ b/hamster/idle.py
@@ -20,44 +20,31 @@
import dbus
from dbus.lowlevel import Message
import gconf
-
-def getIdleSec():
- try:
- bus = dbus.SessionBus()
- gs = bus.get_object('org.gnome.ScreenSaver', '/org/gnome/ScreenSaver')
- idle_time = gs.GetSessionIdleTime()
- except:
- return 0
-
- if idle_time > 0:
- # if we are in idle - grab gconf setting how much is considered idle
- client = gconf.client_get_default()
- idle_delay = client.get_int("/apps/gnome-screensaver/idle_delay")
- idle_time += idle_delay * 60 #delay is in minutes
-
- return idle_time
-
+import datetime as dt
+import gobject
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.
+ Monitors org.gnome.ScreenSaver for idleness. There are two types,
+ 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"
+ The signals are inspected for the "ActiveChanged" and "Lock"
members coming from the org.gnome.ScreenSaver interface and the
- is_idle, and is_screen_locked members are updated appropriately.
+ and is_screen_locked members are updated appropriately.
"""
- def __init__(self):
+ def __init__(self, dispatcher):
self.screensaver_uri = "org.gnome.ScreenSaver"
- self.is_idle = False
- self.is_screen_locked = False
+ self.dispatcher = dispatcher
+ self.screen_locked = False
+ self.idle_from = None
+ self.timeout_minutes = 0 # minutes after session is considered idle
+ self.idle_was_there = False # a workaround variable for pre 2.26
try:
self.bus = dbus.SessionBus()
@@ -72,55 +59,81 @@ class DbusIdleListener(object):
# 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_match_string_non_blocking("interface='%s'" %
+ 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
+
+ # We only care about stuff on this interface. We did filter
# for it above, but even so we still hear from ourselves
# (hamster messages).
- if not message.get_interface() == self.screensaver_uri:
+ if message.get_interface() != self.screensaver_uri:
return True
- # 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:
+ member = message.get_member()
+
+ if member in ("SessionIdleChanged", "ActiveChanged"):
if __debug__:
- print "SessionIdleChanged ->", message.get_args_list()
+ print "%s ->" % member, message.get_args_list()
+
idle_state = message.get_args_list()[0]
if idle_state:
- self.is_idle = True
+ self.idle_from = dt.datetime.now()
+
+ # from gnome screensaver 2.24 to 2.28 they have switched
+ # configuration keys and signal types.
+ # luckily we can determine key by signal type
+ if member == "SessionIdleChanged":
+ delay_key = "/apps/gnome-screensaver/idle_delay"
+ else:
+ delay_key = "/desktop/gnome/session/idle_delay"
+
+ client = gconf.client_get_default()
+ self.timeout_minutes = client.get_int(delay_key)
+
else:
- self.is_idle = False
- self.is_screen_locked = False
- elif message.get_member() == "Lock" and \
- message.get_type() == 1:
+ self.screen_locked = False
+ self.idle_from = None
+
+ if member == "ActiveChanged":
+ # ActiveChanged comes before SessionIdleChanged signal
+ # as a workaround for pre 2.26, we will wait a second - maybe
+ # SessionIdleChanged signal kicks in
+ def dispatch_active_changed(idle_state):
+ if not self.idle_was_there:
+ self.dispatcher.dispatch('active_changed', idle_state)
+ self.idle_was_there = False
+
+ gobject.timeout_add_seconds(1, dispatch_active_changed, idle_state)
+
+ else:
+ # dispatch idle status change to interested parties
+ self.idle_was_there = True
+ self.dispatcher.dispatch('active_changed', idle_state)
+
+ elif member == "Lock":
+ # in case of lock, lock signal will be sent first, followed by
+ # ActiveChanged and SessionIdle signals
if __debug__:
print "Screen Lock Requested"
- self.is_screen_locked = True
+ self.screen_locked = True
return True
+
+
+ def getIdleFrom(self):
+ if not self.idle_from:
+ return dt.datetime.now()
+ if self.screen_locked:
+ return self.idle_from
+ else:
+ # Only subtract idle time from the running task when
+ # idleness is due to time out, not a screen lock.
+ return self.idle_from - dt.timedelta(minutes = self.timeout_minutes)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]