diff options
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r-- | libdbusmenu-gtk/client.c | 108 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.h | 2 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.c | 36 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.h | 2 |
4 files changed, 125 insertions, 23 deletions
diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index a236123..7271c37 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -44,6 +44,10 @@ static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint po static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient); static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient); +static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static gboolean new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); + /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); @@ -61,7 +65,12 @@ dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass) static void dbusmenu_gtkclient_init (DbusmenuGtkClient *self) { + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_DEFAULT, new_item_normal); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_SEPARATOR, new_item_seperator); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(self), DBUSMENU_CLIENT_TYPES_IMAGE, new_item_image); + g_signal_connect(G_OBJECT(self), DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM, G_CALLBACK(new_menuitem), NULL); + return; } @@ -95,14 +104,27 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi) return TRUE; } +/* Process the visible property */ +static void +process_visible (GtkMenuItem * gmi, const gchar * value) +{ + if (value == NULL || !g_strcmp0(value, "true")) { + gtk_widget_show(GTK_WIDGET(gmi)); + } else { + gtk_widget_hide(GTK_WIDGET(gmi)); + } + return; +} + /* 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) { - if (!g_strcmp0(prop, "label")) { + if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_LABEL)) { gtk_menu_item_set_label(gmi, value); - gtk_widget_show(GTK_WIDGET(gmi)); + } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) { + process_visible(gmi, value); } return; @@ -125,31 +147,34 @@ destoryed_dbusmenuitem_cb (gpointer udata, GObject * dbusmenuitem) static void new_menuitem (DbusmenuClient * client, DbusmenuMenuitem * mi, gpointer userdata) { - gpointer ann_mi = g_object_get_data(G_OBJECT(mi), data_menuitem); - GtkMenuItem * gmi = GTK_MENU_ITEM(ann_mi); + g_warning("Got new menuitem signal, which means they want something"); + g_warning(" that I simply don't have."); - 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()); + return; +} +void +dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * item, GtkMenuItem * gmi, DbusmenuMenuitem * parent) +{ /* Attach these two */ - g_object_set_data(G_OBJECT(mi), data_menuitem, gmi); + g_object_set_data(G_OBJECT(item), 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), 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); + g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), gmi); + g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(delete_child), client); + g_signal_connect(G_OBJECT(item), 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); + g_signal_connect(G_OBJECT(gmi), "activate", G_CALLBACK(menu_pressed_cb), item); /* Life insurance */ - g_object_weak_ref(G_OBJECT(mi), destoryed_dbusmenuitem_cb, gmi); + g_object_weak_ref(G_OBJECT(item), destoryed_dbusmenuitem_cb, gmi); + + process_visible(gmi, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_VISIBLE)); + + if (parent != NULL) { + new_child(parent, item, dbusmenu_menuitem_get_position(item, parent), DBUSMENU_GTKCLIENT(client)); + } return; } @@ -251,10 +276,55 @@ dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * GtkMenuItem * mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); if (mi == NULL) { - new_menuitem(DBUSMENU_CLIENT(client), item, NULL); + // new_menuitem(DBUSMENU_CLIENT(client), item, NULL); + g_warning("GTK not updated"); mi = GTK_MENU_ITEM(g_object_get_data(G_OBJECT(item), data_menuitem)); } return mi; } +static gboolean +new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + /* Note: not checking parent, it's reasonable for it to be NULL */ + + GtkMenuItem * gmi; + gmi = GTK_MENU_ITEM(gtk_menu_item_new_with_label(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL))); + + if (gmi != NULL) { + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); + } else { + return FALSE; + } + + return TRUE; +} + +static gboolean +new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + /* Note: not checking parent, it's reasonable for it to be NULL */ + + GtkMenuItem * gmi; + gmi = GTK_MENU_ITEM(gtk_separator_menu_item_new()); + + if (gmi != NULL) { + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); + } else { + return FALSE; + } + + return TRUE; +} + +static gboolean +new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + + return TRUE; +} diff --git a/libdbusmenu-gtk/client.h b/libdbusmenu-gtk/client.h index a549fe0..b1d816f 100644 --- a/libdbusmenu-gtk/client.h +++ b/libdbusmenu-gtk/client.h @@ -79,6 +79,8 @@ GType dbusmenu_gtkclient_get_type (void); DbusmenuGtkClient * dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object); GtkMenuItem * dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * item); +void dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * item, GtkMenuItem * gmi, DbusmenuMenuitem * parent); + /** SECTION:gtkmenu @short_description: A GTK Menu Object that syncronizes over DBus diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c index bc7458c..74e1bec 100644 --- a/libdbusmenu-gtk/menu.c +++ b/libdbusmenu-gtk/menu.c @@ -64,6 +64,7 @@ static void set_property (GObject * obj, guint id, const GValue * value, GParamS static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Internal */ static void build_client (DbusmenuGtkMenu * self); +static void child_realized (DbusmenuMenuitem * child, gpointer userdata); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkMenu, dbusmenu_gtkmenu, GTK_TYPE_MENU); @@ -188,9 +189,7 @@ static void root_child_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, DbusmenuGtkMenu * menu) { g_debug("Root new child"); - DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); - gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child)), position); - gtk_widget_show(GTK_WIDGET(menu)); + g_signal_connect(G_OBJECT(child), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(child_realized), menu); return; } @@ -214,6 +213,18 @@ root_child_delete (DbusmenuMenuitem * root, DbusmenuMenuitem * child, DbusmenuGt } static void +child_realized (DbusmenuMenuitem * child, gpointer userdata) +{ + g_return_if_fail(DBUSMENU_IS_GTKMENU(userdata)); + + DbusmenuGtkMenu * menu = DBUSMENU_GTKMENU(userdata); + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); + + gtk_menu_append(menu, GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child))); + return; +} + +static void root_changed (DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, DbusmenuGtkMenu * menu) { if (newroot == NULL) { gtk_widget_hide(GTK_WIDGET(menu)); @@ -227,7 +238,8 @@ root_changed (DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, DbusmenuGt GList * child = NULL; guint count = 0; for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child)) { - gtk_menu_append(menu, GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(client, child->data))); + /* gtk_menu_append(menu, GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(client, child->data))); */ + g_signal_connect(G_OBJECT(child->data), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(child_realized), menu); count++; } @@ -279,3 +291,19 @@ dbusmenu_gtkmenu_new (gchar * dbus_name, gchar * dbus_object) NULL); } +/** + dbusmenu_gtkmenu_get_client: + @menu: The #DbusmenuGtkMenu to get the client from + + An accessor for the client that this menu is using to + communicate with the server. + + Return value: A valid #DbusmenuGtkClient or NULL on error. +*/ +DbusmenuGtkClient * +dbusmenu_gtkmenu_get_client (DbusmenuGtkMenu * menu) +{ + g_return_val_if_fail(DBUSMENU_IS_GTKMENU(menu), NULL); + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); + return priv->client; +} diff --git a/libdbusmenu-gtk/menu.h b/libdbusmenu-gtk/menu.h index 73804c5..5147d30 100644 --- a/libdbusmenu-gtk/menu.h +++ b/libdbusmenu-gtk/menu.h @@ -31,6 +31,7 @@ License version 3 and version 2.1 along with this program. If not, see #include <glib.h> #include <glib-object.h> +#include "client.h" G_BEGIN_DECLS @@ -71,6 +72,7 @@ struct _DbusmenuGtkMenu { GType dbusmenu_gtkmenu_get_type (void); DbusmenuGtkMenu * dbusmenu_gtkmenu_new (gchar * dbus_name, gchar * dbus_object); +DbusmenuGtkClient * dbusmenu_gtkmenu_get_client (DbusmenuGtkMenu * menu); /** SECTION:gtkmenu |