aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r--libdbusmenu-gtk/Makefile.am2
-rw-r--r--libdbusmenu-gtk/Makefile.in2
-rw-r--r--libdbusmenu-gtk/client.c54
-rw-r--r--libdbusmenu-gtk/parser.c38
4 files changed, 80 insertions, 16 deletions
diff --git a/libdbusmenu-gtk/Makefile.am b/libdbusmenu-gtk/Makefile.am
index 50a8f2c..aa36445 100644
--- a/libdbusmenu-gtk/Makefile.am
+++ b/libdbusmenu-gtk/Makefile.am
@@ -103,7 +103,6 @@ DbusmenuGtk_0_4_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir)
DbusmenuGtk_0_4_gir_LIBS = libdbusmenu-gtk$(VER).la
DbusmenuGtk_0_4_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
DbusmenuGtk_0_4_gir_NAMESPACE = DbusmenuGtk$(VER)
-DbusmenuGtk_0_4_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS)
DbusmenuGtk_0_4_gir_EXPORT_PACKAGES = dbusmenu-gtk$(VER)-0.4
# We duplicate these for the same reason as libdbusmenu_gtk3includedir above
@@ -112,7 +111,6 @@ DbusmenuGtk3_0_4_gir_CFLAGS = $(DbusmenuGtk_0_4_gir_CFLAGS)
DbusmenuGtk3_0_4_gir_LIBS = $(DbusmenuGtk_0_4_gir_LIBS)
DbusmenuGtk3_0_4_gir_FILES = $(DbusmenuGtk_0_4_gir_FILES)
DbusmenuGtk3_0_4_gir_NAMESPACE = $(DbusmenuGtk_0_4_gir_NAMESPACE)
-DbusmenuGtk3_0_4_gir_SCANNERFLAGS = $(DbusmenuGtk_0_4_gir_SCANNERFLAGS)
DbusmenuGtk3_0_4_gir_EXPORT_PACKAGES = $(DbusmenuGtk_0_4_gir_EXPORT_PACKAGES)
INTROSPECTION_GIRS += DbusmenuGtk$(VER)-0.4.gir
diff --git a/libdbusmenu-gtk/Makefile.in b/libdbusmenu-gtk/Makefile.in
index 5647d0d..465ee0b 100644
--- a/libdbusmenu-gtk/Makefile.in
+++ b/libdbusmenu-gtk/Makefile.in
@@ -401,7 +401,6 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) --includedir=$(top_buildd
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_4_gir_LIBS = libdbusmenu-gtk$(VER).la
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_4_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_4_gir_NAMESPACE = DbusmenuGtk$(VER)
-@HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_4_gir_SCANNERFLAGS = $(INTROSPECTION_SCANNER_ARGS)
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_4_gir_EXPORT_PACKAGES = dbusmenu-gtk$(VER)-0.4
# We duplicate these for the same reason as libdbusmenu_gtk3includedir above
@@ -410,7 +409,6 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) --includedir=$(top_buildd
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk3_0_4_gir_LIBS = $(DbusmenuGtk_0_4_gir_LIBS)
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk3_0_4_gir_FILES = $(DbusmenuGtk_0_4_gir_FILES)
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk3_0_4_gir_NAMESPACE = $(DbusmenuGtk_0_4_gir_NAMESPACE)
-@HAVE_INTROSPECTION_TRUE@DbusmenuGtk3_0_4_gir_SCANNERFLAGS = $(DbusmenuGtk_0_4_gir_SCANNERFLAGS)
@HAVE_INTROSPECTION_TRUE@DbusmenuGtk3_0_4_gir_EXPORT_PACKAGES = $(DbusmenuGtk_0_4_gir_EXPORT_PACKAGES)
@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0
@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS)
diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c
index 497808b..7f05d46 100644
--- a/libdbusmenu-gtk/client.c
+++ b/libdbusmenu-gtk/client.c
@@ -551,11 +551,43 @@ process_toggle_state (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * varia
return;
}
+/* Submenu processing */
+static void
+process_submenu (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * variant, DbusmenuGtkClient * gtkclient)
+{
+ const gchar * submenu = NULL;
+ if (variant != NULL) {
+ submenu = g_variant_get_string(variant, NULL);
+ }
+
+ if (g_strcmp0(submenu, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU) != 0) {
+ /* This is the only case we're really supporting right now,
+ so if it's not this, we want to clean up. */
+ /* We're just going to warn for now. */
+ gpointer pmenu = g_object_get_data(G_OBJECT(mi), data_menu);
+ if (pmenu != NULL) {
+ g_warning("The child-display variable is set to '%s' but there's a menu, odd?", submenu);
+ }
+ } else {
+ /* We need to build a menu for these guys to live in. */
+ GtkMenu * menu = GTK_MENU(gtk_menu_new());
+ g_object_set_data(G_OBJECT(mi), data_menu, menu);
+
+ gtk_menu_item_set_submenu(gmi, GTK_WIDGET(menu));
+
+ g_signal_connect(menu, "notify::visible", G_CALLBACK(submenu_notify_visible_cb), mi);
+ }
+
+ 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, GVariant * variant, GtkMenuItem * gmi)
+menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * variant, DbusmenuGtkClient * gtkclient)
{
+ GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(gtkclient, mi);
+
if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_LABEL)) {
gtk_menu_item_set_label(gmi, variant == NULL ? NULL : g_variant_get_string(variant, NULL));
} else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
@@ -566,6 +598,8 @@ menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * variant, Gt
process_toggle_type(mi, gmi, variant);
} else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE)) {
process_toggle_state(mi, gmi, variant);
+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
+ process_submenu(mi, gmi, variant, gtkclient);
}
return;
@@ -704,7 +738,7 @@ dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem *
#endif
/* DbusmenuMenuitem signals */
- 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_PROPERTY_CHANGED, G_CALLBACK(menu_prop_change_cb), client);
g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_shortcut_change_cb), client);
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);
@@ -720,6 +754,7 @@ dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem *
process_sensitive(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_ENABLED));
process_toggle_type(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE));
process_toggle_state(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE));
+ process_submenu(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY), client);
refresh_shortcut(client, item);
/* Oh, we're a child, let's deal with that */
@@ -741,17 +776,12 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus
if (g_strcmp0(dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_TYPE), DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0) { return; }
gpointer ann_menu = g_object_get_data(G_OBJECT(mi), data_menu);
- 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(gtkclient, mi);
- gtk_menu_item_set_submenu(parent, GTK_WIDGET(menu));
+ if (ann_menu == NULL) {
+ g_warning("Children but no menu, someone's been naughty with their '" DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY "' property: '%s'", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY));
+ return;
+ }
- g_signal_connect(menu, "notify::visible", G_CALLBACK(submenu_notify_visible_cb), mi);
- }
+ GtkMenu * menu = GTK_MENU(ann_menu);
GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child);
gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position);
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index e68c286..c627854 100644
--- a/libdbusmenu-gtk/parser.c
+++ b/libdbusmenu-gtk/parser.c
@@ -79,6 +79,11 @@ static void item_activated (DbusmenuMenuitem * item,
gpointer user_data);
static gboolean item_about_to_show (DbusmenuMenuitem * item,
gpointer user_data);
+static gboolean item_handle_event (DbusmenuMenuitem * item,
+ const gchar * name,
+ GVariant * variant,
+ guint timestamp,
+ GtkWidget * widget);
static void widget_notify_cb (GtkWidget * widget,
GParamSpec * pspec,
gpointer data);
@@ -580,6 +585,11 @@ construct_dbusmenu_for_widget (GtkWidget * widget)
DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW,
G_CALLBACK (item_about_to_show),
widget);
+
+ g_signal_connect (G_OBJECT (mi),
+ DBUSMENU_MENUITEM_SIGNAL_EVENT,
+ G_CALLBACK (item_handle_event),
+ widget);
}
dbusmenu_menuitem_property_set_bool (mi,
@@ -924,6 +934,34 @@ item_about_to_show (DbusmenuMenuitem *item, gpointer user_data)
return TRUE;
}
+static gboolean
+item_handle_event (DbusmenuMenuitem *item, const gchar *name,
+ GVariant *variant, guint timestamp, GtkWidget *widget)
+{
+ if (g_strcmp0 (name, DBUSMENU_MENUITEM_EVENT_OPENED) == 0)
+ {
+ GtkWidget *submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (submenu != NULL)
+ {
+ // Show the submenu so the app can notice and futz with the menus as
+ // desired (empathy and geany do this)
+ gtk_widget_show (submenu);
+ }
+ }
+ else if (g_strcmp0 (name, DBUSMENU_MENUITEM_EVENT_CLOSED) == 0)
+ {
+ GtkWidget *submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (submenu != NULL)
+ {
+ // Hide the submenu so the app can notice and futz with the menus as
+ // desired (empathy and geany do this)
+ gtk_widget_hide (submenu);
+ }
+ }
+
+ return FALSE; // just pass through on everything
+}
+
static void
widget_notify_cb (GtkWidget *widget,
GParamSpec *pspec,