wayland: Set a more correct xdg_surface application id
authorJonas Ådahl <jadahl@gmail.com>
Mon, 23 Mar 2015 05:08:09 +0000 (13:08 +0800)
committerJonas Ådahl <jadahl@gmail.com>
Tue, 31 Mar 2015 04:37:50 +0000 (12:37 +0800)
The "app_id" of a xdg_surface should be the ID that can potentially be
used to get the DBUS name or the .desktop file.

For GtkApplication programs this is often the ID passed when creating the
GtkApplication object, so when available lets use that.

As fallbacks, first try g_get_prgname as it often corresponds to the
basename part of the .dektop file for non-GtkApplication programs.
Otherwise use gdk_get_program_class, even though that string usually
doesn't conform to the expectations of xdg_surface.set_application_id.

https://bugzilla.gnome.org/show_bug.cgi?id=746435

gdk/wayland/gdkwindow-wayland.c
gtk/gtkapplication-wayland.c

index 66d371f6d560682e8da53876145f98f01c857e4a..14ffbe47b19b22a180680025e944608a9cacc6c0 100644 (file)
@@ -115,6 +115,17 @@ struct _GdkWindowImplWayland
 
   gchar *title;
 
+  struct {
+    gboolean was_set;
+
+    gchar *application_id;
+    gchar *app_menu_path;
+    gchar *menubar_path;
+    gchar *window_object_path;
+    gchar *application_object_path;
+    gchar *unique_bus_name;
+  } application;
+
   GdkGeometry geometry_hints;
   GdkWindowHints geometry_mask;
 
@@ -144,6 +155,9 @@ static void gdk_wayland_window_configure (GdkWindow *window,
                                           int        height,
                                           int        scale);
 
+static void maybe_set_gtk_surface_dbus_properties (GdkWaylandDisplay *display_wayland,
+                                                   GdkWindowImplWayland *impl);
+
 GType _gdk_window_impl_wayland_get_type (void);
 
 G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
@@ -645,6 +659,13 @@ gdk_window_impl_wayland_finalize (GObject *object)
 
   g_free (impl->title);
 
+  g_free (impl->application.application_id);
+  g_free (impl->application.app_menu_path);
+  g_free (impl->application.menubar_path);
+  g_free (impl->application.window_object_path);
+  g_free (impl->application.application_object_path);
+  g_free (impl->application.unique_bus_name);
+
   g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
   g_clear_pointer (&impl->input_region, cairo_region_destroy);
 
@@ -964,6 +985,7 @@ gdk_wayland_window_create_xdg_surface (GdkWindow *window)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  const gchar *app_id;
 
   impl->xdg_surface = xdg_shell_get_xdg_surface (display_wayland->xdg_shell, impl->surface);
   xdg_surface_add_listener (impl->xdg_surface, &xdg_surface_listener, window);
@@ -977,7 +999,15 @@ gdk_wayland_window_create_xdg_surface (GdkWindow *window)
   if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     xdg_surface_set_fullscreen (impl->xdg_surface, NULL);
 
-  xdg_surface_set_app_id (impl->xdg_surface, gdk_get_program_class ());
+  app_id = impl->application.application_id;
+  if (app_id == NULL)
+    app_id = g_get_prgname ();
+  if (app_id == NULL)
+    app_id = gdk_get_program_class ();
+
+  xdg_surface_set_app_id (impl->xdg_surface, app_id);
+
+  maybe_set_gtk_surface_dbus_properties (display_wayland, impl);
 }
 
 static void
@@ -2408,6 +2438,43 @@ gdk_wayland_window_set_use_custom_surface (GdkWindow *window)
   impl->use_custom_surface = TRUE;
 }
 
+static void
+maybe_set_gtk_surface_dbus_properties (GdkWaylandDisplay *display_wayland,
+                                       GdkWindowImplWayland *impl)
+{
+  if (impl->application.was_set)
+    return;
+
+  if (impl->application.application_id == NULL &&
+      impl->application.app_menu_path == NULL &&
+      impl->application.menubar_path == NULL &&
+      impl->application.window_object_path == NULL &&
+      impl->application.application_object_path == NULL &&
+      impl->application.unique_bus_name == NULL)
+    return;
+
+  if (impl->gtk_surface == NULL)
+    {
+      if (impl->xdg_surface == NULL)
+        return;
+
+      if (display_wayland->gtk_shell == NULL)
+        return;
+
+      impl->gtk_surface = gtk_shell_get_gtk_surface (display_wayland->gtk_shell,
+                                                     impl->surface);
+    }
+
+  gtk_surface_set_dbus_properties (impl->gtk_surface,
+                                   impl->application.application_id,
+                                   impl->application.app_menu_path,
+                                   impl->application.menubar_path,
+                                   impl->application.window_object_path,
+                                   impl->application.application_object_path,
+                                   impl->application.unique_bus_name);
+  impl->application.was_set = TRUE;
+}
+
 void
 gdk_wayland_window_set_dbus_properties_libgtk_only (GdkWindow  *window,
                                                     const char *application_id,
@@ -2417,29 +2484,21 @@ gdk_wayland_window_set_dbus_properties_libgtk_only (GdkWindow  *window,
                                                     const char *application_object_path,
                                                     const char *unique_bus_name)
 {
-  GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+  GdkWaylandDisplay *display_wayland =
+    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
   GdkWindowImplWayland *impl;
 
   g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
 
   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
-  if (impl->gtk_surface == NULL)
-    {
-      if (impl->xdg_surface == NULL)
-        return;
-
-      if (display->gtk_shell == NULL)
-        return;
-
-      impl->gtk_surface = gtk_shell_get_gtk_surface (display->gtk_shell, impl->surface);
-    }
+  impl->application.application_id = g_strdup (application_id);
+  impl->application.app_menu_path = g_strdup (app_menu_path);
+  impl->application.menubar_path = g_strdup (menubar_path);
+  impl->application.window_object_path = g_strdup (window_object_path);
+  impl->application.application_object_path =
+    g_strdup (application_object_path);
+  impl->application.unique_bus_name = g_strdup (unique_bus_name);
 
-  gtk_surface_set_dbus_properties (impl->gtk_surface,
-                                   application_id,
-                                   app_menu_path,
-                                   menubar_path,
-                                   window_object_path,
-                                   application_object_path,
-                                   unique_bus_name);
+  maybe_set_gtk_surface_dbus_properties (display_wayland, impl);
 }
index c0b18bd22cbbe71a3c8131cc5d4206f099a33941..84df82c2753e03fc72635ac89c6662354fade9a6 100644 (file)
@@ -35,9 +35,11 @@ typedef struct
 G_DEFINE_TYPE (GtkApplicationImplWayland, gtk_application_impl_wayland, GTK_TYPE_APPLICATION_IMPL_DBUS)
 
 static void
-gtk_application_impl_wayland_handle_window_map (GtkApplicationImpl *impl,
-                                                GtkWindow          *window)
+gtk_application_impl_wayland_handle_window_realize (GtkApplicationImpl *impl,
+                                                    GtkWindow          *window)
 {
+  GtkApplicationImplClass *impl_class =
+    GTK_APPLICATION_IMPL_CLASS (gtk_application_impl_wayland_parent_class);
   GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
   GdkWindow *gdk_window;
   gchar *window_path;
@@ -54,6 +56,8 @@ gtk_application_impl_wayland_handle_window_map (GtkApplicationImpl *impl,
                                                       window_path, dbus->object_path, dbus->unique_name);
 
   g_free (window_path);
+
+  impl_class->handle_window_realize (impl, window);
 }
 
 static void
@@ -66,5 +70,6 @@ gtk_application_impl_wayland_class_init (GtkApplicationImplWaylandClass *class)
 {
   GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
 
-  impl_class->handle_window_map = gtk_application_impl_wayland_handle_window_map;
+  impl_class->handle_window_realize =
+    gtk_application_impl_wayland_handle_window_realize;
 }