[gtk/wip/ebassi/a11y-2: 419/442] Notify accessibility state changes from GtkWidget



commit 51fc3825825f1bcaa6c76130c3f86921a7887101
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Thu Apr 23 18:01:40 2020 +0100

    Notify accessibility state changes from GtkWidget
    
    Piggybacking on blanket GObject::notify is not very efficient.

 gtk/a11y/gtkwidgetaccessible.c        | 184 ++++++++++++++++++----------------
 gtk/a11y/gtkwidgetaccessibleprivate.h |  14 ++-
 gtk/gtkwidget.c                       |  21 ++++
 3 files changed, 133 insertions(+), 86 deletions(-)
---
diff --git a/gtk/a11y/gtkwidgetaccessible.c b/gtk/a11y/gtkwidgetaccessible.c
index ddd16a0cd6..5fc9f7f09e 100644
--- a/gtk/a11y/gtkwidgetaccessible.c
+++ b/gtk/a11y/gtkwidgetaccessible.c
@@ -38,20 +38,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkWidgetAccessible, gtk_widget_accessible, GTK_TYPE_AC
                          G_ADD_PRIVATE (GtkWidgetAccessible)
                          G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
 
-/* Translate GtkWidget property change notification to the notify_gtk vfunc */
-static void
-notify_cb (GObject    *obj,
-           GParamSpec *pspec)
-{
-  GtkWidgetAccessible *widget;
-  GtkWidgetAccessibleClass *klass;
-
-  widget = GTK_WIDGET_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (obj)));
-  klass = GTK_WIDGET_ACCESSIBLE_GET_CLASS (widget);
-  if (klass->notify_gtk)
-    klass->notify_gtk (obj, pspec);
-}
-
 /*< private >
  * gtk_widget_accessible_update_bounds:
  * @self: a #GtkWidgetAccessible
@@ -95,18 +81,104 @@ gtk_widget_accessible_notify_showing (GtkWidgetAccessible *self)
                                   gtk_widget_get_mapped (widget));
 }
 
+void
+gtk_widget_accessible_notify_tooltip (GtkWidgetAccessible *self)
+{
+  g_return_if_fail (GTK_IS_WIDGET_ACCESSIBLE (self));
+
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+
+  atk_object_notify_state_change (ATK_OBJECT (self),
+                                  ATK_STATE_HAS_TOOLTIP,
+                                  gtk_widget_get_has_tooltip (widget));
+}
+
+void
+gtk_widget_accessible_notify_visible (GtkWidgetAccessible *self)
+{
+  g_return_if_fail (GTK_IS_WIDGET_ACCESSIBLE (self));
+
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+
+  atk_object_notify_state_change (ATK_OBJECT (self),
+                                  ATK_STATE_VISIBLE,
+                                  gtk_widget_get_visible (widget));
+}
+
+void
+gtk_widget_accessible_notify_sensitive (GtkWidgetAccessible *self)
+{
+  g_return_if_fail (GTK_IS_WIDGET_ACCESSIBLE (self));
+
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+  gboolean is_sensitive = gtk_widget_get_sensitive (widget);
+
+  atk_object_notify_state_change (ATK_OBJECT (self),
+                                  ATK_STATE_SENSITIVE,
+                                  is_sensitive);
+  atk_object_notify_state_change (ATK_OBJECT (self),
+                                  ATK_STATE_ENABLED,
+                                  is_sensitive);
+}
+
+void
+gtk_widget_accessible_notify_focus (GtkWidgetAccessible *self)
+{
+  g_return_if_fail (GTK_IS_WIDGET_ACCESSIBLE (self));
+
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+
+  atk_object_notify_state_change (ATK_OBJECT (self),
+                                  ATK_STATE_FOCUSED,
+                                  gtk_widget_has_focus (widget));
+}
+
+void
+gtk_widget_accessible_notify_orientation (GtkWidgetAccessible *self)
+{
+  g_return_if_fail (GTK_IS_WIDGET_ACCESSIBLE (self));
+
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+
+  if (GTK_IS_ORIENTABLE (widget))
+    {
+      GtkOrientable *orientable = GTK_ORIENTABLE (widget);
+      GtkOrientation orientation = gtk_orientable_get_orientation (orientable);
+
+      atk_object_notify_state_change (ATK_OBJECT (self),
+                                      ATK_STATE_HORIZONTAL,
+                                      orientation == GTK_ORIENTATION_HORIZONTAL);
+      atk_object_notify_state_change (ATK_OBJECT (self),
+                                      ATK_STATE_VERTICAL,
+                                      orientation == GTK_ORIENTATION_VERTICAL);
+    }
+}
+
 static void
-gtk_widget_accessible_initialize (AtkObject *obj,
-                                  gpointer   data)
+notify_cb (GObject    *gobject,
+           GParamSpec *pspec,
+           gpointer    user_data)
 {
-  GtkWidget *widget;
+  GtkWidget *widget = GTK_WIDGET (gobject);
+  GtkWidgetAccessible *self = user_data;
 
-  widget = GTK_WIDGET (data);
+  GTK_WIDGET_ACCESSIBLE_GET_CLASS (self)->notify_gtk (G_OBJECT (widget), pspec);
+}
 
-  g_signal_connect (widget, "notify", G_CALLBACK (notify_cb), NULL);
+static void
+gtk_widget_accessible_initialize (AtkObject *object,
+                                  gpointer   data)
+{
+  GtkWidgetAccessible *self = GTK_WIDGET_ACCESSIBLE (object);
+  GtkWidget *widget = data;
 
-  GTK_WIDGET_ACCESSIBLE (obj)->priv->layer = ATK_LAYER_WIDGET;
-  obj->role = ATK_ROLE_UNKNOWN;
+  self->priv->layer = ATK_LAYER_WIDGET;
+  object->role = ATK_ROLE_UNKNOWN;
+
+  /* XXX: This will go away once we move all GtkWidgetAccessibleClass.notify_gtk()
+   * implementations to explicit API on their respective classes
+   */
+  g_signal_connect (widget, "notify", G_CALLBACK (notify_cb), self);
 }
 
 static const char *
@@ -437,69 +509,6 @@ gtk_widget_accessible_get_index_in_parent (AtkObject *accessible)
   return index;
 }
 
-/* This function is the default implementation for the notify_gtk
- * vfunc which gets called when a property changes value on the
- * GtkWidget associated with a GtkWidgetAccessible. It constructs
- * an AtkPropertyValues structure and emits a “property_changed”
- * signal which causes the user specified AtkPropertyChangeHandler
- * to be called.
- */
-static void
-gtk_widget_accessible_notify_gtk (GObject    *obj,
-                                  GParamSpec *pspec)
-{
-  GtkWidget* widget = GTK_WIDGET (obj);
-  AtkObject* atk_obj = gtk_widget_get_accessible (widget);
-  AtkState state;
-  gboolean value;
-
-  if (g_strcmp0 (pspec->name, "has-focus") == 0)
-    {
-      state = ATK_STATE_FOCUSED;
-      value = gtk_widget_has_focus (widget);
-    }
-  else if (g_strcmp0 (pspec->name, "tooltip-text") == 0)
-    {
-      if (atk_obj->description == NULL)
-        g_object_notify (G_OBJECT (atk_obj), "accessible-description");
-      return;
-    }
-  else if (g_strcmp0 (pspec->name, "visible") == 0)
-    {
-      state = ATK_STATE_VISIBLE;
-      value = gtk_widget_get_visible (widget);
-    }
-  else if (g_strcmp0 (pspec->name, "sensitive") == 0)
-    {
-      state = ATK_STATE_SENSITIVE;
-      value = gtk_widget_get_sensitive (widget);
-    }
-  else if (g_strcmp0 (pspec->name, "orientation") == 0 &&
-           GTK_IS_ORIENTABLE (widget))
-    {
-      GtkOrientable *orientable;
-
-      orientable = GTK_ORIENTABLE (widget);
-
-      state = ATK_STATE_HORIZONTAL;
-      value = (gtk_orientable_get_orientation (orientable) == GTK_ORIENTATION_HORIZONTAL);
-    }
-  else if (g_strcmp0 (pspec->name, "has-tooltip") == 0)
-    {
-      state = ATK_STATE_HAS_TOOLTIP;
-      value = gtk_widget_get_has_tooltip (widget);
-    }
-  else
-    return;
-
-  atk_object_notify_state_change (atk_obj, state, value);
-  if (state == ATK_STATE_SENSITIVE)
-    atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);
-
-  if (state == ATK_STATE_HORIZONTAL)
-    atk_object_notify_state_change (atk_obj, ATK_STATE_VERTICAL, !value);
-}
-
 static AtkAttributeSet *
 gtk_widget_accessible_get_attributes (AtkObject *obj)
 {
@@ -550,6 +559,13 @@ gtk_widget_accessible_ref_child (AtkObject *object,
   return NULL;
 }
 
+static void
+gtk_widget_accessible_notify_gtk (GObject    *gobject,
+                                  GParamSpec *pspec)
+{
+  /* Empty, used to chain up safely */
+}
+
 static void
 gtk_widget_accessible_class_init (GtkWidgetAccessibleClass *klass)
 {
diff --git a/gtk/a11y/gtkwidgetaccessibleprivate.h b/gtk/a11y/gtkwidgetaccessibleprivate.h
index e1f210bb35..e60abcb337 100644
--- a/gtk/a11y/gtkwidgetaccessibleprivate.h
+++ b/gtk/a11y/gtkwidgetaccessibleprivate.h
@@ -25,9 +25,19 @@ G_BEGIN_DECLS
 void _gtk_widget_accessible_set_layer (GtkWidgetAccessible *accessible,
                                        AtkLayer             layer);
 
-void    gtk_widget_accessible_update_bounds     (GtkWidgetAccessible *self);
+void    gtk_widget_accessible_update_bounds             (GtkWidgetAccessible *self);
 
-void    gtk_widget_accessible_notify_showing    (GtkWidgetAccessible *self);
+void    gtk_widget_accessible_notify_showing            (GtkWidgetAccessible *self);
+
+void    gtk_widget_accessible_notify_tooltip            (GtkWidgetAccessible *self);
+
+void    gtk_widget_accessible_notify_visible            (GtkWidgetAccessible *self);
+
+void    gtk_widget_accessible_notify_sensitive          (GtkWidgetAccessible *self);
+
+void    gtk_widget_accessible_notify_focus              (GtkWidgetAccessible *self);
+
+void    gtk_widget_accessible_notify_orientation        (GtkWidgetAccessible *self);
 
 G_END_DECLS
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index a56c55d06d..960232e942 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2634,6 +2634,9 @@ gtk_widget_show (GtkWidget *widget)
       g_signal_emit (widget, widget_signals[SHOW], 0);
       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
 
+      if (priv->accessible != NULL)
+        gtk_widget_accessible_notify_visible (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
       gtk_widget_pop_verify_invariants (widget);
       g_object_unref (widget);
     }
@@ -2694,6 +2697,9 @@ gtk_widget_hide (GtkWidget *widget)
       g_signal_emit (widget, widget_signals[HIDE], 0);
       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
 
+      if (priv->accessible != NULL)
+        gtk_widget_accessible_notify_visible (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
       parent = gtk_widget_get_parent (widget);
       if (parent)
        gtk_widget_queue_resize (parent);
@@ -5687,6 +5693,9 @@ gtk_widget_set_sensitive (GtkWidget *widget,
       update_cursor_on_state_change (widget);
     }
 
+  if (priv->accessible != NULL)
+    gtk_widget_accessible_notify_sensitive (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_SENSITIVE]);
 }
 
@@ -9779,6 +9788,9 @@ gtk_widget_set_has_tooltip (GtkWidget *widget,
     {
       priv->has_tooltip = has_tooltip;
 
+      if (priv->accessible != NULL)
+        gtk_widget_accessible_notify_tooltip (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
       g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HAS_TOOLTIP]);
     }
 }
@@ -10375,6 +10387,10 @@ gtk_widget_set_has_focus (GtkWidget *widget,
     return;
 
   priv->has_focus = has_focus;
+
+  if (priv->accessible != NULL)
+    gtk_widget_accessible_notify_focus (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
   g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_HAS_FOCUS]);
 }
 
@@ -12787,6 +12803,8 @@ void
 gtk_widget_update_orientation (GtkWidget      *widget,
                                GtkOrientation  orientation)
 {
+  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
@@ -12799,4 +12817,7 @@ gtk_widget_update_orientation (GtkWidget      *widget,
       gtk_widget_add_css_class (widget, GTK_STYLE_CLASS_VERTICAL);
       gtk_widget_remove_css_class (widget, GTK_STYLE_CLASS_HORIZONTAL);
     }
+
+  if (priv->accessible != NULL)
+    gtk_widget_accessible_notify_orientation (GTK_WIDGET_ACCESSIBLE (priv->accessible));
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]