My recent interactions with the launcher have led me to frustration.
I updated a number of tickets on the subject, and also created an
aggragator to track them all (http://dev.laptop.org/ticket/8090).  The
attached patch is an attempt to solve nearly all of the known
problems.  Testing would be very much appreciated.

The only known issue I've found with this patch is that you can't
click on the activity level button (in the Frame) while a launcher is
the selected activity (though you can click on the launcher icon
directly).  Marco understands this issue, but feels we might be better
off working in a fix separately, since it could be more invasive.
Apart from that know bug, I believe that this new launcher yields
expected behavior everywhere; if you disagree, or find other bugs, let
me know!

- Eben
diff --git a/src/model/homeactivity.py b/src/model/homeactivity.py
index fa50932..34ebda3 100644
--- a/src/model/homeactivity.py
+++ b/src/model/homeactivity.py
@@ -73,9 +73,11 @@ class HomeActivity(gobject.GObject):
                                     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:
-            raise RuntimeError("Activity is already launched!")
+        """Set the window for the activity
+
+        We allow resetting the window for an activity so that we
+        can replace the launcher once we get its real window.
+        """
         if not window:
             raise ValueError("window must be valid")
 
diff --git a/src/model/homemodel.py b/src/model/homemodel.py
index 49f2a23..a35dcc9 100644
--- a/src/model/homemodel.py
+++ b/src/model/homemodel.py
@@ -175,8 +175,10 @@ class HomeModel(gobject.GObject):
 
             home_activity.set_window(window)
 
-            home_activity.props.launching = False
-            self.emit('launch-completed', home_activity)
+            # We only emit launch-completed if this is not a launcher window
+            if service_name:
+                home_activity.props.launching = False
+                self.emit('launch-completed', home_activity)
 
             if self._active_activity is None:
                 self._set_active_activity(home_activity)
diff --git a/src/view/Shell.py b/src/view/Shell.py
index 514b500..77280ac 100644
--- a/src/view/Shell.py
+++ b/src/view/Shell.py
@@ -53,6 +53,7 @@ class Shell(gobject.GObject):
 
         self._model = shellmodel.get_instance()
         self._hosts = {}
+        self._launchers = {}
         self._screen = wnck.screen_get_default()
         self._screen_rotation = 0
 
@@ -63,8 +64,6 @@ class Shell(gobject.GObject):
         self.home_window = HomeWindow()
         self.home_window.show()
 
-        self._launch_window = LaunchWindow()
-
         home_model = self._model.get_home()
         home_model.connect('launch-started', self.__launch_started_cb)
         home_model.connect('launch-failed', self.__launch_failed_cb)
@@ -94,17 +93,24 @@ class Shell(gobject.GObject):
 
     def __launch_started_cb(self, home_model, home_activity):
         if home_activity.get_type() != 'org.laptop.JournalActivity':
-            self._launch_window.show()
+            launch_window = LaunchWindow(home_activity)
+            launch_window.show()
+            self._launchers[home_activity.get_activity_id()] = launch_window
+            self._model.set_zoom_level(shellmodel.ShellModel.ZOOM_ACTIVITY)
 
     def __launch_failed_cb(self, home_model, home_activity):
-        self._launch_window.hide()
+        launch_window = self._launchers[home_activity.get_activity_id()]
+        if launch_window:
+            launch_window.destroy()
 
     def __launch_completed_cb(self, home_model, home_activity):
-        self._launch_window.hide()
-
         activity_host = ActivityHost(home_activity)
         self._hosts[activity_host.get_xid()] = activity_host
 
+        launch_window = self._launchers[home_activity.get_activity_id()]
+        if launch_window:
+            launch_window.destroy()
+
     def _activity_removed_cb(self, home_model, home_activity):
         xid = home_activity.get_xid()
         if self._hosts.has_key(xid):
diff --git a/src/view/launchwindow.py b/src/view/launchwindow.py
index ee3ccfa..2c4d73a 100644
--- a/src/view/launchwindow.py
+++ b/src/view/launchwindow.py
@@ -19,6 +19,7 @@ import hippo
 import gobject
 import logging
 
+from sugar import wm
 from sugar.graphics import style
 from sugar.graphics import animator
 from sugar.graphics.xocolor import XoColor
@@ -27,14 +28,15 @@ from model import shellmodel
 from view.pulsingicon import CanvasPulsingIcon
 
 class LaunchWindow(hippo.CanvasWindow):
-    def __init__(self):
+    def __init__(self, home_activity):
         gobject.GObject.__init__(
-                self, type_hint=gtk.gdk.WINDOW_TYPE_HINT_SPLASHSCREEN)
+                self, type_hint=gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
 
-        self._box = LaunchBox()
+        self._activity_id = home_activity.get_activity_id()
+        self._box = LaunchBox(home_activity)
         self.set_root(self._box)
 
-        self.connect('focus-out-event', self.__focus_out_event_cb)
+        self.connect('realize', self.__realize_cb)
 
         screen = gtk.gdk.screen_get_default()
         screen.connect('size-changed', self.__size_changed_cb)
@@ -48,18 +50,21 @@ class LaunchWindow(hippo.CanvasWindow):
     def _update_size(self):
         self.resize(gtk.gdk.screen_width(), gtk.gdk.screen_height())
 
-    def __focus_out_event_cb(self, widget, event):
-        self.hide()
-        
+    def __realize_cb(self, widget):
+        wm.set_activity_id(widget.window, str(self._activity_id))
+
     def __size_changed_cb(self, screen):
         self._update_size()
 
 class LaunchBox(hippo.CanvasBox):
-    def __init__(self):
+    def __init__(self, home_activity):
         gobject.GObject.__init__(self, orientation=hippo.ORIENTATION_VERTICAL,
                                  background_color=style.COLOR_WHITE.get_int())
 
-        self._activity_icon = CanvasPulsingIcon()
+        self._home_activity = home_activity
+        self._activity_icon = CanvasPulsingIcon(
+                file_name=home_activity.get_icon_path(),
+                pulse_color=home_activity.get_icon_color())
         self.append(self._activity_icon, hippo.PACK_EXPAND)
 
         # FIXME support non-xo colors in CanvasPulsingIcon
@@ -72,14 +77,8 @@ class LaunchBox(hippo.CanvasBox):
         self._home = shellmodel.get_instance().get_home()
         self._home.connect('active-activity-changed',
                            self.__active_activity_changed_cb)
-        self._home.connect('launch-failed', self.__launch_ended_cb)
-        self._home.connect('launch-completed', self.__launch_ended_cb)
-
-        self._update_icon()
 
     def zoom_in(self):
-        logging.debug('zooming in to activity')
-
         self._activity_icon.props.size = style.STANDARD_ICON_SIZE
 
         self._animator.remove_all()
@@ -87,9 +86,6 @@ class LaunchBox(hippo.CanvasBox):
                                       style.STANDARD_ICON_SIZE,
                                       style.XLARGE_ICON_SIZE))
         self._animator.start()
-
-        logging.debug('starting pulse')
-
         self._activity_icon.props.pulsing = True
 
     def suspend(self):
@@ -98,25 +94,12 @@ class LaunchBox(hippo.CanvasBox):
     def resume(self):
         self._activity_icon.props.paused = False
 
-    def _update_icon(self):
-        activity = self._home.get_active_activity()
-        if activity is not None:
-            self._activity_icon.props.file_name = activity.get_icon_path()
-            self._activity_icon.props.pulse_color = activity.get_icon_color()
-        else:
-            self._activity_icon.props.file_name = None
-
-        if activity is not None and activity.props.launching:
+    def __active_activity_changed_cb(self, model, activity):
+        if activity == self._home_activity:
             self.resume()
         else:
             self.suspend()
 
-    def __active_activity_changed_cb(self, model, activity):
-        self._update_icon()
-
-    def __launch_ended_cb(self, model, activity):
-        self._update_icon()
-
 class _Animation(animator.Animation):
     def __init__(self, icon, start_size, end_size):
         animator.Animation.__init__(self, 0.0, 1.0)
_______________________________________________
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar

Reply via email to