[gtk/ebassi/new-a11y: 38/63] Have GtkWidget implement GtkAccessible



commit fba939f1a78a4319cc258adeedaf9620aa12536a
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Jul 8 16:58:11 2020 +0100

    Have GtkWidget implement GtkAccessible
    
    Each widget type has an accessible role associated to its class, as
    roles cannot change during the life time of a widget instance.
    
    Each widget is also responsible for creating an ATContext, to proxy
    state changes to the underlying accessibility infrastructure.

 gtk/gtkwidget.c        | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkwidget.h        |  4 ++++
 gtk/gtkwidgetprivate.h |  5 +++++
 3 files changed, 56 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 698baf8ef5..54e57cbab9 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -27,7 +27,7 @@
 #include "gtkwidgetprivate.h"
 
 #include "gtkaccelgroupprivate.h"
-#include "gtkaccessible.h"
+#include "gtkaccessibleprivate.h"
 #include "gtkapplicationprivate.h"
 #include "gtkbuildable.h"
 #include "gtkbuilderprivate.h"
@@ -755,6 +755,8 @@ gtk_widget_base_class_init (gpointer g_class)
           g_object_unref (shortcut);
         }
     }
+
+  priv->accessible_role = GTK_ACCESSIBLE_ROLE_WIDGET;
 }
 
 static void
@@ -6999,6 +7001,8 @@ gtk_widget_dispose (GObject *object)
     gtk_layout_manager_set_widget (priv->layout_manager, NULL);
   g_clear_object (&priv->layout_manager);
 
+  g_clear_object (&priv->at_context);
+
   priv->visible = FALSE;
   if (_gtk_widget_get_realized (widget))
     gtk_widget_unrealize (widget);
@@ -8052,9 +8056,29 @@ gtk_widget_set_vexpand_set (GtkWidget      *widget,
 /*
  * GtkAccessible implementation
  */
+
+static GtkATContext *
+gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
+{
+  GtkWidget *self = GTK_WIDGET (accessible);
+  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (self);
+
+  if (priv->at_context == NULL)
+    {
+      GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self);
+      GtkWidgetClassPrivate *class_priv = widget_class->priv;
+
+      priv->at_context =
+        gtk_at_context_create (class_priv->accessible_role, accessible);
+    }
+
+  return priv->at_context;
+}
+
 static void
 gtk_widget_accessible_interface_init (GtkAccessibleInterface *iface)
 {
+  iface->get_at_context = gtk_widget_accessible_get_at_context;
 }
 
 /*
@@ -12084,3 +12108,25 @@ gtk_widget_update_orientation (GtkWidget      *widget,
       gtk_widget_remove_css_class (widget, GTK_STYLE_CLASS_HORIZONTAL);
     }
 }
+
+/**
+ * gtk_widget_class_set_accessible_role:
+ * @widget_class: a #GtkWidgetClass
+ * @accessible_role: the #GtkAccessibleRole used by the @widget_class
+ *
+ * Sets the accessible role used by the given #GtkWidget class.
+ *
+ * Different accessible roles have different states, and are rendered
+ * differently by assistive technologies.
+ */
+void
+gtk_widget_class_set_accessible_role (GtkWidgetClass    *widget_class,
+                                      GtkAccessibleRole  accessible_role)
+{
+  GtkWidgetClassPrivate *priv;
+
+  g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
+
+  priv = widget_class->priv;
+  priv->accessible_role = accessible_role;
+}
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 384619f2d2..a897237860 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -977,6 +977,10 @@ void                    gtk_widget_action_set_enabled (GtkWidget  *widget,
                                                        gboolean    enabled);
 
 
+GDK_AVAILABLE_IN_ALL
+void                    gtk_widget_class_set_accessible_role    (GtkWidgetClass    *widget_class,
+                                                                 GtkAccessibleRole  accessible_role);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index a21badafb0..f0df306bde 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -28,6 +28,7 @@
 #include "gtkwidget.h"
 
 #include "gtkactionmuxerprivate.h"
+#include "gtkatcontextprivate.h"
 #include "gtkcsstypesprivate.h"
 #include "gtkeventcontrollerprivate.h"
 #include "gtklistlistmodelprivate.h"
@@ -189,6 +190,9 @@ struct _GtkWidgetPrivate
   /* Tooltip */
   char *tooltip_markup;
   char *tooltip_text;
+
+  /* Accessible context */
+  GtkATContext *at_context;
 };
 
 typedef struct
@@ -205,6 +209,7 @@ struct _GtkWidgetClassPrivate
   GQuark css_name;
   GType layout_manager_type;
   GtkWidgetAction *actions;
+  GtkAccessibleRole accessible_role;
 };
 
 void          gtk_widget_root               (GtkWidget *widget);


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