[kupfer: 4/53] Correctly pass on and use timestamp through kupfer-exec



commit cef2a4c01b7ec91f1a623ad3ad465f13d871e2ef
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Thu Mar 24 17:22:32 2011 +0100

    Correctly pass on and use timestamp through kupfer-exec
    
    Get a UI timestamp with kupfer-exec and pass it on via D-Bus. Make
    kupfer.ui.uievents.current_event_time() the central place for the
    current event timestamp.

 auxdata/kupfer-exec.desktop.in |    1 +
 bin/kupfer-exec.in             |    9 +++++-
 kupfer/launch.py               |   31 ++++++---------------
 kupfer/plugin/windows.py       |    4 +-
 kupfer/ui/browser.py           |    6 ++--
 kupfer/ui/listen.py            |   26 +++++++++--------
 kupfer/ui/preferences.py       |    4 ++-
 kupfer/ui/uievents.py          |   58 ++++++++++++++++++++++++++++++++++++++++
 kupfer/uiutils.py              |    9 ++----
 9 files changed, 100 insertions(+), 48 deletions(-)
---
diff --git a/auxdata/kupfer-exec.desktop.in b/auxdata/kupfer-exec.desktop.in
index 72d208b..eb3ba90 100644
--- a/auxdata/kupfer-exec.desktop.in
+++ b/auxdata/kupfer-exec.desktop.in
@@ -6,4 +6,5 @@ Exec=kupfer-exec %F
 _Name=Execute in Kupfer
 Icon=kupfer
 NoDisplay=true
+StartupNotify=true
 MimeType=text/x-kfcom;
diff --git a/bin/kupfer-exec.in b/bin/kupfer-exec.in
index 134a69c..0717996 100755
--- a/bin/kupfer-exec.in
+++ b/bin/kupfer-exec.in
@@ -12,11 +12,16 @@ then
 	exit 1
 fi
 
+SERVICE="se.kaizer.kupfer"
+OBJ="/interface"
+IFACE="se.kaizer.kupfer.Listener"
+
 while test $# != 0
 do
 	FILE=$(readlink -f "$1")
-	dbus-send --print-reply --dest=se.kaizer.kupfer /interface \
-		se.kaizer.kupfer.Listener.ExecuteFile string:"$FILE" \
+	dbus-send --print-reply --dest=$SERVICE $OBJ \
+		$IFACE.ExecuteFileWithStartup string:"$FILE" \
+		string:"$DESKTOP_STARTUP_ID" \
 		> /dev/null 2>&1
 	KUPFER_RUNNING=$?
 
diff --git a/kupfer/launch.py b/kupfer/launch.py
index 82a90d1..3ad8550 100644
--- a/kupfer/launch.py
+++ b/kupfer/launch.py
@@ -8,11 +8,15 @@ import gobject
 from kupfer import pretty, config
 from kupfer import scheduler
 from kupfer import desktop_launch
-from kupfer.ui import keybindings
+from kupfer.ui import uievents
 from kupfer import terminal
 
+from kupfer.ui.uievents import make_startup_notification_id
 from kupfer.desktop_launch import SpawnError
 
+## NOTE: SpawnError and make_startup_notification_id
+## they *should* be imported from this module
+
 try:
 	import wnck
 except ImportError, e:
@@ -30,24 +34,6 @@ default_associations = {
 }
 
 
-_seq = [0]
-_latest_event_time = 0
-
-def make_startup_notification_id():
-	time = _current_event_time()
-	_seq[0] = _seq[0] + 1
-	return "%s-%d-%s_TIME%d" % ("kupfer", os.getpid(), _seq[0], time)
-
-def _current_event_time():
-	_time = gtk.get_current_event_time() or keybindings.get_current_event_time()
-	global _latest_event_time
-	if _time > 0:
-		_latest_event_time = _time
-	else:
-		_time = _latest_event_time
-	return _time
-
-
 def application_id(app_info, desktop_file=None):
 	"""Return an application id (string) for GAppInfo @app_info"""
 	app_id = app_info.get_id()
@@ -104,7 +90,8 @@ def launch_application(app_info, files=(), uris=(), paths=(), track=True,
 
 	try:
 		desktop_launch.launch_app_info(app_info, files,
-			   timestamp=_current_event_time(), desktop_file=desktop_file,
+			   timestamp=uievents.current_event_time(),
+			   desktop_file=desktop_file,
 			   launch_cb=launch_callback)
 	except SpawnError:
 		raise
@@ -243,7 +230,7 @@ class ApplicationsMatcherService (pretty.OutputMixin):
 			return False
 
 		# for now, just take any window
-		evttime = _current_event_time()
+		evttime = uievents.current_event_time()
 		for w in application_windows:
 			# we special-case the desktop
 			# only show desktop if it's the only window of this app
@@ -261,7 +248,7 @@ class ApplicationsMatcherService (pretty.OutputMixin):
 
 	def application_close_all(self, app_id):
 		application_windows = self.get_application_windows(app_id)
-		evttime = _current_event_time()
+		evttime = uievents.current_event_time()
 		for w in application_windows:
 			if not w.is_skip_tasklist():
 				w.close(evttime)
diff --git a/kupfer/plugin/windows.py b/kupfer/plugin/windows.py
index 242ff2d..62a662f 100644
--- a/kupfer/plugin/windows.py
+++ b/kupfer/plugin/windows.py
@@ -8,13 +8,13 @@ import gtk
 import wnck
 
 from kupfer.objects import Leaf, Action, Source
-from kupfer.ui import keybindings
+from kupfer.ui import uievents
 from kupfer.weaklib import gobject_connect_weakly
 from kupfer.obj.helplib import PicklingHelperMixin
 
 
 def _get_current_event_time():
-	return gtk.get_current_event_time() or keybindings.get_current_event_time()
+	return uievents.current_event_time()
 
 class WindowLeaf (Leaf):
 	def get_actions(self):
diff --git a/kupfer/ui/browser.py b/kupfer/ui/browser.py
index 41f27fd..723eada 100644
--- a/kupfer/ui/browser.py
+++ b/kupfer/ui/browser.py
@@ -21,8 +21,9 @@ from kupfer import kupferui
 from kupfer import version
 
 from kupfer import scheduler
-from kupfer.ui  import listen
+from kupfer.ui import listen
 from kupfer.ui import keybindings
+from kupfer.ui import uievents
 from kupfer.core import data, relevance, learn
 from kupfer.core import settings
 from kupfer import icons
@@ -1947,8 +1948,7 @@ class WindowController (pretty.OutputMixin):
 	def activate(self, sender=None, time=0):
 		self._window_hide_timer.invalidate()
 		if not time:
-			time = (gtk.get_current_event_time() or
-			        keybindings.get_current_event_time())
+			time = uievents.current_event_time()
 		if self._should_recenter_window():
 			self._center_window()
 		self.window.stick()
diff --git a/kupfer/ui/listen.py b/kupfer/ui/listen.py
index b560123..86e6873 100644
--- a/kupfer/ui/listen.py
+++ b/kupfer/ui/listen.py
@@ -16,6 +16,8 @@ except (ImportError, dbus.exceptions.DBusException), exc:
 	session_bus = None
 	print exc
 
+from kupfer.ui import uievents
+
 class AlreadyRunningError (Exception):
 	"""Service already available on the bus Exception"""
 	pass
@@ -47,22 +49,16 @@ class Service (ExportedGObject):
 		if session_bus:
 			session_bus.release_name(server_name)
 
+	@classmethod
 	@dbus.service.method(interface_name)
 	def Present(self):
-		self.emit("present", 0)
+		self.emit("present")
 
 	@dbus.service.method(interface_name, in_signature="ay",
 	                     byte_arrays=True)
-	def PresentWithStartup(self, startup_notification_id):
-		# Try to parse out the time from the startup id
-		time = 0
-		if "_TIME" in startup_notification_id:
-			_ign, bstime = startup_notification_id.split("_TIME", 1)
-			try:
-				time = int(bstime)
-			except ValueError:
-				pass
-		self.emit("present", time)
+	def PresentWithStartup(self, notify_id):
+		with uievents.using_startup_notify_id(notify_id):
+			self.emit("present")
 
 	@dbus.service.method(interface_name)
 	def ShowHide(self):
@@ -83,12 +79,18 @@ class Service (ExportedGObject):
 	def ExecuteFile(self, filepath):
 		self.emit("execute-file", filepath)
 
+	@dbus.service.method(interface_name, in_signature="say",
+	                     byte_arrays=True)
+	def ExecuteFileWithStartup(self, filepath, notify_id):
+		with uievents.using_startup_notify_id(notify_id):
+			self.emit("execute-file", filepath)
+
 	@dbus.service.method(interface_name)
 	def Quit(self):
 		self.emit("quit")
 
 gobject.signal_new("present", Service, gobject.SIGNAL_RUN_LAST,
-		gobject.TYPE_BOOLEAN, (gobject.TYPE_UINT64, ))
+		gobject.TYPE_BOOLEAN, ())
 
 gobject.signal_new("show-hide", Service, gobject.SIGNAL_RUN_LAST,
 		gobject.TYPE_BOOLEAN, ())
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index 9367c2d..31d3f6c 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -14,6 +14,7 @@ from kupfer import scheduler, kupferstring
 from kupfer import kupferui
 from kupfer.core import settings, plugins, relevance, sources
 from kupfer.ui import keybindings
+from kupfer.ui import uievents
 from kupfer.ui.credentials_dialog import ask_user_credentials
 from kupfer.ui import getkey_dialog
 from kupfer import plugin_support
@@ -816,7 +817,8 @@ class PreferencesWindowController (pretty.OutputMixin):
 					self.icons_combobox)
 
 	def show(self):
-		self.window.present()
+		self.window.present_with_time(uievents.current_event_time())
+
 	def show_focus_plugin(self, plugin_id):
 		"""
 		Open and show information about plugin @plugin_id
diff --git a/kupfer/ui/uievents.py b/kupfer/ui/uievents.py
new file mode 100644
index 0000000..416e4d0
--- /dev/null
+++ b/kupfer/ui/uievents.py
@@ -0,0 +1,58 @@
+import contextlib
+import os
+
+import gtk
+
+from kupfer import pretty
+from kupfer.ui import keybindings
+
+class _internal_data (object):
+	seq = 0
+	current_event_time = 0
+
+	@classmethod
+	def inc_seq(cls):
+		cls.seq = cls.seq + 1
+
+
+def make_startup_notification_id():
+	time = current_event_time()
+	_internal_data.inc_seq()
+	return "%s-%d-%s_TIME%d" % ("kupfer", os.getpid(), _internal_data.seq, time)
+
+def current_event_time():
+	return (gtk.get_current_event_time() or
+	        keybindings.get_current_event_time() or
+	        _internal_data.current_event_time)
+
+def _parse_notify_id(startup_notification_id):
+	"""
+	Return timestamp or 0 from @startup_notification_id
+	"""
+	time = 0
+	if "_TIME" in startup_notification_id:
+		_ign, bstime = startup_notification_id.split("_TIME", 1)
+		try:
+			time = int(bstime)
+		except ValueError:
+			pass
+	return time
+
+ contextlib contextmanager
+def using_startup_notify_id(notify_id):
+	"""
+	Pass in a DESKTOP_STARTUP_ID
+
+	with using_startup_notify_id(...):
+		pass
+	"""
+	timestamp = _parse_notify_id(notify_id)
+	if timestamp:
+		gtk.gdk.notify_startup_complete_with_id(notify_id)
+	try:
+		pretty.print_debug(__name__, "Using startup id", repr(notify_id))
+		_internal_data.current_event_time = timestamp
+		yield
+	finally:
+		_internal_data.current_event_time = gtk.gdk.CURRENT_TIME
+
diff --git a/kupfer/uiutils.py b/kupfer/uiutils.py
index dfbbd81..62a8e44 100644
--- a/kupfer/uiutils.py
+++ b/kupfer/uiutils.py
@@ -12,7 +12,7 @@ import pango
 
 from kupfer import pretty
 from kupfer import config, version
-from kupfer.ui import keybindings
+from kupfer.ui import uievents
 
 def _window_destroy_on_escape(widget, event):
 	"""
@@ -23,9 +23,6 @@ def _window_destroy_on_escape(widget, event):
 		widget.destroy()
 		return True
 
-def _get_current_event_time():
-	return gtk.get_current_event_time() or keybindings.get_current_event_time()
-
 def builder_get_objects_from_file(fname, attrs, autoconnect_to=None):
 	"""
 	Open @fname with gtk.Builder and yield objects named @attrs
@@ -108,7 +105,7 @@ def show_text_result(text, title=None):
 	hsize = int(min(wid + (winwid - oldwid) + 5, max_hsize))
 
 	window.resize(hsize, vsize)
-	window.present_with_time(_get_current_event_time())
+	window.present_with_time(uievents.current_event_time())
 
 def _wrap_paragraphs(text):
 	"""
@@ -170,7 +167,7 @@ def show_large_type(text):
 		return True
 	window.connect("key-press-event", _window_destroy)
 	window.show_all()
-	window.present_with_time(_get_current_event_time())
+	window.present_with_time(uievents.current_event_time())
 
 SERVICE_NAME = "org.freedesktop.Notifications"
 OBJECT_PATH = "/org/freedesktop/Notifications"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]