Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--shell/model/homeactivity.py36
-rw-r--r--shell/shellservice.py9
-rw-r--r--sugar/activity/activity.py1
-rw-r--r--sugar/activity/activityfactory.py33
-rw-r--r--sugar/activity/activityhandle.py4
-rw-r--r--sugar/datastore/datastore.py14
7 files changed, 74 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index 9ac60ae..07859a3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+* #2240 Ensure activity uniquness in the shell. (marco)
+
Snapshot f6f3f2b520
* #2103 Use selection grey for progress in the browser entry. (marco)
diff --git a/shell/model/homeactivity.py b/shell/model/homeactivity.py
index 4487c09..8b6a8dc 100644
--- a/shell/model/homeactivity.py
+++ b/shell/model/homeactivity.py
@@ -64,6 +64,14 @@ class HomeActivity(gobject.GObject):
self._launch_time = time.time()
self._launching = False
+ self._retrieve_service()
+
+ if not self._service:
+ bus = dbus.SessionBus()
+ bus.add_signal_receiver(self._name_owner_changed_cb,
+ signal_name="NameOwnerChanged",
+ dbus_interface="org.freedesktop.DBus")
+
def set_window(self, window):
"""An activity is 'launched' once we get its window."""
if self._window or self._xid:
@@ -75,22 +83,14 @@ class HomeActivity(gobject.GObject):
self._xid = window.get_xid()
def get_service(self):
- """Retrieve the application's sugar introspection service
+ """Get the activity service
Note that non-native Sugar applications will not have
such a service, so the return value will be None in
those cases.
"""
- bus = dbus.SessionBus()
- try:
- service = dbus.Interface(
- bus.get_object(_SERVICE_NAME + self._activity_id,
- _SERVICE_PATH + "/" + self._activity_id),
- _SERVICE_INTERFACE)
- except dbus.DBusException:
- service = None
- return service
+ return self._service
def get_title(self):
"""Retrieve the application's root window's suggested title"""
@@ -182,3 +182,19 @@ class HomeActivity(gobject.GObject):
def do_get_property(self, pspec):
if pspec.name == 'launching':
return self._launching
+
+ def _get_service_name(self):
+ return _SERVICE_NAME + self._activity_id
+
+ def _retrieve_service(self):
+ try:
+ bus = dbus.SessionBus()
+ proxy = bus.get_object(self._get_service_name(),
+ _SERVICE_PATH + "/" + self._activity_id)
+ self._service = dbus.Interface(proxy, _SERVICE_INTERFACE)
+ except dbus.DBusException:
+ self._service = None
+
+ def _name_owner_changed_cb(self, name, old, new):
+ if name == self._get_service_name():
+ self._retrieve_service()
diff --git a/shell/shellservice.py b/shell/shellservice.py
index c612d6e..5728e44 100644
--- a/shell/shellservice.py
+++ b/shell/shellservice.py
@@ -63,6 +63,15 @@ class ShellService(dbus.service.Object):
bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus)
dbus.service.Object.__init__(self, bus_name, _DBUS_PATH)
+ @dbus.service.method(_DBUS_SHELL_IFACE,
+ in_signature="s", out_signature="b")
+ def ActivateActivity(self, activity_id):
+ host = self._shell.get_activity(activity_id)
+ if host:
+ host.present()
+ return True
+
+ return False
@dbus.service.method(_DBUS_SHELL_IFACE,
in_signature="ss", out_signature="")
diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py
index 22a84a7..ffa46d9 100644
--- a/sugar/activity/activity.py
+++ b/sugar/activity/activity.py
@@ -248,6 +248,7 @@ class Activity(Window, gtk.Container):
self._jobject.metadata['title'] = _('%s Activity') % get_bundle_name()
self._jobject.metadata['title_set_by_user'] = '0'
self._jobject.metadata['activity'] = self.get_service_name()
+ self._jobject.metadata['activity_id'] = self.get_id()
self._jobject.metadata['keep'] = '0'
#self._jobject.metadata['buddies'] = ''
self._jobject.metadata['preview'] = ''
diff --git a/sugar/activity/activityfactory.py b/sugar/activity/activityfactory.py
index d1480b2..fe2a8bd 100644
--- a/sugar/activity/activityfactory.py
+++ b/sugar/activity/activityfactory.py
@@ -90,24 +90,32 @@ class ActivityCreationHandler(gobject.GObject):
self._activity_handle = activity_handle
bus = dbus.SessionBus()
+
+ bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
+ self._shell = dbus.Interface(bus_object, _SHELL_IFACE)
+
object_path = '/' + service_name.replace('.', '/')
proxy_obj = bus.get_object(service_name, object_path,
follow_name_owner_changes=True)
- factory = dbus.Interface(proxy_obj, _ACTIVITY_FACTORY_INTERFACE)
+ self._factory = dbus.Interface(proxy_obj, _ACTIVITY_FACTORY_INTERFACE)
- factory.create(self._activity_handle.get_dict(),
- reply_handler=self._no_reply_handler,
- error_handler=self._create_error_handler)
-
- bus = dbus.SessionBus()
- bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
- self._shell = dbus.Interface(bus_object, _SHELL_IFACE)
+ if self.get_activity_id() != None:
+ self._shell.ActivateActivity(self.get_activity_id(),
+ reply_handler=self._activate_reply_handler,
+ error_handler=self._activate_error_handler)
+ else:
+ self._launch_activity()
+ def _launch_activity(self):
self._shell.NotifyLaunch(
- service_name, self.get_activity_id(),
+ self._service_name, self.get_activity_id(),
reply_handler=self._no_reply_handler,
error_handler=self._notify_launch_error_handler)
+ self._factory.create(self._activity_handle.get_dict(),
+ reply_handler=self._no_reply_handler,
+ error_handler=self._create_error_handler)
+
def get_activity_id(self):
"""Retrieve the unique identity for this activity"""
return self._activity_handle.activity_id
@@ -121,6 +129,13 @@ class ActivityCreationHandler(gobject.GObject):
def _notify_launch_error_handler(self, err):
logging.debug('Notify launch failed %s' % err)
+ def _activate_reply_handler(self, activated):
+ if not activated:
+ self._launch_activity()
+
+ def _activate_error_handler(self, err):
+ logging.debug("Activity activation request failed %s" % err)
+
def _create_reply_handler(self, xid):
logging.debug("Activity created %s (%s)." %
(self._activity_handle.activity_id, self._service_name))
diff --git a/sugar/activity/activityhandle.py b/sugar/activity/activityhandle.py
index 26d0d47..8e90e70 100644
--- a/sugar/activity/activityhandle.py
+++ b/sugar/activity/activityhandle.py
@@ -20,8 +20,8 @@ from sugar.presence import presenceservice
class ActivityHandle(object):
"""Data structure storing simple activity metadata"""
def __init__(
- self, activity_id, pservice_id=None,
- object_id=None,uri=None
+ self, activity_id=None, pservice_id=None,
+ object_id=None, uri=None
):
"""Initialise the handle from activity_id
diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py
index 2561733..4249239 100644
--- a/sugar/datastore/datastore.py
+++ b/sugar/datastore/datastore.py
@@ -24,6 +24,7 @@ from sugar.datastore import dbus_helpers
from sugar import activity
from sugar.activity.bundle import Bundle
from sugar.activity import activityfactory
+from sugar.activity.activityhandle import ActivityHandle
class DSMetadata(gobject.GObject):
__gsignals__ = {
@@ -38,7 +39,8 @@ class DSMetadata(gobject.GObject):
else:
self._props = props
- default_keys = ['activity', 'mime_type', 'title_set_by_user']
+ default_keys = ['activity', 'activity_id',
+ 'mime_type', 'title_set_by_user']
for key in default_keys:
if not self._props.has_key(key):
self._props[key] = ''
@@ -116,9 +118,13 @@ class DSObject:
activityfactory.create(bundle.get_service_name())
else:
- activity_info = self.get_activities()[0]
- activityfactory.create_with_object_id(activity_info.service_name,
- self.object_id)
+ service_name = self.get_activities()[0].service_name
+
+ handle = ActivityHandle(object_id=self.object_id)
+ if self.metadata['activity_id']:
+ handle.activity_id = self.metadata['activity_id']
+
+ activityfactory.create(service_name, handle)
def get(object_id):
logging.debug('datastore.get')