[kupfer: 22/67] launch: Improve application vs. window tracking, ignore terminals
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer: 22/67] launch: Improve application vs. window tracking, ignore terminals
- Date: Sat, 19 Mar 2011 00:59:35 +0000 (UTC)
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]