[gtk+] Move X property handling to GtkApplicationWindow



commit 76d671d6a2ba44bece238b580728923374393c78
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Dec 17 12:28:30 2011 -0500

    Move X property handling to GtkApplicationWindow
    
    Don't try to deal with this using a qdata and signal connections in
    GtkApplication.

 gtk/Makefile.am            |    1 +
 gtk/gtkapplication.c       |   97 +++++++++++--------------------------------
 gtk/gtkapplicationwindow.c |   72 +++++++++++++++++++++++++++++++-
 3 files changed, 95 insertions(+), 75 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index a5fb322..720f58d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -394,6 +394,7 @@ gtk_private_h_sources =		\
 	gactionmuxer.h		\
 	gactionobserver.h	\
 	gactionobservable.h	\
+	gtkapplicationprivate.h	\
 	gtkaccelgroupprivate.h	\
 	gtkaccelmapprivate.h	\
 	gtkanimationdescription.h \
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index 5cc5272..1b5f2a6 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -21,16 +21,17 @@
 
 #include "config.h"
 
+#include "gtkapplication.h"
+
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <string.h>
 
-#include "gtkapplication.h"
+#include "gtkapplicationprivate.h"
 #include "gtkmarshalers.h"
 #include "gtkmain.h"
-#include "gtkapplicationwindow.h"
 #include "gtkaccelmapprivate.h"
 #include "gactionmuxer.h"
 
@@ -113,94 +114,46 @@ struct _GtkApplicationPrivate
 };
 
 #ifdef GDK_WINDOWING_X11
-typedef struct
-{
-  guint action_export_id;
-  guint window_id;
-} GtkApplicationWindowInfo;
-
-static void
-gtk_application_window_realized_x11 (GtkWindow *window,
-                                     gpointer   user_data)
-{
-  GtkApplication *application = user_data;
-  GtkApplicationWindowInfo *info;
-  GdkWindow *gdkwindow;
-  gchar *window_path;
-  const gchar *unique_id;
-  const gchar *app_id;
-
-  gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
-
-  if (!GDK_IS_X11_WINDOW (gdkwindow))
-    return;
-
-  info = g_object_get_data (G_OBJECT (window), "GtkApplication::window-info");
-
-  window_path = g_strdup_printf ("%s%d", application->priv->window_prefix, info->window_id);
-  gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_OBJECT_PATH", window_path);
-  g_free (window_path);
-
-  unique_id = g_dbus_connection_get_unique_name (application->priv->session);
-  gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_UNIQUE_NAME", unique_id);
-
-  app_id = g_application_get_application_id (G_APPLICATION (application));
-  gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_APPLICATION_ID", app_id);
-}
-
 static void
 gtk_application_window_added_x11 (GtkApplication *application,
                                   GtkWindow      *window)
 {
-  GtkApplicationWindowInfo *info;
-
   if (application->priv->session == NULL)
     return;
 
-  if (!GTK_IS_APPLICATION_WINDOW (window))
-    return;
-
-  /* GtkApplicationWindow associates with us when it is first created,
-   * so surely it's not realized yet...
-   */
-  g_assert (!gtk_widget_get_realized (GTK_WIDGET (window)));
+  if (GTK_IS_APPLICATION_WINDOW (window))
+    {
+      GtkApplicationWindow *app_window = GTK_APPLICATION_WINDOW (window);
+      gboolean success;
 
-  /* ...but we want to know when it is. */
-  g_signal_connect (window, "realize", G_CALLBACK (gtk_application_window_realized_x11), application);
+      /* GtkApplicationWindow associates with us when it is first created,
+       * so surely it's not realized yet...
+       */
+      g_assert (!gtk_widget_get_realized (GTK_WIDGET (window)));
 
-  info = g_slice_new (GtkApplicationWindowInfo);
-  do
-    {
-      gchar *window_path;
+      do
+        {
+          gchar *window_path;
+          guint window_id;
 
-      info->window_id = application->priv->next_id++;
-      window_path = g_strdup_printf ("%s%d", application->priv->window_prefix, info->window_id);
-      info->action_export_id = g_dbus_connection_export_action_group (application->priv->session, window_path,
-                                                                      G_ACTION_GROUP (window), NULL);
-      g_free (window_path);
+          window_id = application->priv->next_id++;
+          window_path = g_strdup_printf ("%s%d", application->priv->window_prefix, window_id);
+          success = gtk_application_window_publish (app_window, application->priv->session, window_path);
+          g_free (window_path);
+        }
+      while (!success);
     }
-  while (!info->action_export_id);
-
-  g_object_set_data (G_OBJECT (window), "GtkApplication::window-info", info);
 }
 
 static void
 gtk_application_window_removed_x11 (GtkApplication *application,
                                     GtkWindow      *window)
 {
-  GtkApplicationWindowInfo *info;
-
   if (application->priv->session == NULL)
     return;
 
-  if (!GTK_IS_APPLICATION_WINDOW (window))
-    return;
-
-  info = g_object_steal_data (G_OBJECT (window), "GtkApplication::window-info");
-
-  g_dbus_connection_unexport_action_group (application->priv->session, info->action_export_id);
-
-  g_slice_free (GtkApplicationWindowInfo, info);
+  if (GTK_IS_APPLICATION_WINDOW (window))
+    gtk_application_window_unpublish (GTK_APPLICATION_WINDOW (window));
 }
 
 static gchar *
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index cb4ed3d..fb9e513 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -23,12 +23,18 @@
 
 #include "gtkapplicationwindow.h"
 
+#include "gtkapplicationprivate.h"
 #include "gtkmodelmenu.h"
 #include "gactionmuxer.h"
 #include "gtkaccelgroup.h"
 #include "gtkaccelmap.h"
 #include "gtkintl.h"
 
+#include <gdk/gdk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/x11/gdkx.h>
+#endif
+
 /**
  * SECTION:gtkapplicationwindow
  * @title: GtkApplicationWindow
@@ -98,6 +104,10 @@ struct _GtkApplicationWindowPrivate
   GMenu *app_menu_section;
   GMenu *menubar_section;
   gboolean show_menubar;
+
+  GDBusConnection *session;
+  gchar           *object_path;
+  guint            export_id;
 };
 
 static void
@@ -565,8 +575,10 @@ static void
 gtk_application_window_real_realize (GtkWidget *widget)
 {
   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
+  GtkApplication *application;
   GtkSettings *settings;
 
+  application = gtk_window_get_application (GTK_WINDOW (window));
   settings = gtk_widget_get_settings (widget);
 
   g_signal_connect (settings, "notify::gtk-shell-shows-app-menu",
@@ -576,11 +588,8 @@ gtk_application_window_real_realize (GtkWidget *widget)
 
   if (window->priv->muxer == NULL)
     {
-      GtkApplication *application;
       GActionMuxer *muxer;
 
-      application = gtk_window_get_application (GTK_WINDOW (window));
-
       muxer = g_action_muxer_new ();
       g_action_muxer_insert (muxer, "app", G_ACTION_GROUP (application));
       g_action_muxer_insert (muxer, "win", G_ACTION_GROUP (window));
@@ -594,6 +603,28 @@ gtk_application_window_real_realize (GtkWidget *widget)
 
   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
     ->realize (widget);
+
+#ifdef GDK_WINDOWING_X11
+  {
+    GdkWindow *gdkwindow;
+
+    gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
+
+    if (GDK_IS_X11_WINDOW (gdkwindow))
+      {
+        const gchar *unique_id;
+        const gchar *app_id;
+
+        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_OBJECT_PATH", window->priv->object_path);
+
+        unique_id = g_dbus_connection_get_unique_name (window->priv->session);
+        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_UNIQUE_NAME", unique_id);
+
+        app_id = g_application_get_application_id (G_APPLICATION (application));
+        gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_APPLICATION_ID", app_id);
+      }
+  }
+#endif
 }
 
 static void
@@ -610,6 +641,41 @@ gtk_application_window_real_unrealize (GtkWidget *widget)
     ->unrealize (widget);
 }
 
+gboolean
+gtk_application_window_publish (GtkApplicationWindow *window,
+                                GDBusConnection      *session,
+                                const gchar          *object_path)
+{
+  g_assert (window->priv->session == NULL);
+  g_assert (window->priv->export_id == 0);
+  g_assert (window->priv->object_path == NULL);
+
+  window->priv->export_id = g_dbus_connection_export_action_group (session, object_path, G_ACTION_GROUP (window), NULL);
+
+  if (window->priv->export_id == 0)
+    return FALSE;
+
+  window->priv->session = session;
+  window->priv->object_path = g_strdup (object_path);
+
+  return TRUE;
+}
+
+void
+gtk_application_window_unpublish (GtkApplicationWindow *window)
+{
+  g_assert (window->priv->session != NULL);
+  g_assert (window->priv->export_id != 0);
+  g_assert (window->priv->object_path != NULL);
+
+  g_dbus_connection_unexport_action_group (window->priv->session, window->priv->export_id);
+  window->priv->session = NULL;
+  window->priv->export_id = 0;
+
+  g_free (window->priv->object_path);
+  window->priv->object_path = NULL;
+}
+
 static void
 gtk_application_window_real_map (GtkWidget *widget)
 {



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