From 8ee69e536d3050dec03f19b8658d47b792f2f918 Mon Sep 17 00:00:00 2001 From: Aurelien Naldi Date: Thu, 8 Oct 2015 22:11:08 +0200 Subject: [PATCH 1/4] Add a save/restore mechanism and use it to resume the last activity on screen unlock --- src/hamster/lib/desktop.py | 47 +++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/hamster/lib/desktop.py b/src/hamster/lib/desktop.py index f60905a42..181abe78d 100644 --- a/src/hamster/lib/desktop.py +++ b/src/hamster/lib/desktop.py @@ -33,6 +33,7 @@ class DesktopIntegrations(object): def __init__(self, storage): self.storage = storage # can't use client as then we get in a dbus loop self._last_notification = None + self._saved = {} dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) self.bus = dbus.SessionBus() @@ -108,13 +109,57 @@ def notify_user(self, summary="", details=""): def on_idle_changed(self, event, state): + if not self.conf_enable_timeout: + if '__paused__' in self._saved: + del self._saved['__paused__'] + return + # state values: 0 = active, 1 = idle - if state == 1 and self.conf_enable_timeout: + if state == 1: idle_from = self.idle_listener.getIdleFrom() idle_from = timegm(idle_from.timetuple()) + self.save_current('__paused__') self.storage.StopTracking(idle_from) + elif '__paused__' in self._saved: + self.restore('__paused__', delete=True) def on_conf_changed(self, event, key, value): if hasattr(self, "conf_%s" % key): setattr(self, "conf_%s" % key, value) + + + def get_current(self): + facts = self.storage.get_todays_facts() + if facts: + last = facts[-1] + if not last['end_time']: + name = last['name'] + category = last['category'] + return name,category + + + def save_current(self, key): + current = self.get_current() + if current: + self._saved[key] = current + elif key in self._saved: + del self._saved[key] + + + def restore(self, key, delete=False): + activity,category = None,None + if key in self._saved: + activity, category = self._saved[key] + if delete: + del self._saved[key] + + if not activity: + self.storage.StopTracking(None) + return + + if category: + activity = '%s@%s' % (activity,category) + + self.storage.add_fact( activity, None, None) + From 667cbacf1c9c0c10c48bbd4daa7e663aacf8de67 Mon Sep 17 00:00:00 2001 From: Aurelien Naldi Date: Thu, 8 Oct 2015 22:33:07 +0200 Subject: [PATCH 2/4] Follow workspace changes --- src/hamster/lib/desktop.py | 16 +++++++++++- src/hamster/workspace.py | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/hamster/workspace.py diff --git a/src/hamster/lib/desktop.py b/src/hamster/lib/desktop.py index 181abe78d..6754bc854 100644 --- a/src/hamster/lib/desktop.py +++ b/src/hamster/lib/desktop.py @@ -24,6 +24,7 @@ from hamster import idle +from hamster import workspace from hamster.lib.configuration import conf from hamster.lib import trophies import dbus @@ -48,6 +49,10 @@ def __init__(self, storage): gobject.timeout_add_seconds(60, self.check_hamster) + self.use_workspace_changes = True # TODO: should be a proper setting + self.workspace_listener = workspace.WnckWatcher() + self.workspace_listener.connect('workspace-changed', self.on_workspace_changed) + def check_hamster(self): """refresh hamster every x secs - load today, check last activity etc.""" @@ -124,6 +129,15 @@ def on_idle_changed(self, event, state): self.restore('__paused__', delete=True) + def on_workspace_changed(self, event, previous_workspace, current_workspace): + if not self.use_workspace_changes: + return + + if previous_workspace is not None: + self.save_current( previous_workspace ) + self.restore(current_workspace) + + def on_conf_changed(self, event, key, value): if hasattr(self, "conf_%s" % key): setattr(self, "conf_%s" % key, value) @@ -141,7 +155,7 @@ def get_current(self): def save_current(self, key): current = self.get_current() - if current: + if current is not None: self._saved[key] = current elif key in self._saved: del self._saved[key] diff --git a/src/hamster/workspace.py b/src/hamster/workspace.py new file mode 100644 index 000000000..0a6a50a3b --- /dev/null +++ b/src/hamster/workspace.py @@ -0,0 +1,51 @@ +# - coding: utf-8 - + +# Copyright (C) 2015 Aurelien Naldi + +# This file is part of Project Hamster. + +# Project Hamster is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# Project Hamster is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with Project Hamster. If not, see . + +from gi.repository import GObject as gobject +from gi.repository import Wnck as wnck +import dbus + +class WnckWatcher(gobject.GObject): + """ + Listen for workspace changes with Wnck and forward them to the desktop integration agent. + It handles all wnck-specific parts and forwards standardised signals, based on the screensaver helper. + """ + __gsignals__ = { + "workspace-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,gobject.TYPE_PYOBJECT)) + } + def __init__(self): + gobject.GObject.__init__(self) + + try: + self.bus = dbus.SessionBus() + except: + return 0 + wnck.Screen.get_default().connect("active-workspace-changed", self.on_workspace_changed) + + + def on_workspace_changed(self, screen, previous_workspace): + try: + workspace_id = screen.get_active_workspace().get_number() + if previous_workspace: + previous_workspace = previous_workspace.get_number() + except: + return + + self.emit('workspace-changed', previous_workspace, workspace_id) + From d4ec95de4c6290aadce7b39a3861650b4975fb1c Mon Sep 17 00:00:00 2001 From: Aurelien Naldi Date: Fri, 9 Oct 2015 10:17:08 +0200 Subject: [PATCH 3/4] Remove unwanted try/catch --- src/hamster/idle.py | 5 +---- src/hamster/workspace.py | 14 ++++---------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/hamster/idle.py b/src/hamster/idle.py index 92d00d4c8..b71616ad5 100644 --- a/src/hamster/idle.py +++ b/src/hamster/idle.py @@ -54,10 +54,7 @@ def __init__(self): 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() - except: - return 0 + self.bus = dbus.SessionBus() # 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. diff --git a/src/hamster/workspace.py b/src/hamster/workspace.py index 0a6a50a3b..a5aeb93f2 100644 --- a/src/hamster/workspace.py +++ b/src/hamster/workspace.py @@ -32,20 +32,14 @@ class WnckWatcher(gobject.GObject): def __init__(self): gobject.GObject.__init__(self) - try: - self.bus = dbus.SessionBus() - except: - return 0 + self.bus = dbus.SessionBus() wnck.Screen.get_default().connect("active-workspace-changed", self.on_workspace_changed) def on_workspace_changed(self, screen, previous_workspace): - try: - workspace_id = screen.get_active_workspace().get_number() - if previous_workspace: - previous_workspace = previous_workspace.get_number() - except: - return + workspace_id = screen.get_active_workspace().get_number() + if previous_workspace: + previous_workspace = previous_workspace.get_number() self.emit('workspace-changed', previous_workspace, workspace_id) From 68e51605d9773e69d8e83874a0d36ea364c949f5 Mon Sep 17 00:00:00 2001 From: Aurelien Naldi Date: Fri, 9 Oct 2015 11:08:19 +0200 Subject: [PATCH 4/4] Use the existing gconf setting to toggle workspace tracking --- src/hamster/lib/configuration.py | 1 + src/hamster/lib/desktop.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hamster/lib/configuration.py b/src/hamster/lib/configuration.py index e3630878b..b2c62c814 100644 --- a/src/hamster/lib/configuration.py +++ b/src/hamster/lib/configuration.py @@ -200,6 +200,7 @@ class GConfStore(gobject.GObject, Singleton): DEFAULTS = { 'enable_timeout' : False, # Should hamster stop tracking on idle 'stop_on_shutdown' : False, # Should hamster stop tracking on shutdown + 'workspace_tracking' : [], # Should hamster track workspace changes 'notify_on_idle' : False, # Remind also if no activity is set 'notify_interval' : 27, # Remind of current activity every X minutes 'day_start_minutes' : 5 * 60 + 30, # At what time does the day start (5:30AM) diff --git a/src/hamster/lib/desktop.py b/src/hamster/lib/desktop.py index 6754bc854..10da7d1ec 100644 --- a/src/hamster/lib/desktop.py +++ b/src/hamster/lib/desktop.py @@ -42,6 +42,7 @@ def __init__(self, storage): self.conf_enable_timeout = conf.get("enable_timeout") self.conf_notify_on_idle = conf.get("notify_on_idle") self.conf_notify_interval = conf.get("notify_interval") + self.conf_workspace_tracking = conf.get("workspace_tracking") conf.connect('conf-changed', self.on_conf_changed) self.idle_listener = idle.DbusIdleListener() @@ -49,7 +50,6 @@ def __init__(self, storage): gobject.timeout_add_seconds(60, self.check_hamster) - self.use_workspace_changes = True # TODO: should be a proper setting self.workspace_listener = workspace.WnckWatcher() self.workspace_listener.connect('workspace-changed', self.on_workspace_changed) @@ -130,7 +130,7 @@ def on_idle_changed(self, event, state): def on_workspace_changed(self, event, previous_workspace, current_workspace): - if not self.use_workspace_changes: + if 'memory' not in self.conf_workspace_tracking: return if previous_workspace is not None: