Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Narvaez <dwnarvaez@gmail.com>2013-02-02 12:09:26 (GMT)
committer Daniel Narvaez <dwnarvaez@gmail.com>2013-02-02 12:09:26 (GMT)
commitc72116c41e731bab6654f438472c9bade9f81089 (patch)
treecde86622f620a9c69323dee468f6bd5889383513
parent9227fd84f4399b4a1181aed0dc465754c30350e7 (diff)
Fallback to _NET_WM_PID to map windows to activitieshtml2
Most toolkits supports that property, so this allows to write activities without setting our own custom properties, which is very handy if you are not using python or are not able to go that low level. This is similar to what gnome-shell is doing. Simplifying a bit their logic to map windows to applications is 1 Check WM_CLASS 2 Check _NET_WM_PID 3 Check startup notification properties Now 1 is not good enough for us. They map multiple windows to the same application, while for us every window is a separate activity. About 3, we don't currently implement startup notification but we could in the future. In that case it could just be a fallback. It probably make sense to keep our own custom properties as 1, for complicated cases like running the window in a subprocess.
-rw-r--r--src/jarabe/model/shell.py44
-rw-r--r--src/jarabe/view/service.py6
2 files changed, 28 insertions, 22 deletions
diff --git a/src/jarabe/model/shell.py b/src/jarabe/model/shell.py
index 437ff90..c6fe742 100644
--- a/src/jarabe/model/shell.py
+++ b/src/jarabe/model/shell.py
@@ -54,7 +54,8 @@ class Activity(GObject.GObject):
LAUNCH_FAILED = 1
LAUNCHED = 2
- def __init__(self, activity_info, activity_id, color, window=None):
+ def __init__(self, activity_info, activity_id, bundle_id, color,
+ window=None, pid=None):
"""Initialise the HomeActivity
activity_info -- sugar3.activity.registry.ActivityInfo instance,
@@ -74,6 +75,8 @@ class Activity(GObject.GObject):
self._activity_info = activity_info
self._launch_time = time.time()
self._launch_status = Activity.LAUNCHING
+ self._bundle_id = bundle_id
+ self._pid = pid
if color is not None:
self._color = color
@@ -204,16 +207,13 @@ class Activity(GObject.GObject):
return self._windows[0]
return None
- def get_type(self):
+ def get_bundle_id(self):
"""Retrieve the activity bundle id for future reference"""
- if not self._windows:
- return None
- else:
- return SugarExt.wm_get_bundle_id(self._windows[0].get_xid())
+ self._bundle_id
def is_journal(self):
"""Returns boolean if the activity is of type JournalActivity"""
- return self.get_type() == 'org.laptop.JournalActivity'
+ return self._bundle_id == 'org.laptop.JournalActivity'
def get_launch_time(self):
"""Return the time at which the activity was first launched
@@ -225,9 +225,7 @@ class Activity(GObject.GObject):
def get_pid(self):
"""Returns the activity's PID"""
- if not self._windows:
- return None
- return self._windows[0].get_pid()
+ return self._pid
def get_bundle_path(self):
"""Returns the activity's bundle directory"""
@@ -530,13 +528,20 @@ class ShellModel(GObject.GObject):
activity_id = SugarExt.wm_get_activity_id(xid)
- service_name = SugarExt.wm_get_bundle_id(xid)
- if service_name:
+ bundle_id = SugarExt.wm_get_bundle_id(xid)
+ if bundle_id:
registry = get_registry()
- activity_info = registry.get_bundle(service_name)
+ activity_info = registry.get_bundle(bundle_id)
else:
activity_info = None
+ if not activity_id and window.get_pid():
+ for home_activity in self._activities:
+ launch_status = home_activity.get_launch_status()
+ if home_activity.get_pid() == window.get_pid() and \
+ launch_status == Activity.LAUNCHING:
+ activity_id = home_activity.get_activity_id()
+
if activity_id:
home_activity = self.get_activity_by_id(activity_id)
@@ -551,7 +556,7 @@ class ShellModel(GObject.GObject):
logging.debug('first window registered for %s', activity_id)
color = self._shared_activities.get(activity_id, None)
home_activity = Activity(activity_info, activity_id,
- color, window)
+ bundle_id, color, window=window)
self._add_activity(home_activity)
else:
logging.debug('window registered for %s', activity_id)
@@ -626,15 +631,16 @@ class ShellModel(GObject.GObject):
self.emit('activity-removed', home_activity)
self._activities.remove(home_activity)
- def notify_launch(self, activity_id, service_name):
+ def notify_launch(self, activity_id, bundle_id, pid):
registry = get_registry()
- activity_info = registry.get_bundle(service_name)
+ activity_info = registry.get_bundle(bundle_id)
if not activity_info:
raise ValueError("Activity service name '%s'" \
" was not found in the bundle registry."
- % service_name)
+ % bundle_id)
color = self._shared_activities.get(activity_id, None)
- home_activity = Activity(activity_info, activity_id, color)
+ home_activity = Activity(activity_info, activity_id, bundle_id,
+ color, pid=pid)
self._add_activity(home_activity)
self._set_active_activity(home_activity)
@@ -650,7 +656,7 @@ class ShellModel(GObject.GObject):
home_activity = self.get_activity_by_id(activity_id)
if home_activity:
logging.debug('Activity %s (%s) launch failed', activity_id,
- home_activity.get_type())
+ home_activity.get_bundle_id())
if self.get_launcher(activity_id) is not None:
self.emit('launch-failed', home_activity)
else:
diff --git a/src/jarabe/view/service.py b/src/jarabe/view/service.py
index 61b3d59..c7187c7 100644
--- a/src/jarabe/view/service.py
+++ b/src/jarabe/view/service.py
@@ -80,9 +80,9 @@ class UIService(dbus.service.Object):
return False
@dbus.service.method(_DBUS_SHELL_IFACE,
- in_signature='ss', out_signature='')
- def NotifyLaunch(self, bundle_id, activity_id):
- shell.get_model().notify_launch(activity_id, bundle_id)
+ in_signature='ssi', out_signature='')
+ def NotifyLaunch(self, bundle_id, activity_id, pid):
+ shell.get_model().notify_launch(activity_id, bundle_id, pid)
@dbus.service.method(_DBUS_SHELL_IFACE,
in_signature='s', out_signature='')