diff options
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r-- | libdbusmenu-gtk/Makefile.am | 5 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.c | 35 | ||||
-rw-r--r-- | libdbusmenu-gtk/parser.c | 67 |
3 files changed, 95 insertions, 12 deletions
diff --git a/libdbusmenu-gtk/Makefile.am b/libdbusmenu-gtk/Makefile.am index b1ee91a..fcebd04 100644 --- a/libdbusmenu-gtk/Makefile.am +++ b/libdbusmenu-gtk/Makefile.am @@ -68,7 +68,7 @@ libdbusmenu_gtk_la_CFLAGS = \ -DG_LOG_DOMAIN="\"LIBDBUSMENU-GTK\"" libdbusmenu_gtk_la_LIBADD = \ - ../libdbusmenu-glib/libdbusmenu-glib.la \ + $(top_builddir)/libdbusmenu-glib/libdbusmenu-glib.la \ $(DBUSMENUGTK_LIBS) # We duplicate these here because Automake won't let us use $(VER) on the left hand side. @@ -118,7 +118,8 @@ DbusmenuGtk_0_4_gir_INCLUDES = \ $(GTKGIR) \ Dbusmenu-0.4 DbusmenuGtk_0_4_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir) -DbusmenuGtk_0_4_gir_LIBS = libdbusmenu-gtk$(VER).la +DbusmenuGtk_0_4_gir_LIBS = libdbusmenu-gtk$(VER).la \ + $(top_builddir)/libdbusmenu-glib/libdbusmenu-glib.la DbusmenuGtk_0_4_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources)) DbusmenuGtk_0_4_gir_NAMESPACE = DbusmenuGtk$(VER) DbusmenuGtk_0_4_gir_EXPORT_PACKAGES = dbusmenu-gtk$(VER)-0.4 diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 9888cbe..830356a 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -725,6 +725,30 @@ process_disposition (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * varian return; } +/* Process the accessible description */ +static void +process_a11y_desc (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * variant, DbusmenuGtkClient * gtkclient) +{ + AtkObject * aobj = gtk_widget_get_accessible(GTK_WIDGET(gmi)); + + if (aobj == NULL) { + return; + } + + const gchar * setname = NULL; + + if (variant != NULL) { + setname = g_variant_get_string(variant, NULL); + } + + if (setname == NULL) { + setname = ""; + } + + atk_object_set_name(aobj, setname); + return; +} + /* Whenever we have a property change on a DbusmenuMenuitem we need to be responsive to that. */ static void @@ -747,8 +771,7 @@ menu_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * variant, Db } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_DISPOSITION)) { process_disposition(mi, gmi, variant, gtkclient); } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC)) { - atk_object_set_name(gtk_widget_get_accessible(GTK_WIDGET(gmi)), variant == NULL ? NULL : - g_variant_get_string(variant, NULL)); + process_a11y_desc(mi, gmi, variant, gtkclient); } return; @@ -894,6 +917,7 @@ dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * 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); process_disposition(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_DISPOSITION), client); + process_a11y_desc(item, gmi, dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC), client); refresh_shortcut(client, item); const gchar * a11y_desc = dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC); @@ -1128,12 +1152,7 @@ image_property_handle (DbusmenuMenuitem * item, const gchar * property, GVariant return; } - const gchar * value = NULL; - if (variant != NULL) { - value = g_variant_get_string(variant, NULL); - } - - if (value == NULL || value[0] == '\0') { + if (variant == NULL) { /* This means that we're unsetting a value. */ /* Try to use the other one */ if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_NAME)) { diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 0ecfa1e..ab3b77a 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -26,6 +26,8 @@ License version 3 and version 2.1 along with this program. If not, see <http://www.gnu.org/licenses/> */ +#include <atk/atk.h> + #include "parser.h" #include "menuitem.h" #include "client.h" @@ -41,6 +43,7 @@ typedef struct _ParserData GtkWidget *widget; GtkWidget *shell; GtkWidget *image; + AtkObject *accessible; } ParserData; typedef struct _RecurseContext @@ -67,6 +70,9 @@ static void image_notify_cb (GtkWidget * widget, static void action_notify_cb (GtkAction * action, GParamSpec * pspec, gpointer data); +static void a11y_name_notify_cb (AtkObject * accessible, + GParamSpec * pspec, + gpointer data); static void item_inserted_cb (GtkContainer * menu, GtkWidget * widget, #ifdef HAVE_GTK3 @@ -200,6 +206,12 @@ parse_data_free (gpointer data) g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image); } + if (pdata != NULL && pdata->accessible != NULL) { + g_signal_handlers_disconnect_matched(pdata->accessible, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, G_CALLBACK(a11y_name_notify_cb), NULL); + g_object_remove_weak_pointer(G_OBJECT(pdata->accessible), (gpointer*)&pdata->accessible); + } + g_free(pdata); return; @@ -415,8 +427,11 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) /* Oops, let's tell our parents about us */ if (peek == NULL) { - if (dbusmenu_menuitem_get_parent(thisitem) != NULL) { - dbusmenu_menuitem_unparent(thisitem); + g_object_ref(thisitem); + + DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent(thisitem); + if (parent != NULL) { + dbusmenu_menuitem_child_delete(parent, thisitem); } gint pos = get_child_position (widget); @@ -427,6 +442,8 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) else dbusmenu_menuitem_child_append (recurse->parent, thisitem); + + g_object_unref(thisitem); } } @@ -582,6 +599,27 @@ construct_dbusmenu_for_widget (GtkWidget * widget) mi); g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); + AtkObject *accessible = gtk_widget_get_accessible (widget); + if (accessible) + { + // Getting the accessible name of the Atk object retrieves the text + // of the menu item label, unless the application has set an alternate + // accessible name. + const gchar * label_text = gtk_label_get_text (GTK_LABEL (label)); + const gchar * a11y_name = atk_object_get_name (accessible); + if (g_strcmp0 (a11y_name, label_text)) + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, a11y_name); + + // An application may set an alternate accessible name in the future, + // so we had better watch out for it. + pdata->accessible = accessible; + g_signal_connect (G_OBJECT (accessible), + "notify::accessible-name", + G_CALLBACK (a11y_name_notify_cb), + mi); + g_object_add_weak_pointer(G_OBJECT (accessible), (gpointer*)&pdata->accessible); + } + if (GTK_IS_ACTIVATABLE (widget)) { GtkActivatable *activatable = GTK_ACTIVATABLE (widget); @@ -948,6 +986,31 @@ action_notify_cb (GtkAction *action, } static void +a11y_name_notify_cb (AtkObject *accessible, + GParamSpec *pspec, + gpointer data) +{ + DbusmenuMenuitem *item = (DbusmenuMenuitem *)data; + GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + GtkWidget *label = find_menu_label (widget); + const gchar *label_text = gtk_label_get_text (GTK_LABEL (label)); + const gchar *name = atk_object_get_name (accessible); + + /* If an application sets the accessible name to NULL, then a subsequent + * call to get the accessible name from the Atk object should return the same + * string as the text of the menu item label, in which case, we want to clear + * the accessible description property of the dbusmenu item. + */ + if (pspec->name == g_intern_static_string ("accessible-name")) + { + if (!g_strcmp0 (name, label_text)) + dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, NULL); + else + dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, name); + } +} + +static void item_activated (DbusmenuMenuitem *item, guint timestamp, gpointer user_data) { GtkWidget *child; |