[mutter/wip/carlosg/axe-libsn: 1/2] x11: Drop usage of libstartup-notification



commit 312e53d7e1d0a29dc5ea52471a7cb82aeac94072
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Apr 16 12:47:00 2019 +0200

    x11: Drop usage of libstartup-notification
    
    And replace with our own XClientMessageEvent handling. It has the advantage
    that we can mix Wayland and X11 startup notifications without always going
    through X11 so that libstartup-notification is able to get the full picture.
    This will fare much better on no/intermittent X11 availability.
    
    A second advantage is the removed dependency, and that it seems to result
    in less code (yay abstractions!).

 config.h.meson                          |   3 -
 meson.build                             |   8 -
 src/core/display-private.h              |   4 -
 src/core/main.c                         |   5 -
 src/core/meta-launch-context.c          |  15 -
 src/meson.build                         |   6 -
 src/x11/meta-startup-notification-x11.c | 474 +++++++++++++++-----------------
 src/x11/meta-startup-notification-x11.h |   5 -
 8 files changed, 217 insertions(+), 303 deletions(-)
---
diff --git a/config.h.meson b/config.h.meson
index 70681d774..34f5f239f 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -46,9 +46,6 @@
 /* Building with SM support */
 #mesondefine HAVE_SM
 
-/* Building with startup notification support */
-#mesondefine HAVE_STARTUP_NOTIFICATION
-
 /* Path to Xwayland executable */
 #mesondefine XWAYLAND_PATH
 
diff --git a/meson.build b/meson.build
index 6ce9e59f2..1c0226d4d 100644
--- a/meson.build
+++ b/meson.build
@@ -225,12 +225,6 @@ if have_pango_ft2
   pangoft2_dep = dependency('pangoft2')
 endif
 
-have_startup_notification = get_option('startup_notification')
-if have_startup_notification
-  libstartup_notification_dep = dependency('libstartup-notification-1.0',
-                                           version: libstartup_notification_req)
-endif
-
 have_remote_desktop = get_option('remote_desktop')
 if have_remote_desktop
   libpipewire_dep = dependency('libpipewire-0.2', version: libpipewire_req)
@@ -334,7 +328,6 @@ cdata.set('HAVE_WAYLAND_EGLSTREAM', have_wayland_eglstream)
 cdata.set('HAVE_LIBGUDEV', have_libgudev)
 cdata.set('HAVE_LIBWACOM', have_libwacom)
 cdata.set('HAVE_SM', have_sm)
-cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification)
 cdata.set('HAVE_INTROSPECTION', have_introspection)
 
 xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
@@ -399,7 +392,6 @@ output = [
   '        gudev.................... ' + have_libgudev.to_string(),
   '        Wacom.................... ' + have_libwacom.to_string(),
   '        SM....................... ' + have_sm.to_string(),
-  '        Startup notification..... ' + have_startup_notification.to_string(),
   '        Introspection............ ' + have_introspection.to_string(),
   '',
   '    Tests:',
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 55e1d27d1..d2b8921b4 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -31,10 +31,6 @@
 #include <X11/extensions/sync.h>
 #include <X11/Xlib.h>
 
-#ifdef HAVE_STARTUP_NOTIFICATION
-#include <libsn/sn.h>
-#endif
-
 #include "clutter/clutter.h"
 #include "core/keybindings-private.h"
 #include "core/meta-gesture-tracker-private.h"
diff --git a/src/core/main.c b/src/core/main.c
index e8464720f..3ad2999fe 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -118,11 +118,6 @@ static void prefs_changed_callback (MetaPreference pref,
 static void
 meta_print_compilation_info (void)
 {
-#ifdef HAVE_STARTUP_NOTIFICATION
-  meta_verbose ("Compiled with startup notification\n");
-#else
-  meta_verbose ("Compiled without startup notification\n");
-#endif
 }
 
 /**
diff --git a/src/core/meta-launch-context.c b/src/core/meta-launch-context.c
index eda51514f..3b73ebf31 100644
--- a/src/core/meta-launch-context.c
+++ b/src/core/meta-launch-context.c
@@ -125,27 +125,12 @@ meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context,
                                            GList             *files)
 {
   MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
-  MetaDisplay *display = context->display;
   int workspace_idx = -1;
   char *startup_id = NULL;
 
   if (context->workspace)
     workspace_idx = meta_workspace_index (context->workspace);
 
-  if (display->x11_display)
-    {
-      /* If there is a X11 display, we prefer going entirely through
-       * libsn, as SnMonitor expects to keep a view of the full lifetime
-       * of the startup sequence. We can't avoid it when launching and
-       * expect that a "remove" message from a X11 client will be handled.
-       */
-      startup_id =
-        meta_x11_startup_notification_launch (display->x11_display,
-                                              info,
-                                              context->timestamp,
-                                              workspace_idx);
-    }
-
   if (!startup_id)
     {
       const char *application_id = NULL;
diff --git a/src/meson.build b/src/meson.build
index 9919b5cfb..499b7ef35 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -55,12 +55,6 @@ if have_libgudev
   ]
 endif
 
-if have_startup_notification
-  mutter_pkg_private_deps += [
-    libstartup_notification_dep,
-  ]
-endif
-
 if have_libwacom
   mutter_pkg_private_deps += [
     libwacom_dep,
diff --git a/src/x11/meta-startup-notification-x11.c b/src/x11/meta-startup-notification-x11.c
index d6814926a..e063dd0bc 100644
--- a/src/x11/meta-startup-notification-x11.c
+++ b/src/x11/meta-startup-notification-x11.c
@@ -26,345 +26,305 @@
 #include "meta/meta-x11-errors.h"
 #include "x11/meta-x11-display-private.h"
 
-#ifdef HAVE_STARTUP_NOTIFICATION
+#define MAX_MESSAGE_LENGTH 4096
+#define CLIENT_MESSAGE_DATA_LENGTH 20
 
 enum
 {
-  PROP_SEQ_X11_0,
-  PROP_SEQ_X11_SEQ,
-  N_SEQ_X11_PROPS
+  MESSAGE_TYPE_NEW,
+  MESSAGE_TYPE_REMOVE,
 };
 
-struct _MetaStartupSequenceX11
+struct _MetaX11StartupNotification
 {
-  MetaStartupSequence parent_instance;
-  SnStartupSequence *seq;
+  Atom atom_net_startup_info_begin;
+  Atom atom_net_startup_info;
+  GHashTable *messages;
+  MetaX11Display *x11_display;
 };
 
-struct _MetaX11StartupNotification
+typedef struct
 {
-  SnDisplay *sn_display;
-  SnMonitorContext *sn_context;
-};
+  Window xwindow;
+  GString *data;
+} StartupMessage;
 
-static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS];
 
-G_DEFINE_TYPE (MetaStartupSequenceX11,
-               meta_startup_sequence_x11,
-               META_TYPE_STARTUP_SEQUENCE)
+static StartupMessage *
+startup_message_new (Window window)
+{
+  StartupMessage *message;
+
+  message = g_new0 (StartupMessage, 1);
+  message->xwindow = window;
+  message->data = g_string_new (NULL);
+
+  return message;
+}
 
 static void
-meta_startup_sequence_x11_complete (MetaStartupSequence *seq)
+startup_message_free (StartupMessage *message)
 {
-  MetaStartupSequenceX11 *seq_x11;
-
-  seq_x11 = META_STARTUP_SEQUENCE_X11 (seq);
-  sn_startup_sequence_complete (seq_x11->seq);
+  g_string_free (message->data, TRUE);
+  g_free (message);
 }
 
 static void
-meta_startup_sequence_x11_finalize (GObject *object)
+skip_whitespace (const gchar **str)
+{
+  while ((*str)[0] == ' ')
+    (*str)++;
+}
+
+static gchar *
+parse_key (const gchar **str)
 {
-  MetaStartupSequenceX11 *seq_x11;
+  const gchar *start = *str;
 
-  seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
-  sn_startup_sequence_unref (seq_x11->seq);
+  while (*str[0] != '\0' && *str[0] != '=')
+    (*str)++;
 
-  G_OBJECT_CLASS (meta_startup_sequence_x11_parent_class)->finalize (object);
+  if (start == *str)
+    return NULL;
+
+  return g_strndup (start, *str - start);
 }
 
-static void
-meta_startup_sequence_x11_set_property (GObject      *object,
-                                        guint         prop_id,
-                                        const GValue *value,
-                                        GParamSpec   *pspec)
+static gchar *
+parse_value (const gchar **str)
 {
-  MetaStartupSequenceX11 *seq_x11;
+  const gchar *end;
+  gboolean escaped = FALSE, quoted = FALSE;
+  GString *value;
 
-  seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
+  end = *str;
+  value = g_string_new (NULL);
 
-  switch (prop_id)
+  while (end[0] != '\0')
     {
-    case PROP_SEQ_X11_SEQ:
-      seq_x11->seq = g_value_get_pointer (value);
-      sn_startup_sequence_ref (seq_x11->seq);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
+      if (escaped)
+        {
+          g_string_append_c (value, end[0]);
+          escaped = FALSE;
+        }
+      else
+        {
+          if (!quoted && end[0] == ' ')
+            break;
+          else if (end[0] == '"')
+            quoted = !quoted;
+          else if (end[0] == '\\')
+            escaped = TRUE;
+          else
+            g_string_append_c (value, end[0]);
+        }
 
-static void
-meta_startup_sequence_x11_get_property (GObject    *object,
-                                        guint       prop_id,
-                                        GValue     *value,
-                                        GParamSpec *pspec)
-{
-  MetaStartupSequenceX11 *seq_x11;
+      end++;
+    }
 
-  seq_x11 = META_STARTUP_SEQUENCE_X11 (object);
+  *str = end;
 
-  switch (prop_id)
+  if (value->len == 0)
     {
-    case PROP_SEQ_X11_SEQ:
-      g_value_set_pointer (value, seq_x11->seq);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+      g_string_free (value, TRUE);
+      return NULL;
     }
-}
 
-static void
-meta_startup_sequence_x11_init (MetaStartupSequenceX11 *seq)
-{
+  return g_string_free (value, FALSE);
 }
 
-static void
-meta_startup_sequence_x11_class_init (MetaStartupSequenceX11Class *klass)
+static gboolean
+startup_message_parse (StartupMessage  *message,
+                       int             *type,
+                       gchar          **id,
+                       GHashTable     **data)
 {
-  MetaStartupSequenceClass *seq_class;
-  GObjectClass *object_class;
-
-  seq_class = META_STARTUP_SEQUENCE_CLASS (klass);
-  seq_class->complete = meta_startup_sequence_x11_complete;
-
-  object_class = G_OBJECT_CLASS (klass);
-  object_class->finalize = meta_startup_sequence_x11_finalize;
-  object_class->set_property = meta_startup_sequence_x11_set_property;
-  object_class->get_property = meta_startup_sequence_x11_get_property;
-
-  seq_x11_props[PROP_SEQ_X11_SEQ] =
-    g_param_spec_pointer ("seq",
-                          "Sequence",
-                          "Sequence",
-                          G_PARAM_READWRITE |
-                          G_PARAM_CONSTRUCT_ONLY);
-
-  g_object_class_install_properties (object_class, N_SEQ_X11_PROPS,
-                                     seq_x11_props);
-}
+  const gchar *str = message->data->str;
 
-static MetaStartupSequence *
-meta_startup_sequence_x11_new (SnStartupSequence *seq)
-{
-  gint64 timestamp;
-
-  timestamp = sn_startup_sequence_get_timestamp (seq) * 1000;
-  return g_object_new (META_TYPE_STARTUP_SEQUENCE_X11,
-                       "id", sn_startup_sequence_get_id (seq),
-                       "icon-name", sn_startup_sequence_get_icon_name (seq),
-                       "application-id", sn_startup_sequence_get_application_id (seq),
-                       "wmclass", sn_startup_sequence_get_wmclass (seq),
-                       "name", sn_startup_sequence_get_name (seq),
-                       "workspace", sn_startup_sequence_get_workspace (seq),
-                       "timestamp", timestamp,
-                       "seq", seq,
-                       NULL);
-}
+  if (strncmp (str, "new:", 4) == 0)
+    {
+      *type = MESSAGE_TYPE_NEW;
+      str += 4;
+    }
+  else if (strncmp (str, "remove:", 7) == 0)
+    {
+      *type = MESSAGE_TYPE_REMOVE;
+      str += 7;
+    }
+  else
+    {
+      return FALSE;
+    }
 
-static void
-sn_error_trap_push (SnDisplay *sn_display,
-                    Display   *xdisplay)
-{
-  MetaDisplay *display;
+  *data = g_hash_table_new_full (g_str_hash,
+                                 g_str_equal,
+                                 g_free,
+                                 g_free);
+  while (str[0])
+    {
+      gchar *key, *value;
 
-  display = meta_display_for_x_display (xdisplay);
-  if (display != NULL)
-    meta_x11_error_trap_push (display->x11_display);
-}
+      skip_whitespace (&str);
+      key = parse_key (&str);
+      if (!key)
+        break;
 
-static void
-sn_error_trap_pop (SnDisplay *sn_display,
-                   Display   *xdisplay)
-{
-  MetaDisplay *display;
+      str++;
+      value = parse_value (&str);
 
-  display = meta_display_for_x_display (xdisplay);
-  if (display != NULL)
-    meta_x11_error_trap_pop (display->x11_display);
-}
+      if (!value)
+        {
+          g_free (key);
+          break;
+        }
 
-static void
-meta_startup_notification_sn_event (SnMonitorEvent *event,
-                                    void           *user_data)
-{
-  MetaX11Display *x11_display = user_data;
-  MetaStartupNotification *sn = x11_display->display->startup_notification;
-  MetaStartupSequence *seq;
-  SnStartupSequence *sequence;
+      g_hash_table_insert (*data, key, value);
+    }
 
-  sequence = sn_monitor_event_get_startup_sequence (event);
+  *id = g_strdup (g_hash_table_lookup (*data, "ID"));
 
-  sn_startup_sequence_ref (sequence);
+  return TRUE;
+}
 
-  switch (sn_monitor_event_get_type (event))
-    {
-    case SN_MONITOR_EVENT_INITIATED:
-      {
-        const char *wmclass;
-
-        wmclass = sn_startup_sequence_get_wmclass (sequence);
-
-        meta_topic (META_DEBUG_STARTUP,
-                    "Received startup initiated for %s wmclass %s\n",
-                    sn_startup_sequence_get_id (sequence),
-                    wmclass ? wmclass : "(unset)");
-
-        seq = meta_startup_sequence_x11_new (sequence);
-        meta_startup_notification_add_sequence (sn, seq);
-        g_object_unref (seq);
-      }
-      break;
-
-    case SN_MONITOR_EVENT_COMPLETED:
-      {
-        meta_topic (META_DEBUG_STARTUP,
-                    "Received startup completed for %s\n",
-                    sn_startup_sequence_get_id (sequence));
-
-        seq = meta_startup_notification_lookup_sequence (sn, sn_startup_sequence_get_id (sequence));
-        if (seq)
-          {
-            meta_startup_sequence_complete (seq);
-            meta_startup_notification_remove_sequence (sn, seq);
-          }
-      }
-      break;
-
-    case SN_MONITOR_EVENT_CHANGED:
-      meta_topic (META_DEBUG_STARTUP,
-                  "Received startup changed for %s\n",
-                  sn_startup_sequence_get_id (sequence));
-      break;
-
-    case SN_MONITOR_EVENT_CANCELED:
-      meta_topic (META_DEBUG_STARTUP,
-                  "Received startup canceled for %s\n",
-                  sn_startup_sequence_get_id (sequence));
-      break;
-    }
+static gboolean
+startup_message_add_data (StartupMessage *message,
+                          const gchar    *data)
+{
+  int len;
+
+  len = strnlen (data, CLIENT_MESSAGE_DATA_LENGTH);
+  g_string_append_len (message->data, data, len);
 
-  sn_startup_sequence_unref (sequence);
+  return (message->data->len > MAX_MESSAGE_LENGTH ||
+          len < CLIENT_MESSAGE_DATA_LENGTH);
 }
-#endif
 
 void
 meta_x11_startup_notification_init (MetaX11Display *x11_display)
 {
-#ifdef HAVE_STARTUP_NOTIFICATION
   MetaX11StartupNotification *x11_sn;
 
   x11_sn = g_new0 (MetaX11StartupNotification, 1);
-  x11_sn->sn_display = sn_display_new (x11_display->xdisplay,
-                                            sn_error_trap_push,
-                                            sn_error_trap_pop);
-  x11_sn->sn_context =
-    sn_monitor_context_new (x11_sn->sn_display,
-                            meta_x11_display_get_screen_number (x11_display),
-                            meta_startup_notification_sn_event,
-                            x11_display,
-                            NULL);
-
+  x11_sn->atom_net_startup_info_begin = XInternAtom (x11_display->xdisplay,
+                                                     "_NET_STARTUP_INFO_BEGIN",
+                                                     False);
+  x11_sn->atom_net_startup_info = XInternAtom (x11_display->xdisplay,
+                                               "_NET_STARTUP_INFO",
+                                               False);
+  x11_sn->messages = g_hash_table_new_full (NULL, NULL, NULL,
+                                            (GDestroyNotify) startup_message_free);
+  x11_sn->x11_display = x11_display;
   x11_display->startup_notification = x11_sn;
-#endif
 }
 
 void
 meta_x11_startup_notification_release (MetaX11Display *x11_display)
 {
-#ifdef HAVE_STARTUP_NOTIFICATION
   MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
 
   x11_display->startup_notification = NULL;
 
   if (x11_sn)
     {
-      sn_monitor_context_unref (x11_sn->sn_context);
-      sn_display_unref (x11_sn->sn_display);
+      g_hash_table_unref (x11_sn->messages);
       g_free (x11_sn);
     }
-#endif
 }
 
-gboolean
-meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
-                                             XEvent         *xevent)
+static void
+handle_message (MetaX11StartupNotification *x11_sn,
+                StartupMessage             *message)
 {
-  MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
+  MetaStartupNotification *sn = x11_sn->x11_display->display->startup_notification;
+  MetaStartupSequence *seq;
+  GHashTable *data;
+  char *id;
+  int type;
 
-  if (!x11_sn)
-    return FALSE;
+  if (message->data->len <= MAX_MESSAGE_LENGTH &&
+      startup_message_parse (message, &type, &id, &data))
+    {
+      if (type == MESSAGE_TYPE_NEW)
+        {
+          seq = g_object_new (META_TYPE_STARTUP_SEQUENCE,
+                              "id", id,
+                              "icon-name", g_hash_table_lookup (data, "ICON_NAME"),
+                              "application-id", g_hash_table_lookup (data, "APPLICATION_ID"),
+                              "wmclass", g_hash_table_lookup (data, "WMCLASS"),
+                              "name", g_hash_table_lookup (data, "NAME"),
+                              "workspace", g_hash_table_lookup (data, "WORKSPACE"),
+                              "timestamp", g_hash_table_lookup (data, "TIMESTAMP"),
+                              NULL);
+
+          meta_topic (META_DEBUG_STARTUP,
+                      "Received startup initiated for %s wmclass %s\n",
+                      id, (gchar*) g_hash_table_lookup (data, "WMCLASS"));
+
+          meta_startup_notification_add_sequence (sn, seq);
+          g_object_unref (seq);
+        }
+      else if (type == MESSAGE_TYPE_REMOVE)
+        {
+          meta_topic (META_DEBUG_STARTUP,
+                      "Received startup completed for %s\n", id);
+          seq = meta_startup_notification_lookup_sequence (sn, id);
+
+          if (seq)
+            {
+              meta_startup_sequence_complete (seq);
+              meta_startup_notification_remove_sequence (sn, seq);
+            }
+        }
 
-  return sn_display_process_event (x11_sn->sn_display, xevent);
-}
+      g_hash_table_unref (data);
+      g_free (id);
+    }
 
-typedef void (* SetAppIdFunc) (SnLauncherContext *context,
-                               const char        *app_id);
+  g_hash_table_remove (x11_sn->messages, GINT_TO_POINTER (message->xwindow));
+}
 
-gchar *
-meta_x11_startup_notification_launch (MetaX11Display *x11_display,
-                                      GAppInfo       *app_info,
-                                      uint32_t        timestamp,
-                                      int             workspace)
+static gboolean
+handle_startup_notification_event (MetaX11StartupNotification *x11_sn,
+                                   XClientMessageEvent        *client_event)
 {
-  gchar *startup_id = NULL;
-#ifdef HAVE_STARTUP_NOTIFICATION
-  MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
-  SnLauncherContext *sn_launcher;
-  int screen;
-
-  screen = meta_x11_display_get_screen_number (x11_display);
-  sn_launcher = sn_launcher_context_new (x11_sn->sn_display, screen);
+  StartupMessage *message;
 
-  sn_launcher_context_set_name (sn_launcher, g_app_info_get_name (app_info));
-  sn_launcher_context_set_workspace (sn_launcher, workspace);
-  sn_launcher_context_set_binary_name (sn_launcher,
-                                       g_app_info_get_executable (app_info));
-
-  if (G_IS_DESKTOP_APP_INFO (app_info))
+  if (client_event->message_type == x11_sn->atom_net_startup_info_begin)
+    {
+      message = startup_message_new (client_event->window);
+      g_hash_table_insert (x11_sn->messages,
+                           GINT_TO_POINTER (client_event->window),
+                           message);
+      if (startup_message_add_data (message, client_event->data.b))
+        handle_message (x11_sn, message);
+      return TRUE;
+    }
+  else if (client_event->message_type == x11_sn->atom_net_startup_info)
     {
-      const char *application_id;
-      SetAppIdFunc func = NULL;
-      GModule *self;
-
-      application_id =
-        g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info));
-      self = g_module_open (NULL, G_MODULE_BIND_MASK);
-
-      /* This here is a terrible workaround to bypass a libsn bug that is not
-       * likely to get fixed at this point.
-       * sn_launcher_context_set_application_id is correctly defined in the
-       * sn-launcher.h file, but it's mistakenly called
-       * sn_launcher_set_application_id in the C file.
-       *
-       * We look up the symbol instead, but still prefer the correctly named
-       * function, if one were ever to be added.
-       */
-      if (!g_module_symbol (self, "sn_launcher_context_set_application_id",
-                            (gpointer *) &func))
+      message = g_hash_table_lookup (x11_sn->messages,
+                                     GINT_TO_POINTER (client_event->window));
+      if (message)
         {
-          g_module_symbol (self, "sn_launcher_set_application_id",
-                           (gpointer *) &func);
+          if (startup_message_add_data (message, client_event->data.b))
+            handle_message (x11_sn, message);
+          return TRUE;
         }
-
-      if (func)
-        func (sn_launcher, application_id);
-
-      g_module_close (self);
     }
 
-  sn_launcher_context_initiate (sn_launcher,
-                                g_get_prgname (),
-                                g_app_info_get_name (app_info),
-                                timestamp);
+  return FALSE;
+}
+
+gboolean
+meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
+                                             XEvent         *xevent)
+{
+  MetaX11StartupNotification *x11_sn = x11_display->startup_notification;
 
-  startup_id = g_strdup (sn_launcher_context_get_startup_id (sn_launcher));
+  if (!x11_sn)
+    return FALSE;
 
-  /* Fire and forget, we have a SnMonitor in addition */
-  sn_launcher_context_unref (sn_launcher);
-#endif /* HAVE_STARTUP_NOTIFICATION */
+  if (xevent->xany.type != ClientMessage)
+    return FALSE;
 
-  return startup_id;
+  return handle_startup_notification_event (x11_sn, &xevent->xclient);
 }
diff --git a/src/x11/meta-startup-notification-x11.h b/src/x11/meta-startup-notification-x11.h
index b46a45e5d..050d20caf 100644
--- a/src/x11/meta-startup-notification-x11.h
+++ b/src/x11/meta-startup-notification-x11.h
@@ -36,9 +36,4 @@ void     meta_x11_startup_notification_release (MetaX11Display *x11_display);
 gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display,
                                                       XEvent         *xevent);
 
-gchar *  meta_x11_startup_notification_launch (MetaX11Display *x11_display,
-                                               GAppInfo       *app_info,
-                                               uint32_t        timestamp,
-                                               int             workspace);
-
 #endif /* META_X11_STARTUP_NOTIFICATION_H */


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