From 1a450e2613d2b1c604df5c0c83786a679eda0268 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 23 Jun 2009 16:51:28 -0500 Subject: Okay, being a little funny with how these things are playing out. Missing subversion's crazy everything is a copy semantics right now. It works well for stuff like this. --- libdbusmenu-gtk/client.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 libdbusmenu-gtk/client.c (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c new file mode 100644 index 0000000..4074947 --- /dev/null +++ b/libdbusmenu-gtk/client.c @@ -0,0 +1,332 @@ +/* +A library to take the object model made consistent by libdbusmenu-glib +and visualize it in GTK. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "menu.h" +#include "libdbusmenu-glib/client.h" + +/* Properties */ +enum { + PROP_0, + PROP_DBUSOBJECT, + PROP_DBUSNAME +}; + +/* Private */ +typedef struct _DbusmenuGtkMenuPrivate DbusmenuGtkMenuPrivate; +struct _DbusmenuGtkMenuPrivate { + DbusmenuClient * client; + + gchar * dbus_object; + gchar * dbus_name; +}; + +#define DBUSMENU_GTKMENU_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_GTKMENU_TYPE, DbusmenuGtkMenuPrivate)) + +/* Prototypes */ +static void dbusmenu_gtkmenu_class_init (DbusmenuGtkMenuClass *klass); +static void dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self); +static void dbusmenu_gtkmenu_dispose (GObject *object); +static void dbusmenu_gtkmenu_finalize (GObject *object); +static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); +static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); +/* Internal */ +static void build_client (DbusmenuGtkMenu * self); + +/* GObject Stuff */ +G_DEFINE_TYPE (DbusmenuGtkMenu, dbusmenu_gtkmenu, GTK_TYPE_MENU); + +static void +dbusmenu_gtkmenu_class_init (DbusmenuGtkMenuClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (DbusmenuGtkMenuPrivate)); + + object_class->dispose = dbusmenu_gtkmenu_dispose; + object_class->finalize = dbusmenu_gtkmenu_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + + g_object_class_install_property (object_class, PROP_DBUSOBJECT, + g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", + "The Object on the client that we're getting our data from.", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_DBUSNAME, + g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_NAME, "DBus Client we connect to", + "Name of the DBus client we're connecting to.", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + return; +} + +static void +dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(self); + + priv->client = NULL; + + priv->dbus_object = NULL; + priv->dbus_name = NULL; + + return; +} + +static void +dbusmenu_gtkmenu_dispose (GObject *object) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(object); + + if (priv->client != NULL) { + g_object_unref(G_OBJECT(priv->client)); + priv->client = NULL; + } + + G_OBJECT_CLASS (dbusmenu_gtkmenu_parent_class)->dispose (object); + return; +} + +static void +dbusmenu_gtkmenu_finalize (GObject *object) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(object); + + g_free(priv->dbus_object); + priv->dbus_object = NULL; + + g_free(priv->dbus_name); + priv->dbus_name = NULL; + + G_OBJECT_CLASS (dbusmenu_gtkmenu_parent_class)->finalize (object); + return; +} + +static void +set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(obj); + + switch (id) { + case PROP_DBUSNAME: + priv->dbus_name = g_value_dup_string(value); + if (priv->dbus_name != NULL && priv->dbus_object != NULL) { + build_client(DBUSMENU_GTKMENU(obj)); + } + break; + case PROP_DBUSOBJECT: + priv->dbus_object = g_value_dup_string(value); + if (priv->dbus_name != NULL && priv->dbus_object != NULL) { + build_client(DBUSMENU_GTKMENU(obj)); + } + break; + default: + g_warning("Unknown property %d.", id); + return; + } + + return; +} + +static void +get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(obj); + + switch (id) { + case PROP_DBUSNAME: + g_value_set_string(value, priv->dbus_name); + break; + case PROP_DBUSOBJECT: + g_value_set_string(value, priv->dbus_object); + break; + default: + g_warning("Unknown property %d.", id); + return; + } + + return; +} + +/* Internal Functions */ + +static const gchar * data_menuitem = "dbusmenugtk-data-gtkmenuitem"; +static const gchar * data_menu = "dbusmenugtk-data-gtkmenu"; + +static gboolean +menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi) +{ + dbusmenu_menuitem_activate(mi); + return TRUE; +} + +static void +menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, GtkMenuItem * gmi) +{ + if (!g_strcmp0(prop, "label")) { + gtk_menu_item_set_label(gmi, value); + gtk_widget_show(GTK_WIDGET(gmi)); + } + + return; +} + +static void +destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem) +{ + /* g_debug("DbusmenuMenuitem was destroyed"); */ + gtk_widget_destroy(GTK_WIDGET(udata)); + return; +} + +static void +connect_menuitem (DbusmenuMenuitem * mi, GtkMenuItem * gmi) +{ + g_object_set_data(G_OBJECT(mi), data_menuitem, gmi); + + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi); + g_signal_connect(G_OBJECT(gmi), "activate", G_CALLBACK(menu_pressed_cb), mi); + + g_object_weak_ref(G_OBJECT(mi), destoryed_dbusmenuitem_cb, gmi); + + return; +} + +static void +process_dbusmenu_menuitem (DbusmenuMenuitem * mi, GtkMenu * parentmenu) +{ + gpointer unknown_menuitem = g_object_get_data(G_OBJECT(mi), data_menuitem); + if (unknown_menuitem == NULL) { + /* Oh, a virgin DbusmenuMenuitem, let's fix that. */ + GtkWidget * menuitem = gtk_menu_item_new(); + connect_menuitem(mi, GTK_MENU_ITEM(menuitem)); + unknown_menuitem = menuitem; + gtk_menu_shell_append(GTK_MENU_SHELL(parentmenu), menuitem); + } + + GList * children = dbusmenu_menuitem_get_children(mi); + if (children == NULL) { + /* If there are no children to process we are + done and we can move along */ + return; + } + + /* Phase 0: Make a submenu if we don't have one */ + gpointer unknown_menu = g_object_get_data(G_OBJECT(mi), data_menu); + if (unknown_menu == NULL) { + GtkWidget * gtkmenu = gtk_menu_new(); + g_object_ref(gtkmenu); + g_object_set_data_full(G_OBJECT(mi), data_menu, gtkmenu, g_object_unref); + unknown_menu = gtkmenu; + gtk_menu_item_set_submenu(GTK_MENU_ITEM(unknown_menuitem), gtkmenu); + gtk_widget_show(gtkmenu); + } + + /* Phase 1: Add missing children */ + GList * child = NULL; + for (child = children; child != NULL; child = g_list_next(child)) { + process_dbusmenu_menuitem(DBUSMENU_MENUITEM(child->data), GTK_MENU(unknown_menu)); + } + + /* Phase 2: Delete removed children */ + /* Actually, we don't need to do this because of the weak + reference that we've added above. When the DbusmenuMenuitem + gets destroyed it takes its GtkMenuItem with it. Bye bye. */ + + /* Phase 3: Profit! */ + return; +} + +/* Processing the layout being updated and handling + that and making it into a menu */ +static void +process_layout_change (DbusmenuClient * client, DbusmenuGtkMenu * gtkmenu) +{ + DbusmenuMenuitem * root = dbusmenu_client_get_root(client); + + GList * children = dbusmenu_menuitem_get_children(root); + if (children == NULL) { + return; + } + + GList * child = NULL; + for (child = children; child != NULL; child = g_list_next(child)) { + process_dbusmenu_menuitem(DBUSMENU_MENUITEM(child->data), GTK_MENU(gtkmenu)); + } + + return; +} + + +/* Builds the client and connects all of the signals + up for it so that it's happy-happy */ +static void +build_client (DbusmenuGtkMenu * self) +{ + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(self); + + if (priv->client == NULL) { + priv->client = dbusmenu_client_new(priv->dbus_name, priv->dbus_object); + + /* Register for layout changes, this should come after the + creation of the client pulls it from DBus */ + g_signal_connect(G_OBJECT(priv->client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(process_layout_change), self); + } + + return; +} + +/* Public API */ + +/** + dbusmenu_gtkmenu_new: + @dbus_name: Name of the #DbusmenuServer on DBus + @dbus_name: Name of the object on the #DbusmenuServer + + Creates a new #DbusmenuGtkMenu object and creates a #DbusmenuClient + that connects across DBus to a #DbusmenuServer. + + Return value: A new #DbusmenuGtkMenu sync'd with a server +*/ +DbusmenuGtkMenu * +dbusmenu_gtkmenu_new (gchar * dbus_name, gchar * dbus_object) +{ + return g_object_new(DBUSMENU_GTKMENU_TYPE, + DBUSMENU_CLIENT_PROP_DBUS_OBJECT, dbus_object, + DBUSMENU_CLIENT_PROP_DBUS_NAME, dbus_name, + NULL); +} + -- cgit v1.2.3 From ef09b6addc6fe5df82f3fded6f7b4b86377ef37f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 23 Jun 2009 22:58:59 -0500 Subject: Okay, now we're rebuilding this client thingy. --- libdbusmenu-gtk/client.c | 70 ++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 4074947..8ee1718 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -43,39 +43,39 @@ enum { }; /* Private */ -typedef struct _DbusmenuGtkMenuPrivate DbusmenuGtkMenuPrivate; -struct _DbusmenuGtkMenuPrivate { +typedef struct _DbusmenuGtkClientPrivate DbusmenuGtkClientPrivate; +struct _DbusmenuGtkClientPrivate { DbusmenuClient * client; gchar * dbus_object; gchar * dbus_name; }; -#define DBUSMENU_GTKMENU_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_GTKMENU_TYPE, DbusmenuGtkMenuPrivate)) +#define DBUSMENU_GTKCLIENT_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_GTKCLIENT_TYPE, DbusmenuGtkClientPrivate)) /* Prototypes */ -static void dbusmenu_gtkmenu_class_init (DbusmenuGtkMenuClass *klass); -static void dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self); -static void dbusmenu_gtkmenu_dispose (GObject *object); -static void dbusmenu_gtkmenu_finalize (GObject *object); +static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass); +static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self); +static void dbusmenu_gtkclient_dispose (GObject *object); +static void dbusmenu_gtkclient_finalize (GObject *object); static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Internal */ -static void build_client (DbusmenuGtkMenu * self); +static void build_client (DbusmenuGtkClient * self); /* GObject Stuff */ -G_DEFINE_TYPE (DbusmenuGtkMenu, dbusmenu_gtkmenu, GTK_TYPE_MENU); +G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); static void -dbusmenu_gtkmenu_class_init (DbusmenuGtkMenuClass *klass) +dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (DbusmenuGtkMenuPrivate)); + g_type_class_add_private (klass, sizeof (DbusmenuGtkClientPrivate)); - object_class->dispose = dbusmenu_gtkmenu_dispose; - object_class->finalize = dbusmenu_gtkmenu_finalize; + object_class->dispose = dbusmenu_gtkclient_dispose; + object_class->finalize = dbusmenu_gtkclient_finalize; object_class->set_property = set_property; object_class->get_property = get_property; @@ -94,9 +94,9 @@ dbusmenu_gtkmenu_class_init (DbusmenuGtkMenuClass *klass) } static void -dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self) +dbusmenu_gtkclient_init (DbusmenuGtkClient *self) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(self); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(self); priv->client = NULL; @@ -107,23 +107,23 @@ dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self) } static void -dbusmenu_gtkmenu_dispose (GObject *object) +dbusmenu_gtkclient_dispose (GObject *object) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(object); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(object); if (priv->client != NULL) { g_object_unref(G_OBJECT(priv->client)); priv->client = NULL; } - G_OBJECT_CLASS (dbusmenu_gtkmenu_parent_class)->dispose (object); + G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->dispose (object); return; } static void -dbusmenu_gtkmenu_finalize (GObject *object) +dbusmenu_gtkclient_finalize (GObject *object) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(object); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(object); g_free(priv->dbus_object); priv->dbus_object = NULL; @@ -131,26 +131,26 @@ dbusmenu_gtkmenu_finalize (GObject *object) g_free(priv->dbus_name); priv->dbus_name = NULL; - G_OBJECT_CLASS (dbusmenu_gtkmenu_parent_class)->finalize (object); + G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->finalize (object); return; } static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(obj); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(obj); switch (id) { case PROP_DBUSNAME: priv->dbus_name = g_value_dup_string(value); if (priv->dbus_name != NULL && priv->dbus_object != NULL) { - build_client(DBUSMENU_GTKMENU(obj)); + build_client(DBUSMENU_GTKCLIENT(obj)); } break; case PROP_DBUSOBJECT: priv->dbus_object = g_value_dup_string(value); if (priv->dbus_name != NULL && priv->dbus_object != NULL) { - build_client(DBUSMENU_GTKMENU(obj)); + build_client(DBUSMENU_GTKCLIENT(obj)); } break; default: @@ -164,7 +164,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(obj); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(obj); switch (id) { case PROP_DBUSNAME: @@ -273,7 +273,7 @@ process_dbusmenu_menuitem (DbusmenuMenuitem * mi, GtkMenu * parentmenu) /* Processing the layout being updated and handling that and making it into a menu */ static void -process_layout_change (DbusmenuClient * client, DbusmenuGtkMenu * gtkmenu) +process_layout_change (DbusmenuClient * client, DbusmenuGtkClient * gtkmenu) { DbusmenuMenuitem * root = dbusmenu_client_get_root(client); @@ -294,9 +294,9 @@ process_layout_change (DbusmenuClient * client, DbusmenuGtkMenu * gtkmenu) /* Builds the client and connects all of the signals up for it so that it's happy-happy */ static void -build_client (DbusmenuGtkMenu * self) +build_client (DbusmenuGtkClient * self) { - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(self); + DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(self); if (priv->client == NULL) { priv->client = dbusmenu_client_new(priv->dbus_name, priv->dbus_object); @@ -312,19 +312,19 @@ build_client (DbusmenuGtkMenu * self) /* Public API */ /** - dbusmenu_gtkmenu_new: + dbusmenu_gtkclient_new: @dbus_name: Name of the #DbusmenuServer on DBus @dbus_name: Name of the object on the #DbusmenuServer - Creates a new #DbusmenuGtkMenu object and creates a #DbusmenuClient + Creates a new #DbusmenuGtkClient object and creates a #DbusmenuClient that connects across DBus to a #DbusmenuServer. - Return value: A new #DbusmenuGtkMenu sync'd with a server + Return value: A new #DbusmenuGtkClient sync'd with a server */ -DbusmenuGtkMenu * -dbusmenu_gtkmenu_new (gchar * dbus_name, gchar * dbus_object) +DbusmenuGtkClient * +dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object) { - return g_object_new(DBUSMENU_GTKMENU_TYPE, + return g_object_new(DBUSMENU_GTKCLIENT_TYPE, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, dbus_object, DBUSMENU_CLIENT_PROP_DBUS_NAME, dbus_name, NULL); -- cgit v1.2.3 From c6967512647c4282ce740ca6e1899e06f1a91453 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 23 Jun 2009 23:05:44 -0500 Subject: Getting rid of code. We don't need properties or to build a cleint. I mean, we are one :) --- libdbusmenu-gtk/client.c | 128 ++--------------------------------------------- 1 file changed, 4 insertions(+), 124 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 8ee1718..6263cea 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -32,37 +32,13 @@ License version 3 and version 2.1 along with this program. If not, see #include -#include "menu.h" -#include "libdbusmenu-glib/client.h" - -/* Properties */ -enum { - PROP_0, - PROP_DBUSOBJECT, - PROP_DBUSNAME -}; - -/* Private */ -typedef struct _DbusmenuGtkClientPrivate DbusmenuGtkClientPrivate; -struct _DbusmenuGtkClientPrivate { - DbusmenuClient * client; - - gchar * dbus_object; - gchar * dbus_name; -}; - -#define DBUSMENU_GTKCLIENT_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_GTKCLIENT_TYPE, DbusmenuGtkClientPrivate)) +#include "client.h" /* Prototypes */ static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass); static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self); static void dbusmenu_gtkclient_dispose (GObject *object); static void dbusmenu_gtkclient_finalize (GObject *object); -static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); -static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); -/* Internal */ -static void build_client (DbusmenuGtkClient * self); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); @@ -72,23 +48,8 @@ dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (DbusmenuGtkClientPrivate)); - object_class->dispose = dbusmenu_gtkclient_dispose; object_class->finalize = dbusmenu_gtkclient_finalize; - object_class->set_property = set_property; - object_class->get_property = get_property; - - g_object_class_install_property (object_class, PROP_DBUSOBJECT, - g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_OBJECT, "DBus Object we represent", - "The Object on the client that we're getting our data from.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_DBUSNAME, - g_param_spec_string(DBUSMENU_CLIENT_PROP_DBUS_NAME, "DBus Client we connect to", - "Name of the DBus client we're connecting to.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); return; } @@ -96,12 +57,6 @@ dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass) static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self) { - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(self); - - priv->client = NULL; - - priv->dbus_object = NULL; - priv->dbus_name = NULL; return; } @@ -109,78 +64,21 @@ dbusmenu_gtkclient_init (DbusmenuGtkClient *self) static void dbusmenu_gtkclient_dispose (GObject *object) { - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(object); - - if (priv->client != NULL) { - g_object_unref(G_OBJECT(priv->client)); - priv->client = NULL; - } G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->dispose (object); return; } +static void process_layout_change (DbusmenuClient * client, DbusmenuGtkClient * gtkmenu); + static void dbusmenu_gtkclient_finalize (GObject *object) { - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(object); - - g_free(priv->dbus_object); - priv->dbus_object = NULL; - - g_free(priv->dbus_name); - priv->dbus_name = NULL; - + process_layout_change(NULL, NULL); G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->finalize (object); return; } -static void -set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) -{ - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(obj); - - switch (id) { - case PROP_DBUSNAME: - priv->dbus_name = g_value_dup_string(value); - if (priv->dbus_name != NULL && priv->dbus_object != NULL) { - build_client(DBUSMENU_GTKCLIENT(obj)); - } - break; - case PROP_DBUSOBJECT: - priv->dbus_object = g_value_dup_string(value); - if (priv->dbus_name != NULL && priv->dbus_object != NULL) { - build_client(DBUSMENU_GTKCLIENT(obj)); - } - break; - default: - g_warning("Unknown property %d.", id); - return; - } - - return; -} - -static void -get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) -{ - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(obj); - - switch (id) { - case PROP_DBUSNAME: - g_value_set_string(value, priv->dbus_name); - break; - case PROP_DBUSOBJECT: - g_value_set_string(value, priv->dbus_object); - break; - default: - g_warning("Unknown property %d.", id); - return; - } - - return; -} - /* Internal Functions */ static const gchar * data_menuitem = "dbusmenugtk-data-gtkmenuitem"; @@ -291,24 +189,6 @@ process_layout_change (DbusmenuClient * client, DbusmenuGtkClient * gtkmenu) } -/* Builds the client and connects all of the signals - up for it so that it's happy-happy */ -static void -build_client (DbusmenuGtkClient * self) -{ - DbusmenuGtkClientPrivate * priv = DBUSMENU_GTKCLIENT_GET_PRIVATE(self); - - if (priv->client == NULL) { - priv->client = dbusmenu_client_new(priv->dbus_name, priv->dbus_object); - - /* Register for layout changes, this should come after the - creation of the client pulls it from DBus */ - g_signal_connect(G_OBJECT(priv->client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(process_layout_change), self); - } - - return; -} - /* Public API */ /** -- cgit v1.2.3 From d4503d1336b547db4b8cbdd8de75c01898eceff5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 24 Jun 2009 09:22:00 -0500 Subject: Major reshuffling, not quite done, but compiles. --- libdbusmenu-gtk/client.c | 93 +++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 53 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 6263cea..9657c28 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -39,6 +39,10 @@ static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass); static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self); static void dbusmenu_gtkclient_dispose (GObject *object); static void dbusmenu_gtkclient_finalize (GObject *object); +static void new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata); +static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpointer userdata); +static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata); +static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, gpointer userdata); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); @@ -57,7 +61,7 @@ dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass) static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self) { - + g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM, G_CALLBACK(new_menuitem), NULL); return; } @@ -69,12 +73,10 @@ dbusmenu_gtkclient_dispose (GObject *object) return; } -static void process_layout_change (DbusmenuClient * client, DbusmenuGtkClient * gtkmenu); - static void dbusmenu_gtkclient_finalize (GObject *object) { - process_layout_change(NULL, NULL); + G_OBJECT_CLASS (dbusmenu_gtkclient_parent_class)->finalize (object); return; } @@ -84,6 +86,8 @@ dbusmenu_gtkclient_finalize (GObject *object) static const gchar * data_menuitem = "dbusmenugtk-data-gtkmenuitem"; static const gchar * data_menu = "dbusmenugtk-data-gtkmenu"; +/* This is the call back for the GTK widget for when it gets + clicked on by the user to send it back across the bus. */ static gboolean menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi) { @@ -91,6 +95,8 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi) return TRUE; } +/* Whenever we have a property change on a DbusmenuMenuitem + we need to be responsive to that. */ static void menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, GtkMenuItem * gmi) { @@ -102,6 +108,9 @@ menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, gchar * value, GtkMenu return; } +/* Call back that happens when the DbusmenuMenuitem + is destroyed. We're making sure to clean up everything + else down the pipe. */ static void destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem) { @@ -110,85 +119,63 @@ destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem) return; } +/* This takes a new DbusmenuMenuitem and attaches the + various things that we need to make it work in a + GTK World. */ static void -connect_menuitem (DbusmenuMenuitem * mi, GtkMenuItem * gmi) +new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) { + GtkWidget * gmi = gtk_menu_item_new(); + + /* Attach these two */ g_object_set_data(G_OBJECT(mi), data_menuitem, gmi); + /* DbusmenuMenuitem signals */ g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(new_child), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(delete_child), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(move_child), NULL); + + /* GtkMenuitem signals */ g_signal_connect(G_OBJECT(gmi), "activate", G_CALLBACK(menu_pressed_cb), mi); + /* Life insurance */ g_object_weak_ref(G_OBJECT(mi), destoryed_dbusmenuitem_cb, gmi); return; } static void -process_dbusmenu_menuitem (DbusmenuMenuitem * mi, GtkMenu * parentmenu) +new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpointer userdata) { - gpointer unknown_menuitem = g_object_get_data(G_OBJECT(mi), data_menuitem); - if (unknown_menuitem == NULL) { - /* Oh, a virgin DbusmenuMenuitem, let's fix that. */ - GtkWidget * menuitem = gtk_menu_item_new(); - connect_menuitem(mi, GTK_MENU_ITEM(menuitem)); - unknown_menuitem = menuitem; - gtk_menu_shell_append(GTK_MENU_SHELL(parentmenu), menuitem); - } - - GList * children = dbusmenu_menuitem_get_children(mi); - if (children == NULL) { - /* If there are no children to process we are - done and we can move along */ - return; - } + gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); + if (ann_menu == NULL) { + /* Oh, we don't have a submenu, build one! */ - /* Phase 0: Make a submenu if we don't have one */ - gpointer unknown_menu = g_object_get_data(G_OBJECT(mi), data_menu); - if (unknown_menu == NULL) { - GtkWidget * gtkmenu = gtk_menu_new(); - g_object_ref(gtkmenu); - g_object_set_data_full(G_OBJECT(mi), data_menu, gtkmenu, g_object_unref); - unknown_menu = gtkmenu; - gtk_menu_item_set_submenu(GTK_MENU_ITEM(unknown_menuitem), gtkmenu); - gtk_widget_show(gtkmenu); } - /* Phase 1: Add missing children */ - GList * child = NULL; - for (child = children; child != NULL; child = g_list_next(child)) { - process_dbusmenu_menuitem(DBUSMENU_MENUITEM(child->data), GTK_MENU(unknown_menu)); - } + return; +} - /* Phase 2: Delete removed children */ - /* Actually, we don't need to do this because of the weak - reference that we've added above. When the DbusmenuMenuitem - gets destroyed it takes its GtkMenuItem with it. Bye bye. */ +static void +delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata) +{ - /* Phase 3: Profit! */ return; } -/* Processing the layout being updated and handling - that and making it into a menu */ static void -process_layout_change (DbusmenuClient * client, DbusmenuGtkClient * gtkmenu) +move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, gpointer userdata) { - DbusmenuMenuitem * root = dbusmenu_client_get_root(client); - - GList * children = dbusmenu_menuitem_get_children(root); - if (children == NULL) { + gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); + if (ann_menu == NULL) { + g_warning("Moving a child when we don't have a submenu!"); return; } - GList * child = NULL; - for (child = children; child != NULL; child = g_list_next(child)) { - process_dbusmenu_menuitem(DBUSMENU_MENUITEM(child->data), GTK_MENU(gtkmenu)); - } - return; } - /* Public API */ /** -- cgit v1.2.3 From 8d75067ada03ed13fcb183987f8392c18afd4992 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 24 Jun 2009 21:27:10 -0500 Subject: Handling the differing signals to set things up with the various gtk widgets --- libdbusmenu-gtk/client.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 9657c28..99e41bf 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -125,7 +125,16 @@ destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem) static void new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) { - GtkWidget * gmi = gtk_menu_item_new(); + gpointer ann_mi = g_object_get_data(G_OBJECT(mi), data_menuitem); + GtkMenuItem * gmi = GTK_MENU_ITEM(ann_mi); + + if (gmi != NULL) { + /* It's possible we've already been looked at, that's + okay, but we can just ignore this signal then. */ + return; + } + + gmi = GTK_MENU_ITEM(gtk_menu_item_new()); /* Attach these two */ g_object_set_data(G_OBJECT(mi), data_menuitem, gmi); @@ -149,17 +158,34 @@ static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpointer userdata) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); - if (ann_menu == NULL) { + GtkMenu * menu = GTK_MENU(ann_menu); + if (menu == NULL) { /* Oh, we don't have a submenu, build one! */ + menu = GTK_MENU(gtk_menu_new()); + g_object_set_data(G_OBJECT(mi), data_menu, menu); - } + GtkMenuItem * parent = dbusmenu_gtkclient_menuitem_get (mi); + gtk_menu_item_set_submenu(parent, GTK_WIDGET(menu)); + } + GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get (child); + gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position); + return; } static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata) { + if (g_list_length(dbusmenu_menuitem_get_children(mi)) == 0) { + gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); + GtkMenu * menu = GTK_MENU(ann_menu); + + if (menu != NULL) { + gtk_widget_destroy(GTK_WIDGET(menu)); + g_object_set_data(G_OBJECT(mi), data_menu, NULL); + } + } return; } @@ -173,6 +199,9 @@ move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint ol return; } + GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get (child); + gtk_menu_reorder_child(GTK_MENU(ann_menu), GTK_WIDGET(childmi), new); + return; } @@ -197,3 +226,9 @@ dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object) NULL); } +GtkMenuItem * +dbusmenu_gtkclient_menuitem_get (DbusmenuMenuitem * item) +{ + return GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); +} + -- cgit v1.2.3 From 04a9be5019d23590111030196d41fc08ac9cc146 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 24 Jun 2009 21:37:54 -0500 Subject: Some comments for the gtk-doc stuff --- libdbusmenu-gtk/client.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 99e41bf..eae304f 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -226,6 +226,15 @@ dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object) NULL); } +/** + dbusmenu_gtkclient_menuitem_get: + @item: #DbusmenuMenuitem to get associated #GtkMenuItem on. + + This grabs the #GtkMenuItem that is associated with the + #DbusmenuMenuitem. + + Return value: The #GtkMenuItem that can be played with. +*/ GtkMenuItem * dbusmenu_gtkclient_menuitem_get (DbusmenuMenuitem * item) { -- cgit v1.2.3 From 7dca1c307d2fecb14308f4f31a7bec4c86cc38cc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 25 Jun 2009 15:18:11 -0500 Subject: Adding the client to the child related functions --- libdbusmenu-gtk/client.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index eae304f..7ba710f 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -40,9 +40,9 @@ static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self); static void dbusmenu_gtkclient_dispose (GObject *object); static void dbusmenu_gtkclient_finalize (GObject *object); static void new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata); -static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpointer userdata); -static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata); -static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, gpointer userdata); +static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, DbusmenuGtkClient * gtkclient); +static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient); +static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); @@ -140,10 +140,10 @@ new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) g_object_set_data(G_OBJECT(mi), data_menuitem, gmi); /* DbusmenuMenuitem signals */ - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(new_child), NULL); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(delete_child), NULL); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(move_child), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(new_child), client); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(delete_child), client); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(move_child), client); /* GtkMenuitem signals */ g_signal_connect(G_OBJECT(gmi), "activate", G_CALLBACK(menu_pressed_cb), mi); @@ -155,7 +155,7 @@ new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) } static void -new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpointer userdata) +new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, DbusmenuGtkClient * gtkclient) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); GtkMenu * menu = GTK_MENU(ann_menu); @@ -175,7 +175,7 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, gpoi } static void -delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata) +delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient) { if (g_list_length(dbusmenu_menuitem_get_children(mi)) == 0) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); @@ -191,7 +191,7 @@ delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, gpointer userdata } static void -move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, gpointer userdata) +move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); if (ann_menu == NULL) { -- cgit v1.2.3 From 1e11dbfb9f51114ae1f1fe9fc2d25a507f54738a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 25 Jun 2009 15:24:54 -0500 Subject: Making it so that we don't have any gtk events or handling of the root node. It's a special node, we need to leave it alone. --- libdbusmenu-gtk/client.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 7ba710f..64cb709 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -154,9 +154,17 @@ new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) return; } +static gboolean +is_root (DbusmenuGtkClient * gtkclient, DbusmenuMenuitem * mi) +{ + return mi == dbusmenu_client_get_root(DBUSMENU_CLIENT(gtkclient)); +} + static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, DbusmenuGtkClient * gtkclient) { + if (is_root(gtkclient, mi)) { return; } + gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); GtkMenu * menu = GTK_MENU(ann_menu); if (menu == NULL) { @@ -170,6 +178,7 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get (child); gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position); + gtk_widget_show(GTK_WIDGET(menu)); return; } @@ -177,6 +186,8 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient) { + if (is_root(gtkclient, mi)) { return; } + if (g_list_length(dbusmenu_menuitem_get_children(mi)) == 0) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); GtkMenu * menu = GTK_MENU(ann_menu); @@ -193,6 +204,8 @@ delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient) { + if (is_root(gtkclient, mi)) { return; } + gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); if (ann_menu == NULL) { g_warning("Moving a child when we don't have a submenu!"); -- cgit v1.2.3 From 7fde2d3d2d3b1437eea4695d5164d92b0d845b5c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 25 Jun 2009 15:38:16 -0500 Subject: Make it so that getting the menuitem will create it in cases where it's not created. This removes the chance of a race between the various functions. --- libdbusmenu-gtk/client.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 64cb709..f715e35 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -172,11 +172,11 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus menu = GTK_MENU(gtk_menu_new()); g_object_set_data(G_OBJECT(mi), data_menu, menu); - GtkMenuItem * parent = dbusmenu_gtkclient_menuitem_get (mi); + GtkMenuItem * parent = dbusmenu_gtkclient_menuitem_get(gtkclient, mi); gtk_menu_item_set_submenu(parent, GTK_WIDGET(menu)); } - GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get (child); + GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child); gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position); gtk_widget_show(GTK_WIDGET(menu)); @@ -212,7 +212,7 @@ move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint ol return; } - GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get (child); + GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child); gtk_menu_reorder_child(GTK_MENU(ann_menu), GTK_WIDGET(childmi), new); return; @@ -241,6 +241,7 @@ dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object) /** dbusmenu_gtkclient_menuitem_get: + @client: A #DbusmenuGtkClient with the item in it. @item: #DbusmenuMenuitem to get associated #GtkMenuItem on. This grabs the #GtkMenuItem that is associated with the @@ -249,8 +250,17 @@ dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object) Return value: The #GtkMenuItem that can be played with. */ GtkMenuItem * -dbusmenu_gtkclient_menuitem_get (DbusmenuMenuitem * item) +dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * item) { - return GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), NULL); + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(item), NULL); + + GtkMenuItem * mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); + if (mi == NULL) { + new_menuitem(DBUSMENU_CLIENT(client), item, NULL); + mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); + } + + return mi; } -- cgit v1.2.3 From eea69ca7f7a48ff17a02adee6a2640663b9c0245 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 26 Jun 2009 12:53:15 -0500 Subject: Removing the old is_root and now using the new property on the menuitems for that task. --- libdbusmenu-gtk/client.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'libdbusmenu-gtk/client.c') diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index f715e35..a236123 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -154,16 +154,10 @@ new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) return; } -static gboolean -is_root (DbusmenuGtkClient * gtkclient, DbusmenuMenuitem * mi) -{ - return mi == dbusmenu_client_get_root(DBUSMENU_CLIENT(gtkclient)); -} - static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, DbusmenuGtkClient * gtkclient) { - if (is_root(gtkclient, mi)) { return; } + if (dbusmenu_menuitem_get_root(mi)) { return; } gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); GtkMenu * menu = GTK_MENU(ann_menu); @@ -186,7 +180,7 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient) { - if (is_root(gtkclient, mi)) { return; } + if (dbusmenu_menuitem_get_root(mi)) { return; } if (g_list_length(dbusmenu_menuitem_get_children(mi)) == 0) { gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); @@ -204,7 +198,7 @@ delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient) { - if (is_root(gtkclient, mi)) { return; } + if (dbusmenu_menuitem_get_root(mi)) { return; } gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu); if (ann_menu == NULL) { -- cgit v1.2.3