aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r--libdbusmenu-gtk/client.c14
-rw-r--r--libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in2
-rw-r--r--libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in2
-rw-r--r--libdbusmenu-gtk/parser.c73
4 files changed, 78 insertions, 13 deletions
diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c
index 510e74e..497808b 100644
--- a/libdbusmenu-gtk/client.c
+++ b/libdbusmenu-gtk/client.c
@@ -458,7 +458,7 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
{
if (gtk_menu_item_get_submenu(gmi) == NULL) {
GVariant * variant = g_variant_new("i", 0);
- dbusmenu_menuitem_handle_event(mi, "clicked", variant, gtk_get_current_event_time());
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_ACTIVATED, variant, gtk_get_current_event_time());
} else {
/* TODO: We need to stop the display of the submenu
until this callback returns. */
@@ -467,6 +467,15 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
return TRUE;
}
+static void
+submenu_notify_visible_cb (GtkWidget * menu, GParamSpec * pspec, DbusmenuMenuitem * mi)
+{
+ if (gtk_widget_get_visible (menu))
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_OPENED, NULL, gtk_get_current_event_time());
+ else
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_CLOSED, NULL, gtk_get_current_event_time());
+}
+
/* Process the visible property */
static void
process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value)
@@ -740,11 +749,12 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus
GtkMenuItem * parent = dbusmenu_gtkclient_menuitem_get(gtkclient, mi);
gtk_menu_item_set_submenu(parent, GTK_WIDGET(menu));
+
+ g_signal_connect(menu, "notify::visible", G_CALLBACK(submenu_notify_visible_cb), mi);
}
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));
return;
}
diff --git a/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in b/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
index 8784556..9a1b460 100644
--- a/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
+++ b/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
@@ -5,7 +5,7 @@ bindir=@bindir@
includedir=@includedir@
Cflags: -I${includedir}/libdbusmenu-0.4
-Requires: dbusmenu-glib-0.4
+Requires: dbusmenu-glib-0.4 gdk-pixbuf-2.0 gtk+-2.0
Libs: -L${libdir} -ldbusmenu-gtk
Name: libdbusmenu-gtk
diff --git a/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in b/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
index 804b13e..c297db3 100644
--- a/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
+++ b/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
@@ -5,7 +5,7 @@ bindir=@bindir@
includedir=@includedir@
Cflags: -I${includedir}/libdbusmenu-0.4
-Requires: dbusmenu-glib-0.4
+Requires: dbusmenu-glib-0.4 gdk-pixbuf-2.0 gtk+-3.0
Libs: -L${libdir} -ldbusmenu-gtk3
Name: libdbusmenu-gtk3
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index 1b032bb..9d93a1e 100644
--- a/libdbusmenu-gtk/parser.c
+++ b/libdbusmenu-gtk/parser.c
@@ -69,6 +69,9 @@ static void action_notify_cb (GtkAction * action,
static void child_added_cb (GtkContainer * menu,
GtkWidget * widget,
gpointer data);
+static void child_removed_cb (GtkContainer * menu,
+ GtkWidget * widget,
+ gpointer data);
static void theme_changed_cb (GtkIconTheme * theme,
gpointer data);
static void item_activated (DbusmenuMenuitem * item,
@@ -98,15 +101,25 @@ static void menuitem_notify_cb (GtkWidget * widget,
DbusmenuMenuitem *
dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
{
- g_return_val_if_fail(GTK_IS_MENU_ITEM(widget) || GTK_IS_MENU_SHELL(widget), NULL);
+ g_return_val_if_fail(GTK_IS_MENU_ITEM(widget) || GTK_IS_MENU_SHELL(widget), NULL);
+
+ DbusmenuMenuitem * returnval = NULL;
+ gpointer data = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM);
- RecurseContext recurse = {0};
+ if (data == NULL) {
+ RecurseContext recurse = {0};
- recurse.toplevel = gtk_widget_get_toplevel(widget);
+ recurse.toplevel = gtk_widget_get_toplevel(widget);
- parse_menu_structure_helper(widget, &recurse);
+ parse_menu_structure_helper(widget, &recurse);
+
+ returnval = recurse.parent;
+ } else {
+ returnval = DBUSMENU_MENUITEM(data);
+ g_object_ref(G_OBJECT(returnval));
+ }
- return recurse.parent;
+ return returnval;
}
/**
@@ -124,7 +137,9 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
DbusmenuMenuitem *
dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget)
{
- g_return_val_if_fail(GTK_IS_MENU_ITEM(widget), NULL);
+ if (!GTK_IS_MENU_ITEM(widget)) {
+ return NULL;
+ }
return DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM));
}
@@ -160,6 +175,8 @@ parse_data_free (gpointer data)
if (pdata != NULL && pdata->shell != NULL) {
g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
0, 0, NULL, G_CALLBACK(child_added_cb), NULL);
+ g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(child_removed_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell);
}
@@ -246,7 +263,6 @@ new_menuitem (GtkWidget * widget)
static void
parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
{
-
/* If this is a shell, then let's handle the items in it. */
if (GTK_IS_MENU_SHELL (widget)) {
/* Okay, this is a little janky and all.. but some applications update some
@@ -282,6 +298,10 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
"child-added",
G_CALLBACK (child_added_cb),
recurse->parent);
+ g_signal_connect (G_OBJECT (widget),
+ "child-removed",
+ G_CALLBACK (child_removed_cb),
+ recurse->parent);
g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell);
}
@@ -371,14 +391,20 @@ sanitize_label_text (const gchar * label)
which we don't. */
gchar * sanitized = NULL;
GError * error = NULL;
+
+ if (label == NULL) {
+ return NULL;
+ }
+
if (pango_parse_markup (label, -1, 0, NULL, &sanitized, NULL, &error)) {
return sanitized;
}
- else {
+
+ if (error != NULL) {
g_warning ("Could not parse '%s': %s", label, error->message);
g_error_free (error);
- return g_strdup (label);
}
+ return g_strdup (label);
}
static gchar *
@@ -533,6 +559,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget)
"child-added",
G_CALLBACK (child_added_cb),
mi);
+ g_signal_connect (G_OBJECT (submenu),
+ "child-removed",
+ G_CALLBACK (child_removed_cb),
+ mi);
g_object_add_weak_pointer(G_OBJECT(submenu), (gpointer*)&pdata->shell);
}
@@ -625,6 +655,9 @@ update_icon (DbusmenuMenuitem *menuitem, GtkImage *image)
if (image != NULL && should_show_image (image)) {
switch (gtk_image_get_storage_type (image)) {
+ case GTK_IMAGE_EMPTY:
+ break;
+
case GTK_IMAGE_PIXBUF:
pixbuf = g_object_ref (gtk_image_get_pixbuf (image));
break;
@@ -940,6 +973,28 @@ child_added_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
parse_menu_structure_helper(widget, &recurse);
}
+/* A child item was added to a menu we're watching. Let's try to integrate it. */
+static void
+child_removed_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
+{
+ gpointer pmi = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM);
+ if (pmi == NULL) {
+ return;
+ }
+
+ DbusmenuMenuitem * child = DBUSMENU_MENUITEM(pmi);
+
+ pmi = g_object_get_data(G_OBJECT(menu), CACHED_MENUITEM);
+ if (pmi == NULL) {
+ return;
+ }
+
+ DbusmenuMenuitem * parent = DBUSMENU_MENUITEM(pmi);
+
+ dbusmenu_menuitem_child_delete(parent, child);
+ return;
+}
+
static void
theme_changed_cb (GtkIconTheme *theme, gpointer data)
{