[gtk+] move menus over from GLib



commit 60317cbf1ad16eb9228d9d901275a65db7f2cde5
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Jan 16 14:46:04 2012 -0500

    move menus over from GLib
    
    App menu and menubar are now properties of GtkApplication and their bus
    location is exported using X window properties.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=668118

 gtk/gtkapplication.c        |  232 ++++++++++++++++++++++++++++++++++---------
 gtk/gtkapplication.h        |    4 +-
 gtk/gtkapplicationprivate.h |    6 +
 gtk/gtkapplicationwindow.c  |   21 +++--
 4 files changed, 205 insertions(+), 58 deletions(-)
---
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index 95a5e8e..b4c29a8 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -134,7 +134,9 @@ static guint gtk_application_signals[LAST_SIGNAL];
 
 enum {
   PROP_ZERO,
-  PROP_REGISTER_SESSION
+  PROP_REGISTER_SESSION,
+  PROP_APP_MENU,
+  PROP_MENUBAR
 };
 
 G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
@@ -147,7 +149,17 @@ struct _GtkApplicationPrivate
 
 #ifdef GDK_WINDOWING_X11
   GDBusConnection *session_bus;
-  gchar *window_prefix;
+  const gchar     *application_id;
+  gchar           *object_path;
+
+  GMenuModel      *app_menu;
+  gchar           *app_menu_path;
+  guint            app_menu_id;
+
+  GMenuModel      *menubar;
+  gchar           *menubar_path;
+  guint            menubar_id;
+
   guint next_id;
 
   GDBusProxy *sm_proxy;
@@ -168,6 +180,59 @@ struct _GtkApplicationPrivate
 
 #ifdef GDK_WINDOWING_X11
 static void
+gtk_application_x11_publish_menu (GtkApplication  *application,
+                                  const gchar     *type,
+                                  GMenuModel      *model,
+                                  guint           *id,
+                                  gchar          **path)
+{
+  gint i;
+
+  /* unexport any existing menu */
+  if (*id)
+    {
+      g_dbus_connection_unexport_menu_model (application->priv->session_bus, *id);
+      g_free (*path);
+      *path = NULL;
+      *id = 0;
+    }
+
+  /* export the new menu, if there is one */
+  if (model != NULL)
+    {
+      /* try getting the preferred name */
+      *path = g_strconcat (application->priv->object_path, "/menus/", type, NULL);
+      *id = g_dbus_connection_export_menu_model (application->priv->session_bus, *path, model, NULL);
+
+      /* keep trying until we get a working name... */
+      for (i = 0; *id == 0; i++)
+        {
+          g_free (*path);
+          *path = g_strdup_printf ("%s/menus/%s%d", application->priv->object_path, type, i);
+          *id = g_dbus_connection_export_menu_model (application->priv->session_bus, *path, model, NULL);
+        }
+    }
+}
+
+static void
+gtk_application_set_app_menu_x11 (GtkApplication *application,
+                                  GMenuModel     *app_menu)
+{
+  gtk_application_x11_publish_menu (application, "appmenu", app_menu,
+                                    &application->priv->app_menu_id,
+                                    &application->priv->app_menu_path);
+}
+
+static void
+gtk_application_set_menubar_x11 (GtkApplication *application,
+                                 GMenuModel     *menubar)
+{
+  gtk_application_x11_publish_menu (application, "menubar", menubar,
+                                    &application->priv->menubar_id,
+                                    &application->priv->menubar_path);
+}
+
+static void
 gtk_application_window_added_x11 (GtkApplication *application,
                                   GtkWindow      *window)
 {
@@ -190,7 +255,7 @@ gtk_application_window_added_x11 (GtkApplication *application,
           guint window_id;
 
           window_id = application->priv->next_id++;
-          window_path = g_strdup_printf ("%s%d", application->priv->window_prefix, window_id);
+          window_path = g_strdup_printf ("%s/window/%d", application->priv->object_path, window_id);
           success = gtk_application_window_publish (app_window, application->priv->session_bus, window_path);
           g_free (window_path);
         }
@@ -210,11 +275,11 @@ gtk_application_window_removed_x11 (GtkApplication *application,
 }
 
 static gchar *
-window_prefix_from_appid (const gchar *appid)
+object_path_from_appid (const gchar *appid)
 {
   gchar *appid_path, *iter;
 
-  appid_path = g_strconcat ("/", appid, "/windows/", NULL);
+  appid_path = g_strconcat ("/", appid, NULL);
   for (iter = appid_path; *iter; iter++)
     {
       if (*iter == '.')
@@ -236,7 +301,7 @@ gtk_application_startup_x11 (GtkApplication *application)
 
   application_id = g_application_get_application_id (G_APPLICATION (application));
   application->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
-  application->priv->window_prefix = window_prefix_from_appid (application_id);
+  application->priv->object_path = object_path_from_appid (application_id);
 
   gtk_application_startup_session_dbus (GTK_APPLICATION (application));
 }
@@ -244,8 +309,8 @@ gtk_application_startup_x11 (GtkApplication *application)
 static void
 gtk_application_shutdown_x11 (GtkApplication *application)
 {
-  g_free (application->priv->window_prefix);
-  application->priv->window_prefix = NULL;
+  g_free (application->priv->object_path);
+  application->priv->object_path = NULL;
   g_clear_object (&application->priv->session_bus);
 
   g_clear_object (&application->priv->sm_proxy);
@@ -253,6 +318,25 @@ gtk_application_shutdown_x11 (GtkApplication *application)
   g_free (application->priv->app_id);
   g_free (application->priv->client_path);
 }
+
+const gchar *
+gtk_application_get_dbus_object_path (GtkApplication *application)
+{
+  return application->priv->object_path;
+}
+
+const gchar *
+gtk_application_get_app_menu_object_path (GtkApplication *application)
+{
+  return application->priv->app_menu_path;
+}
+
+const gchar *
+gtk_application_get_menubar_object_path (GtkApplication *application)
+{
+  return application->priv->menubar_path;
+}
+
 #endif
 
 #ifdef GDK_WINDOWING_QUARTZ
@@ -535,26 +619,6 @@ extract_accels_from_menu (GMenuModel     *model,
 }
 
 static void
-gtk_application_notify (GObject    *object,
-                        GParamSpec *pspec)
-{
-  if (strcmp (pspec->name, "app-menu") == 0 ||
-      strcmp (pspec->name, "menubar") == 0)
-    {
-      GMenuModel *model;
-      g_object_get (object, pspec->name, &model, NULL);
-      if (model)
-        {
-          extract_accels_from_menu (model, GTK_APPLICATION (object));
-          g_object_unref (model);
-        }
-    }
-
-  if (G_OBJECT_CLASS (gtk_application_parent_class)->notify)
-    G_OBJECT_CLASS (gtk_application_parent_class)->notify (object, pspec);
-}
-
-static void
 gtk_application_get_property (GObject    *object,
                               guint       prop_id,
                               GValue     *value,
@@ -568,6 +632,14 @@ gtk_application_get_property (GObject    *object,
       g_value_set_boolean (value, application->priv->register_session);
       break;
 
+    case PROP_APP_MENU:
+      g_value_set_object (value, gtk_application_get_app_menu (application));
+      break;
+
+    case PROP_MENUBAR:
+      g_value_set_object (value, gtk_application_get_menubar (application));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -588,6 +660,14 @@ gtk_application_set_property (GObject      *object,
       application->priv->register_session = g_value_get_boolean (value);
       break;
 
+    case PROP_APP_MENU:
+      gtk_application_set_app_menu (application, g_value_get_object (value));
+      break;
+
+    case PROP_MENUBAR:
+      gtk_application_set_menubar (application, g_value_get_object (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -602,6 +682,18 @@ gtk_application_quit (GtkApplication *app)
 }
 
 static void
+gtk_application_finalize (GObject *object)
+{
+  GtkApplication *application = GTK_APPLICATION (object);
+
+  g_clear_object (&application->priv->app_menu);
+  g_clear_object (&application->priv->menubar);
+
+  G_OBJECT_CLASS (gtk_application_parent_class)
+    ->finalize (object);
+}
+
+static void
 gtk_application_class_init (GtkApplicationClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -609,7 +701,7 @@ gtk_application_class_init (GtkApplicationClass *class)
 
   object_class->get_property = gtk_application_get_property;
   object_class->set_property = gtk_application_set_property;
-  object_class->notify = gtk_application_notify;
+  object_class->finalize = gtk_application_finalize;
 
   application_class->add_platform_data = gtk_application_add_platform_data;
   application_class->before_emit = gtk_application_before_emit;
@@ -698,6 +790,20 @@ gtk_application_class_init (GtkApplicationClass *class)
                           P_("Register session"),
                           P_("Register with the session manager"),
                           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_APP_MENU,
+    g_param_spec_object ("app-menu",
+                         P_("Application menu"),
+                         P_("The GMenuModel for the application menu"),
+                         G_TYPE_MENU_MODEL,
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_MENUBAR,
+    g_param_spec_object ("menubar",
+                         P_("Menubar"),
+                         P_("The GMenuModel for the menubar"),
+                         G_TYPE_MENU_MODEL,
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 /**
@@ -918,7 +1024,7 @@ gtk_application_remove_accelerator (GtkApplication *application,
 /**
  * gtk_application_set_app_menu:
  * @application: a #GtkApplication
- * @model: (allow-none): a #GMenuModel, or %NULL
+ * @app_menu: (allow-none): a #GMenuModel, or %NULL
  *
  * Sets or unsets the application menu for @application.
  *
@@ -935,9 +1041,28 @@ gtk_application_remove_accelerator (GtkApplication *application,
  */
 void
 gtk_application_set_app_menu (GtkApplication *application,
-                              GMenuModel     *model)
+                              GMenuModel     *app_menu)
 {
-  g_object_set (application, "app-menu", model, NULL);
+  g_return_if_fail (GTK_IS_APPLICATION (application));
+
+  if (app_menu != application->priv->app_menu)
+    {
+      if (application->priv->app_menu != NULL)
+        g_object_unref (application->priv->app_menu);
+
+      application->priv->app_menu = app_menu;
+
+      if (application->priv->app_menu != NULL)
+        g_object_ref (application->priv->app_menu);
+
+      extract_accels_from_menu (app_menu, application);
+
+#ifdef GDK_WINDOWING_X11
+      gtk_application_set_app_menu_x11 (application, app_menu);
+#endif
+
+      g_object_notify (G_OBJECT (application), "app-menu");
+    }
 }
 
 /**
@@ -954,20 +1079,15 @@ gtk_application_set_app_menu (GtkApplication *application,
 GMenuModel *
 gtk_application_get_app_menu (GtkApplication *application)
 {
-  GMenuModel *app_menu = NULL;
-
-  g_object_get (application, "app-menu", &app_menu, NULL);
-
-  if (app_menu)
-    g_object_unref (app_menu);
+  g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
 
-  return app_menu;
+  return application->priv->app_menu;
 }
 
 /**
  * gtk_application_set_menubar:
  * @application: a #GtkApplication
- * @model: (allow-none): a #GMenuModel, or %NULL
+ * @menubar: (allow-none): a #GMenuModel, or %NULL
  *
  * Sets or unsets the menubar for windows of @application.
  *
@@ -985,9 +1105,28 @@ gtk_application_get_app_menu (GtkApplication *application)
  */
 void
 gtk_application_set_menubar (GtkApplication *application,
-                             GMenuModel     *model)
+                             GMenuModel     *menubar)
 {
-  g_object_set (application, "menubar", model, NULL);
+  g_return_if_fail (GTK_IS_APPLICATION (application));
+
+  if (menubar != application->priv->menubar)
+    {
+      if (application->priv->menubar != NULL)
+        g_object_unref (application->priv->menubar);
+
+      application->priv->menubar = menubar;
+
+      if (application->priv->menubar != NULL)
+        g_object_ref (application->priv->menubar);
+
+      extract_accels_from_menu (menubar, application);
+
+#ifdef GDK_WINDOWING_X11
+      gtk_application_set_menubar_x11 (application, menubar);
+#endif
+
+      g_object_notify (G_OBJECT (application), "menubar");
+    }
 }
 
 /**
@@ -1004,14 +1143,9 @@ gtk_application_set_menubar (GtkApplication *application,
 GMenuModel *
 gtk_application_get_menubar (GtkApplication *application)
 {
-  GMenuModel *menubar = NULL;
-
-  g_object_get (application, "menubar", &menubar, NULL);
-
-  if (menubar)
-    g_object_unref (menubar);
+  g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
 
-  return menubar;
+  return application->priv->menubar;
 }
 
 #if defined(GDK_WINDOWING_X11)
diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h
index 878a9a1..b9a9ad7 100644
--- a/gtk/gtkapplication.h
+++ b/gtk/gtkapplication.h
@@ -79,11 +79,11 @@ GList *          gtk_application_get_windows   (GtkApplication    *application);
 
 GMenuModel *     gtk_application_get_app_menu  (GtkApplication    *application);
 void             gtk_application_set_app_menu  (GtkApplication    *application,
-                                                GMenuModel        *model);
+                                                GMenuModel        *app_menu);
 
 GMenuModel *     gtk_application_get_menubar   (GtkApplication    *application);
 void             gtk_application_set_menubar   (GtkApplication    *application,
-                                                GMenuModel        *model);
+                                                GMenuModel        *menubar);
 
 void             gtk_application_add_accelerator    (GtkApplication  *application,
                                                      const gchar     *accelerator,
diff --git a/gtk/gtkapplicationprivate.h b/gtk/gtkapplicationprivate.h
index b2b9b9c..4b24a53 100644
--- a/gtk/gtkapplicationprivate.h
+++ b/gtk/gtkapplicationprivate.h
@@ -38,5 +38,11 @@ G_GNUC_INTERNAL
 GSimpleActionObserver * gtk_application_window_create_observer          (GtkApplicationWindow *window,
                                                                          const gchar          *action_name,
                                                                          GVariant             *target);
+G_GNUC_INTERNAL
+const gchar *           gtk_application_get_dbus_object_path            (GtkApplication       *application);
+G_GNUC_INTERNAL
+const gchar *           gtk_application_get_app_menu_object_path        (GtkApplication       *application);
+G_GNUC_INTERNAL
+const gchar *           gtk_application_get_menubar_object_path         (GtkApplication       *application);
 
 #endif /* __GTK_APPLICATION_PRIVATE_H__ */
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index 555db91..9a7aa35 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -700,16 +700,23 @@ gtk_application_window_real_realize (GtkWidget *widget)
 
     if (GDK_IS_X11_WINDOW (gdkwindow))
       {
-        const gchar *unique_id;
-        const gchar *app_id;
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APPLICATION_ID",
+                                          g_application_get_application_id (G_APPLICATION (application)));
 
-        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_OBJECT_PATH", window->priv->object_path);
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_UNIQUE_BUS_NAME",
+                                          g_dbus_connection_get_unique_name (window->priv->session));
 
-        unique_id = g_dbus_connection_get_unique_name (window->priv->session);
-        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_UNIQUE_NAME", unique_id);
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APPLICATION_OBJECT_PATH",
+                                          gtk_application_get_dbus_object_path (application));
 
-        app_id = g_application_get_application_id (G_APPLICATION (application));
-        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_APPLICATION_ID", app_id);
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_WINDOW_OBJECT_PATH",
+                                          window->priv->object_path);
+
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_APP_MENU_OBJECT_PATH",
+                                          gtk_application_get_app_menu_object_path (application));
+
+        gdk_x11_window_set_utf8_property (gdkwindow, "_GTK_MENUBAR_OBJECT_PATH",
+                                          gtk_application_get_menubar_object_path (application));
       }
   }
 #endif



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