From feb64f40b0f50735104da0a7fdafbe480763c180 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2013 00:54:26 +0100 Subject: [PATCH 1/1] a11y: Emit text-changed signals directly When setting new text on the label, the text-changed::delete signal needs to be emitted before deleting the text (so that atk-bridge can query the old text) while the text-changed::insert event needs to happen afterwards (for the same reason). The old code using the notify signal was only emitted after changing the text. --- gtk/a11y/Makefile.am | 1 + gtk/a11y/gtklabelaccessible.c | 91 +++++++++++++--------------- gtk/a11y/gtklabelaccessibleprivate.h | 30 +++++++++ gtk/gtklabel.c | 5 +- 4 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 gtk/a11y/gtklabelaccessibleprivate.h diff --git a/gtk/a11y/Makefile.am b/gtk/a11y/Makefile.am index ee9b0ce01..2ca36b641 100644 --- a/gtk/a11y/Makefile.am +++ b/gtk/a11y/Makefile.am @@ -106,6 +106,7 @@ gtka11y_private_h_sources = \ gtkcellaccessibleprivate.h \ gtkcolorswatchaccessibleprivate.h \ gtkiconviewaccessibleprivate.h \ + gtklabelaccessibleprivate.h \ gtklockbuttonaccessibleprivate.h \ gtktextviewaccessibleprivate.h \ gtktreeviewaccessibleprivate.h \ diff --git a/gtk/a11y/gtklabelaccessible.c b/gtk/a11y/gtklabelaccessible.c index c88b7d7d8..c21676410 100644 --- a/gtk/a11y/gtklabelaccessible.c +++ b/gtk/a11y/gtklabelaccessible.c @@ -19,11 +19,11 @@ #include #include +#include "gtkwidgetprivate.h" #include "gtklabelaccessible.h" struct _GtkLabelAccessiblePrivate { - gchar *text; gint cursor_position; gint selection_bound; }; @@ -46,16 +46,11 @@ gtk_label_accessible_initialize (AtkObject *obj, gpointer data) { GtkWidget *widget; - GtkLabelAccessible *accessible; ATK_OBJECT_CLASS (gtk_label_accessible_parent_class)->initialize (obj, data); - accessible = GTK_LABEL_ACCESSIBLE (obj); - widget = GTK_WIDGET (data); - accessible->priv->text = g_strdup (gtk_label_get_text (GTK_LABEL (widget))); - /* * Check whether ancestor of GtkLabel is a GtkButton and if so * set accessible parent for GtkLabelAccessible @@ -97,6 +92,45 @@ check_for_selection_change (GtkLabelAccessible *accessible, return ret_val; } +void +_gtk_label_accessible_text_deleted (GtkLabel *label) +{ + AtkObject *obj; + const char *text; + guint length; + + obj = _gtk_widget_peek_accessible (GTK_WIDGET (label)); + if (obj == NULL) + return; + + text = gtk_label_get_text (label); + length = g_utf8_strlen (text, -1); + if (length > 0) + g_signal_emit_by_name (obj, "text-changed::delete", 0, length); +} + +void +_gtk_label_accessible_text_inserted (GtkLabel *label) +{ + AtkObject *obj; + const char *text; + guint length; + + obj = _gtk_widget_peek_accessible (GTK_WIDGET (label)); + if (obj == NULL) + return; + + text = gtk_label_get_text (label); + length = g_utf8_strlen (text, -1); + if (length > 0) + g_signal_emit_by_name (obj, "text-changed::insert", 0, length); + + if (obj->name == NULL) + /* The label has changed so notify a change in accessible-name */ + g_object_notify (G_OBJECT (obj), "accessible-name"); + + g_signal_emit_by_name (obj, "visible-data-changed"); +} static void gtk_label_accessible_notify_gtk (GObject *obj, @@ -105,37 +139,10 @@ gtk_label_accessible_notify_gtk (GObject *obj, GtkWidget *widget = GTK_WIDGET (obj); AtkObject* atk_obj = gtk_widget_get_accessible (widget); GtkLabelAccessible *accessible; - gint length; accessible = GTK_LABEL_ACCESSIBLE (atk_obj); - if (g_strcmp0 (pspec->name, "label") == 0) - { - const gchar *text; - - text = gtk_label_get_text (GTK_LABEL (widget)); - if (g_strcmp0 (accessible->priv->text, text) == 0) - return; - - /* Create a delete text and an insert text signal */ - length = g_utf8_strlen (accessible->priv->text, -1); - if (length > 0) - g_signal_emit_by_name (atk_obj, "text-changed::delete", 0, length); - - g_free (accessible->priv->text); - accessible->priv->text = g_strdup (text); - - length = g_utf8_strlen (accessible->priv->text, -1); - if (length > 0) - g_signal_emit_by_name (atk_obj, "text-changed::insert", 0, length); - - if (atk_obj->name == NULL) - /* The label has changed so notify a change in accessible-name */ - g_object_notify (G_OBJECT (atk_obj), "accessible-name"); - - g_signal_emit_by_name (atk_obj, "visible-data-changed"); - } - else if (g_strcmp0 (pspec->name, "cursor-position") == 0) + if (g_strcmp0 (pspec->name, "cursor-position") == 0) { g_signal_emit_by_name (atk_obj, "text-caret-moved", _gtk_label_get_cursor_position (GTK_LABEL (widget))); @@ -151,17 +158,6 @@ gtk_label_accessible_notify_gtk (GObject *obj, GTK_WIDGET_ACCESSIBLE_CLASS (gtk_label_accessible_parent_class)->notify_gtk (obj, pspec); } -static void -gtk_label_accessible_finalize (GObject *object) -{ - GtkLabelAccessible *accessible = GTK_LABEL_ACCESSIBLE (object); - - g_free (accessible->priv->text); - - G_OBJECT_CLASS (gtk_label_accessible_parent_class)->finalize (object); -} - - /* atkobject.h */ static AtkStateSet * @@ -274,11 +270,8 @@ gtk_label_accessible_get_name (AtkObject *accessible) static void gtk_label_accessible_class_init (GtkLabelAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass; - - gobject_class->finalize = gtk_label_accessible_finalize; + GtkWidgetAccessibleClass *widget_class = GTK_WIDGET_ACCESSIBLE_CLASS (klass); widget_class->notify_gtk = gtk_label_accessible_notify_gtk; diff --git a/gtk/a11y/gtklabelaccessibleprivate.h b/gtk/a11y/gtklabelaccessibleprivate.h new file mode 100644 index 000000000..544a94ff5 --- /dev/null +++ b/gtk/a11y/gtklabelaccessibleprivate.h @@ -0,0 +1,30 @@ +/* GTK+ - accessibility implementations + * Copyright (C) 2002, 2004 Anders Carlsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_LABEL_ACCESSIBLE_PRIVATE_H__ +#define __GTK_LABEL_ACCESSIBLE_PRIVATE_H__ + +#include + +G_BEGIN_DECLS + +void _gtk_label_accessible_text_deleted (GtkLabel *label); +void _gtk_label_accessible_text_inserted (GtkLabel *label); + +G_END_DECLS + +#endif /* __GTK_LABEL_ACCESSIBLE_PRIVATE_H__ */ diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index b228d0567..8d18cf0c8 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -52,7 +52,7 @@ #include "gtktypebuiltins.h" #include "gtkmain.h" -#include "a11y/gtklabelaccessible.h" +#include "a11y/gtklabelaccessibleprivate.h" /* this is in case rint() is not provided by the compiler, * such as in the case of C89 compilers, like MSVC @@ -1987,9 +1987,12 @@ gtk_label_set_text_internal (GtkLabel *label, return; } + _gtk_label_accessible_text_deleted (label); g_free (priv->text); priv->text = str; + _gtk_label_accessible_text_inserted (label); + gtk_label_select_region_index (label, 0, 0); } -- 2.43.2