[kupfer: 22/67] launch: Improve application vs. window tracking, ignore terminals



commit 59c862dc31ff29fe8b1ac4f12864151eb21c8e09
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Tue Mar 15 22:52:29 2011 +0100

    launch: Improve application vs. window tracking, ignore terminals

 kupfer/launch.py   |  102 ++++++++++++++++++++--------------------------------
 kupfer/terminal.py |    7 ++++
 2 files changed, 46 insertions(+), 63 deletions(-)
---
diff --git a/kupfer/launch.py b/kupfer/launch.py
index dd08164..f2edfa2 100644
--- a/kupfer/launch.py
+++ b/kupfer/launch.py
@@ -9,15 +9,14 @@ from kupfer import pretty, config
 from kupfer import scheduler
 from kupfer import desktop_launch
 from kupfer.ui import keybindings
+from kupfer import terminal
 
 try:
 	import wnck
 except ImportError, e:
-	pretty.print_info(__name__, "Disabling launch module:", e)
+	pretty.print_info(__name__, "Disabling window tracking:", e)
 	wnck = None
 
-kupfer_env = "KUPFER_APP_ID"
-
 default_associations = {
 	"evince" : "Document Viewer",
 	"file-roller" : "File Roller",
@@ -28,29 +27,6 @@ default_associations = {
 }
 
 
-def _read_environ(pid, envcache=None):
-	"""Read the environment for application with @pid
-	and return as a dictionary. Only works for the user's
-	own processes, of course
-	"""
-	if envcache and pid in envcache:
-		return envcache[pid]
-	try:
-		f = open("/proc/%d/environ" % int(pid), "r")
-	except IOError:
-		return None
-	else:
-		env = f.read()
-	environ = {}
-	for line in env.split("\x00"):
-		vals = line.split("=", 1)
-		if len(vals) == 2:
-			environ[vals[0]] = vals[1]
-		else:
-			continue
-	if envcache is not None: envcache[pid] = environ
-	return environ
-
 def application_id(app_info, desktop_file=None):
 	"""Return an application id (string) for GAppInfo @app_info"""
 	app_id = app_info.get_id()
@@ -78,7 +54,6 @@ def launch_application(app_info, files=(), uris=(), paths=(), track=True,
 	"""
 	assert app_info
 
-	from gtk.gdk import AppLaunchContext
 	from gio import File
 	from glib import GError
 
@@ -87,31 +62,31 @@ def launch_application(app_info, files=(), uris=(), paths=(), track=True,
 	if uris:
 		files = [File(p) for p in uris]
 
+	svc = GetApplicationsMatcherService()
+	app_id = application_id(app_info, desktop_file)
+
+	if activate and svc.application_is_running(app_id):
+		svc.application_to_front(app_id)
+		return True
+
+	# An launch callback closure for the @app_id
+	def application_launch_callback(argv, pid, notify_id, files, timestamp):
+		pretty.print_debug(__name__, "Launched", argv, pid, notify_id, files)
+		is_terminal = terminal.is_known_terminal_executable(argv[0])
+		pretty.print_debug(__name__, argv, "is terminal:", is_terminal)
+		if not is_terminal:
+			svc.launched_application(app_id, pid)
+
 	if track:
-		app_id = application_id(app_info, desktop_file)
-		os.putenv(kupfer_env, app_id)
+		launch_callback = application_launch_callback
 	else:
-		app_id = ""
-	svc = GetApplicationsMatcherService()
-	try:
-		if activate and svc.application_is_running(app_id):
-			svc.application_to_front(app_id)
-			return True
+		launch_callback = None
 
-		try:
-			ret = desktop_launch.launch_app_info(app_info, files,
-					timestamp=_current_event_time(), desktop_file=desktop_file)
-			if not ret:
-				pretty.print_info(__name__, "Error launching", app_info)
-		except GError, e:
-			pretty.print_info(__name__, "Error:", e)
-			return False
-		else:
-			if track:
-				app_id = application_id(app_info, desktop_file)
-				svc.launched_application(app_id)
-	finally:
-		os.unsetenv(kupfer_env)
+	ret = desktop_launch.launch_app_info(app_info, files,
+			   timestamp=_current_event_time(), desktop_file=desktop_file,
+			   launch_cb=launch_callback)
+	if not ret:
+		pretty.print_info(__name__, "Error launching", app_info)
 	return True
 
 def application_is_running(app_id):
@@ -141,7 +116,9 @@ class ApplicationsMatcherService (pretty.OutputMixin):
 		return screen.get_windows_stacked()
 
 	def _get_filename(self):
-		version = 1
+		# Version 1: Up to incl v203
+		# Version 2: Do not track terminals
+		version = 2
 		return os.path.join(config.get_cache_home(),
 				"application_identification_v%d.pickle" % version)
 	def _load(self):
@@ -197,27 +174,26 @@ class ApplicationsMatcherService (pretty.OutputMixin):
 			return True
 		return False
 
-	def launched_application(self, app_id):
+	def launched_application(self, app_id, pid):
 		if self._has_match(app_id):
 			return
 		timeout = time() + 15
-		envcache = {}
-		gobject.timeout_add_seconds(2, self._find_application, app_id, timeout, envcache)
+		gobject.timeout_add_seconds(2, self._find_application, app_id, pid, timeout)
 		# and once later
-		gobject.timeout_add_seconds(30, self._find_application, app_id, timeout, envcache)
+		gobject.timeout_add_seconds(30, self._find_application, app_id, pid, timeout)
 
-	def _find_application(self, app_id, timeout, envcache=None):
+	def _find_application(self, app_id, pid, timeout):
+		if self._has_match(app_id):
+			return False
 		self.output_debug("Looking for window for application", app_id)
 		for w in self._get_wnck_screen_windows_stacked():
 			app = w.get_application()
-			pid = app.get_pid()
-			if not pid:
-				pid = w.get_pid()
-			env = _read_environ(pid, envcache=envcache)
-			if env and kupfer_env in env:
-				if env[kupfer_env] == app_id:
-					self._store(app_id, w)
-					return False
+			app_pid = app.get_pid()
+			if not app_pid:
+				app_pid = w.get_pid()
+			if app_pid == pid:
+				self._store(app_id, w)
+				return False
 		if time() > timeout:
 			return False
 		return True
diff --git a/kupfer/terminal.py b/kupfer/terminal.py
index 0727932..b4186a6 100644
--- a/kupfer/terminal.py
+++ b/kupfer/terminal.py
@@ -25,6 +25,13 @@ def register_terminal(terminal_description):
 def unregister_terminal(terminal_id):
 	_TERMINALS[:] = [t for t in _TERMINALS if t.app_id != terminal_id]
 
+def is_known_terminal_executable(exearg):
+	"Return True if @exearg is a known terminal"
+	for term in _TERMINALS:
+		if exearg == term.argv[0]:
+			return True
+	return False
+
 def get_valid_terminals():
 	for term in _TERMINALS:
 		# iterate over $PATH directories



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