[gtk+] GtkApplication: export windows on the bus
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkApplication: export windows on the bus
- Date: Mon, 19 Dec 2011 18:01:57 +0000 (UTC)
commit 90fcf994d51634f1ec640c388724e9858ceff432
Author: Ryan Lortie <desrt desrt ca>
Date: Mon Dec 5 00:27:11 2011 -0500
GtkApplication: export windows on the bus
And advertise their location on the bus using X11 properties.
gtk/gtkapplication.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkwindow.c | 17 ------
2 files changed, 151 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index 1d1bba9..43e891b 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -30,7 +30,7 @@
#include "gtkapplication.h"
#include "gtkmarshalers.h"
#include "gtkmain.h"
-#include "gtkwindow.h"
+#include "gtkapplicationwindow.h"
#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_X11
@@ -76,8 +76,142 @@ G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
struct _GtkApplicationPrivate
{
GList *windows;
+
+#ifdef GDK_WINDOWING_X11
+ GDBusConnection *session;
+ gchar *window_prefix;
+ guint next_id;
+#endif
};
+#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)));
+
+ /* ...but we want to know when it is. */
+ g_signal_connect (window, "realize", G_CALLBACK (gtk_application_window_realized_x11), application);
+
+ info = g_slice_new (GtkApplicationWindowInfo);
+ do
+ {
+ gchar *window_path;
+
+ 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);
+ }
+ 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);
+}
+
+static gchar *
+window_prefix_from_appid (const gchar *appid)
+{
+ gchar *appid_path, *iter;
+
+ appid_path = g_strconcat ("/", appid, "/windows/", NULL);
+ for (iter = appid_path; *iter; iter++)
+ {
+ if (*iter == '.')
+ *iter = '/';
+
+ if (*iter == '-')
+ *iter = '_';
+ }
+
+ return appid_path;
+}
+
+static void
+gtk_application_startup_x11 (GtkApplication *application)
+{
+ const gchar *application_id;
+
+ application_id = g_application_get_application_id (G_APPLICATION (application));
+ application->priv->session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ application->priv->window_prefix = window_prefix_from_appid (application_id);
+}
+
+static void
+gtk_application_shutdown_x11 (GtkApplication *application)
+{
+ g_free (application->priv->window_prefix);
+ application->priv->window_prefix = NULL;
+ application->priv->session = NULL;
+}
+#endif
+
static gboolean
gtk_application_focus_in_event_cb (GtkWindow *window,
GdkEventFocus *event,
@@ -104,11 +238,19 @@ gtk_application_startup (GApplication *application)
->startup (application);
gtk_init (0, 0);
+
+#ifdef GDK_WINDOWING_X11
+ gtk_application_startup_x11 (GTK_APPLICATION (application));
+#endif
}
static void
gtk_application_shutdown (GApplication *application)
{
+#ifdef GDK_WINDOWING_X11
+ gtk_application_shutdown_x11 (GTK_APPLICATION (application));
+#endif
+
G_APPLICATION_CLASS (gtk_application_parent_class)
->shutdown (application);
}
@@ -179,6 +321,10 @@ gtk_application_window_added (GtkApplication *application,
g_signal_connect (window, "focus-in-event",
G_CALLBACK (gtk_application_focus_in_event_cb),
application);
+
+#ifdef GDK_WINDOWING_X11
+ gtk_application_window_added_x11 (application, window);
+#endif
}
static void
@@ -187,6 +333,10 @@ gtk_application_window_removed (GtkApplication *application,
{
GtkApplicationPrivate *priv = application->priv;
+#ifdef GDK_WINDOWING_X11
+ gtk_application_window_removed_x11 (application, window);
+#endif
+
g_signal_handlers_disconnect_by_func (window,
gtk_application_focus_in_event_cb,
application);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 0581679..ac7536c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -2681,7 +2681,6 @@ gtk_window_set_application (GtkWindow *window,
GtkApplication *application)
{
GtkWindowPrivate *priv;
- GdkWindow *gdkwindow;
g_return_if_fail (GTK_IS_WINDOW (window));
@@ -2701,22 +2700,6 @@ gtk_window_set_application (GtkWindow *window,
g_object_notify (G_OBJECT (window), "application");
}
-
-#ifdef GDK_WINDOWING_X11
- gdkwindow = gtk_widget_get_window (GTK_WIDGET (window));
- if (gdkwindow)
- {
- if (GDK_IS_X11_WINDOW (gdkwindow))
- {
- const char *id;
- if (application)
- id = g_application_get_application_id ((GApplication*)application);
- else
- id = NULL;
- gdk_x11_window_set_utf8_property (gdkwindow, "_DBUS_APPLICATION_ID", id);
- }
- }
-#endif
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]