[gnome-shell] Consume startup-notification APPLICATION_ID



commit c92ce5983d751491d5887ac6e0c6d95b9a0cbffb
Author: Colin Walters <walters verbum org>
Date:   Wed Feb 24 11:29:44 2010 -0500

    Consume startup-notification APPLICATION_ID
    
    This patch ensures we're showing the correct data when doing
    startup-notification.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=612833

 configure.ac               |   11 +++
 js/ui/panel.js             |   17 +++--
 src/shell-app-system.c     |   14 +++-
 src/shell-window-tracker.c |  155 ++++++++++++++++++++++++++++++++------------
 src/shell-window-tracker.h |    1 +
 5 files changed, 145 insertions(+), 53 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 2f5c0ca..710e61b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,17 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1
 				 clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
                                  libstartup-notification-1.0
                                  gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
+
+# This is for the newly added application id bits, we can replace this with
+# a version check later
+saved_CFLAGS=$CFLAGS
+saved_LIBS=$LIBS
+CFLAGS=$MUTTER_PLUGIN_CFLAGS
+LIBS=$MUTTER_PLUGIN_LIBS
+AC_CHECK_FUNCS(sn_startup_sequence_get_application_id)
+CFLAGS=$saved_CFLAGS
+LIBS=$saved_LIBS
+
 PKG_CHECK_MODULES(TIDY, clutter-1.0)
 PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6 gnome-desktop-2.0 >= 2.26)
 PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
diff --git a/js/ui/panel.js b/js/ui/panel.js
index e35a655..bd9c11b 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -248,10 +248,9 @@ AppPanelMenu.prototype = {
         let focusedApp = tracker.focus_app;
 
         let lastSequence = null;
-        if (focusedApp == null) {
-            let sequences = tracker.get_startup_sequences();
-            if (sequences.length > 0)
-                lastSequence = sequences[sequences.length - 1];
+        let sequences = tracker.get_startup_sequences();
+        if (sequences.length > 0) {
+            lastSequence = sequences[sequences.length - 1];
         }
 
         // If the currently focused app hasn't changed and the current
@@ -262,13 +261,17 @@ AppPanelMenu.prototype = {
                     && lastSequence.get_id() == this._activeSequence.get_id())))
             return;
 
-        this._focusedApp = focusedApp;
-        this._activeSequence = lastSequence;
-
         if (this._iconBox.child != null)
             this._iconBox.child.destroy();
         this._iconBox.hide();
         this._label.setText('');
+
+        if (focusedApp == null && lastSequence != null)
+            focusedApp = lastSequence.get_app();
+
+        this._focusedApp = focusedApp;
+        this._activeSequence = lastSequence;
+
         let icon;
         if (this._focusedApp != null) {
             icon = this._focusedApp.get_faded_icon(AppDisplay.APPICON_SIZE);
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index c2d0025..94d5a79 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -1224,10 +1224,16 @@ shell_app_info_launch_full (ShellAppInfo *info,
       meta_window_activate (info->window, timestamp);
       return TRUE;
     }
-
-  filename = shell_app_info_get_desktop_file_path (info);
-  gapp = g_desktop_app_info_new_from_filename (filename);
-  g_free (filename);
+  else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
+    {
+      gapp = g_desktop_app_info_new (shell_app_info_get_id (info));
+    }
+  else
+    {
+      filename = shell_app_info_get_desktop_file_path (info);
+      gapp = g_desktop_app_info_new_from_filename (filename);
+      g_free (filename);
+    }
 
   if (!gapp)
     {
diff --git a/src/shell-window-tracker.c b/src/shell-window-tracker.c
index 1c9ee6c..9f91917 100644
--- a/src/shell-window-tracker.c
+++ b/src/shell-window-tracker.c
@@ -286,16 +286,16 @@ shell_window_tracker_is_window_interesting (MetaWindow *window)
 }
 
 /**
- * get_app_for_window_direct:
+ * get_app_from_window_wmclass:
  *
  * Looks only at the given window, and attempts to determine
- * an application based on WM_CLASS.  If that fails, then
- * a "transient" application is created.
+ * an application based on WM_CLASS.  If one can't be determined,
+ * return %NULL.
  *
- * Return value: (transfer full): A newly-referenced #ShellApp
+ * Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
  */
 static ShellApp *
-get_app_for_window_direct (MetaWindow  *window)
+get_app_from_window_wmclass (MetaWindow  *window)
 {
   ShellApp *app;
   ShellAppSystem *appsys;
@@ -306,7 +306,7 @@ get_app_for_window_direct (MetaWindow  *window)
   wmclass = get_appid_from_window (window);
 
   if (!wmclass)
-    return shell_app_system_get_app_for_window (appsys, window);
+    return NULL;
 
   with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL);
   g_free (wmclass);
@@ -322,49 +322,33 @@ get_app_for_window_direct (MetaWindow  *window)
         app = shell_app_system_get_app (appsys, id);
     }
 
-  if (app == NULL)
-    app = shell_app_system_get_app_for_window (appsys, window);
-
   return app;
 }
 
 /**
- * get_app_for_window:
+ * get_app_from_window_group:
+ * @monitor: a #ShellWindowTracker
+ * @window: a #MetaWindow
  *
- * Determines the application associated with a window, using
- * all available information such as the window's MetaGroup,
- * and what we know about other windows.
+ * Check other windows in the group for @window to see if we have
+ * an application for one of them.
+ *
+ * Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
  */
-static ShellApp *
-get_app_for_window (ShellWindowTracker    *monitor,
-                    MetaWindow         *window)
+static ShellApp*
+get_app_from_window_group (ShellWindowTracker  *monitor,
+                           MetaWindow          *window)
 {
   ShellApp *result;
-  MetaWindow *source_window;
   GSList *group_windows;
   MetaGroup *group;
   GSList *iter;
 
-  result = NULL;
-  if (meta_window_get_window_type (window) == META_WINDOW_NORMAL)
-    {
-      result = g_hash_table_lookup (monitor->window_to_app, window);
-      if (result != NULL)
-        {
-          g_object_ref (result);
-          return result;
-        }
-      else
-        return get_app_for_window_direct (window);
-    }
-
   group = meta_window_get_group (window);
   if (group == NULL)
-    group_windows = g_slist_prepend (NULL, window);
-  else
-    group_windows = meta_group_list_windows (group);
+    return NULL;
 
-  source_window = window;
+  group_windows = meta_group_list_windows (group);
 
   result = NULL;
   /* Try finding a window in the group of type NORMAL; if we
@@ -376,21 +360,83 @@ get_app_for_window (ShellWindowTracker    *monitor,
       if (meta_window_get_window_type (group_window) != META_WINDOW_NORMAL)
         continue;
 
-       source_window = group_window;
-       result = g_hash_table_lookup (monitor->window_to_app, group_window);
-       if (result)
-         break;
+      result = g_hash_table_lookup (monitor->window_to_app, group_window);
+      if (result)
+        break;
     }
 
   g_slist_free (group_windows);
 
+  if (result)
+    g_object_ref (result);
+
+  return result;
+}
+
+/**
+ * get_app_for_window:
+ *
+ * Determines the application associated with a window, using
+ * all available information such as the window's MetaGroup,
+ * and what we know about other windows.
+ */
+static ShellApp *
+get_app_for_window (ShellWindowTracker    *monitor,
+                    MetaWindow         *window)
+{
+  ShellApp *result;
+  const char *startup_id;
+
+  result = NULL;
+  /* First, we check whether we already know about this window,
+   * if so, just return that.
+   */
+  if (meta_window_get_window_type (window) == META_WINDOW_NORMAL)
+    {
+      result = g_hash_table_lookup (monitor->window_to_app, window);
+      if (result != NULL)
+        {
+          g_object_ref (result);
+          return result;
+        }
+    }
+
+  /* Check if the app's WM_CLASS specifies an app */
+  result = get_app_from_window_wmclass (window);
   if (result != NULL)
+    return result;
+
+  /* Now we check whether we have a match through startup-notification */
+  startup_id = meta_window_get_startup_id (window);
+  if (startup_id)
     {
-      g_object_ref (result);
-      return result;
+      GSList *iter, *sequences;
+
+      sequences = shell_window_tracker_get_startup_sequences (monitor);
+      for (iter = sequences; iter; iter = iter->next)
+        {
+          ShellStartupSequence *sequence = iter->data;
+          const char *id = shell_startup_sequence_get_id (sequence);
+          if (strcmp (id, startup_id) != 0)
+            continue;
+
+          result = shell_startup_sequence_get_app (sequence);
+          if (result)
+            break;
+        }
     }
 
-  return get_app_for_window_direct (source_window);
+  /* If we didn't get a startup-notification match, see if we matched
+   * any other windows in the group.
+   */
+  if (result == NULL)
+    result = get_app_from_window_group (monitor, window);
+
+  /* Our last resort - we create a fake app from the window */
+  if (result == NULL)
+    result = shell_app_system_get_app_for_window (shell_app_system_get_default (), window);
+
+  return result;
 }
 
 const char *
@@ -588,7 +634,6 @@ on_startup_sequence_changed (MetaScreen            *screen,
                              SnStartupSequence     *sequence,
                              ShellWindowTracker    *self)
 {
-  /* Just proxy the signal */
   g_signal_emit (G_OBJECT (self), signals[STARTUP_SEQUENCE_CHANGED], 0, sequence);
 }
 
@@ -795,6 +840,32 @@ shell_startup_sequence_get_id (ShellStartupSequence *sequence)
   return sn_startup_sequence_get_id ((SnStartupSequence*)sequence);
 }
 
+/**
+ * shell_startup_sequence_get_app:
+ * @sequence: A #ShellStartupSequence
+ *
+ * Returns: (transfer full): The application being launched, or %NULL if unknown.
+ */
+ShellApp *
+shell_startup_sequence_get_app (ShellStartupSequence *sequence)
+{
+#ifdef HAVE_SN_STARTUP_SEQUENCE_GET_APPLICATION_ID
+  const char *appid;
+  ShellAppSystem *appsys;
+  ShellApp *app;
+
+  appid = sn_startup_sequence_get_application_id ((SnStartupSequence*)sequence);
+  if (!appid)
+    return NULL;
+
+  appsys = shell_app_system_get_default ();
+  app = shell_app_system_get_app_for_path (appsys, appid);
+  return app;
+#else
+  return NULL;
+#endif
+}
+
 const char *
 shell_startup_sequence_get_name (ShellStartupSequence *sequence)
 {
diff --git a/src/shell-window-tracker.h b/src/shell-window-tracker.h
index acc3028..bb2014d 100644
--- a/src/shell-window-tracker.h
+++ b/src/shell-window-tracker.h
@@ -50,6 +50,7 @@ typedef struct _ShellStartupSequence ShellStartupSequence;
 GType shell_startup_sequence_get_type (void);
 
 const char *shell_startup_sequence_get_id (ShellStartupSequence *sequence);
+ShellApp *shell_startup_sequence_get_app (ShellStartupSequence *sequence);
 const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
 gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
 ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);



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