From 0b0d4765a00706be78f2485ab0937bc8cbb04031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 29 May 2016 13:51:02 +0200 Subject: [PATCH] Add GtkStackAccessible Show only the currently visible child to a11y. --- gtk/a11y/Makefile.inc | 3 + gtk/a11y/gtkstackaccessible.c | 109 +++++++++++++++++++++++++++ gtk/a11y/gtkstackaccessible.h | 54 +++++++++++++ gtk/a11y/gtkstackaccessibleprivate.h | 32 ++++++++ gtk/gtkstack.c | 7 ++ 5 files changed, 205 insertions(+) create mode 100644 gtk/a11y/gtkstackaccessible.c create mode 100644 gtk/a11y/gtkstackaccessible.h create mode 100644 gtk/a11y/gtkstackaccessibleprivate.h diff --git a/gtk/a11y/Makefile.inc b/gtk/a11y/Makefile.inc index e13b14ce82..21c4014bc5 100644 --- a/gtk/a11y/Makefile.inc +++ b/gtk/a11y/Makefile.inc @@ -42,6 +42,8 @@ a11y_h_sources = \ a11y/gtkspinbuttonaccessible.h \ a11y/gtkspinneraccessible.h \ a11y/gtkstatusbaraccessible.h \ + a11y/gtkstackaccessible.h \ + a11y/gtkstackaccessibleprivate.h \ a11y/gtkswitchaccessible.h \ a11y/gtktextcellaccessible.h \ a11y/gtktextviewaccessible.h \ @@ -114,6 +116,7 @@ a11y_c_sources = \ a11y/gtkspinbuttonaccessible.c \ a11y/gtkspinneraccessible.c \ a11y/gtkstatusbaraccessible.c \ + a11y/gtkstackaccessible.c \ a11y/gtkswitchaccessible.c \ a11y/gtktextcellaccessible.c \ a11y/gtktextviewaccessible.c \ diff --git a/gtk/a11y/gtkstackaccessible.c b/gtk/a11y/gtkstackaccessible.c new file mode 100644 index 0000000000..11c25345d4 --- /dev/null +++ b/gtk/a11y/gtkstackaccessible.c @@ -0,0 +1,109 @@ +/* GTK+ - accessibility implementations + * Copyright (C) 2016 Timm Bäder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include +#include +#include "gtkstackaccessible.h" +#include "gtkwidgetprivate.h" + + +G_DEFINE_TYPE (GtkStackAccessible, gtk_stack_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE) + +static AtkObject* +gtk_stack_accessible_ref_child (AtkObject *obj, + int i) +{ + GtkWidget *stack = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + GtkWidget *visible_child; + + if (stack == NULL) + return NULL; + + if (i != 0) + return NULL; + + visible_child = gtk_stack_get_visible_child (GTK_STACK (stack)); + + if (visible_child == NULL) + return NULL; + + return g_object_ref (gtk_widget_get_accessible (visible_child)); +} + +static int +gtk_stack_accessible_get_n_children (AtkObject *obj) +{ + GtkWidget *stack = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + + if (stack == NULL) + return 0; + + if (gtk_stack_get_visible_child (GTK_STACK (stack))) + return 1; + + return 0; +} + +static void +gtk_stack_accessible_class_init (GtkStackAccessibleClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + GtkContainerAccessibleClass *container_class = (GtkContainerAccessibleClass*)klass; + + class->get_n_children = gtk_stack_accessible_get_n_children; + class->ref_child = gtk_stack_accessible_ref_child; + /* + * As we report the stack as having only the visible child, + * we are not interested in add and remove signals + */ + container_class->add_gtk = NULL; + container_class->remove_gtk = NULL; +} + +static void +gtk_stack_accessible_init (GtkStackAccessible *bar) {} + + +void +gtk_stack_accessible_update_visible_child (GtkStack *stack, + GtkWidget *old_visible_child, + GtkWidget *new_visible_child) +{ + AtkObject *stack_accessible = _gtk_widget_peek_accessible (GTK_WIDGET (stack)); + + if (stack_accessible == NULL) + return; + + if (old_visible_child) + { + AtkObject *accessible = gtk_widget_get_accessible (old_visible_child); + g_object_notify (G_OBJECT (accessible), "accessible-parent"); + g_signal_emit_by_name (stack_accessible, "children-changed::remove", 0, accessible, NULL); + } + + if (new_visible_child) + { + AtkObject *accessible = gtk_widget_get_accessible (new_visible_child); + g_object_notify (G_OBJECT (accessible), "accessible-parent"); + g_signal_emit_by_name (stack_accessible, "children-changed::add", 0, accessible, NULL); + } +} + + + diff --git a/gtk/a11y/gtkstackaccessible.h b/gtk/a11y/gtkstackaccessible.h new file mode 100644 index 0000000000..ebd8ab48a5 --- /dev/null +++ b/gtk/a11y/gtkstackaccessible.h @@ -0,0 +1,54 @@ +/* GTK+ - accessibility implementations + * Copyright (C) 2016 Timm Bäder + * + * 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_STACK_ACCESSIBLE_H__ +#define __GTK_STACK_ACCESSIBLE_H__ + +#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_STACK_ACCESSIBLE (gtk_stack_accessible_get_type ()) +#define GTK_STACK_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_STACK_ACCESSIBLE, GtkStackAccessible)) +#define GTK_STACK_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STACK_ACCESSIBLE, GtkStackAccessibleClass)) +#define GTK_IS_STACK_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_STACK_ACCESSIBLE)) +#define GTK_IS_STACK_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_STACK_ACCESSIBLE)) +#define GTK_STACK_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STACK_ACCESSIBLE, GtkStackAccessibleClass)) + +typedef struct _GtkStackAccessible GtkStackAccessible; +typedef struct _GtkStackAccessibleClass GtkStackAccessibleClass; + +struct _GtkStackAccessible +{ + GtkContainerAccessible parent; +}; + +struct _GtkStackAccessibleClass +{ + GtkContainerAccessibleClass parent_class; +}; + +GDK_AVAILABLE_IN_3_22 +GType gtk_stack_accessible_get_type (void); + +G_END_DECLS + +#endif diff --git a/gtk/a11y/gtkstackaccessibleprivate.h b/gtk/a11y/gtkstackaccessibleprivate.h new file mode 100644 index 0000000000..538c8b1c2d --- /dev/null +++ b/gtk/a11y/gtkstackaccessibleprivate.h @@ -0,0 +1,32 @@ +/* GTK+ - accessibility implementations + * Copyright (C) 2016 Timm Bäder + * + * 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_STACK_ACCESSIBLE_PRIVATE_H__ +#define __GTK_STACK_ACCESSIBLE_PRIVATE_H__ + +#include + +G_BEGIN_DECLS + +void gtk_stack_accessible_update_visible_child (GtkStack *stack, + GtkWidget *old_visible_child, + GtkWidget *new_visible_child); + + +G_END_DECLS + +#endif /* __GTK_STACK_ACCESSIBLE_PRIVATE_H__ */ diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c index 92bc911ff9..22e19a6bfa 100644 --- a/gtk/gtkstack.c +++ b/gtk/gtkstack.c @@ -30,6 +30,8 @@ #include "gtkprogresstrackerprivate.h" #include "gtksettingsprivate.h" #include "gtkwidgetprivate.h" +#include "a11y/gtkstackaccessible.h" +#include "a11y/gtkstackaccessibleprivate.h" #include #include @@ -557,6 +559,7 @@ gtk_stack_class_init (GtkStackClass *klass) gtk_container_class_install_child_properties (container_class, LAST_CHILD_PROP, stack_child_props); + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_STACK_ACCESSIBLE); gtk_widget_class_set_css_name (widget_class, "stack"); } @@ -1116,6 +1119,10 @@ set_visible_child (GtkStack *stack, } } + gtk_stack_accessible_update_visible_child (stack, + priv->visible_child ? priv->visible_child->widget : NULL, + child_info ? child_info->widget : NULL); + priv->visible_child = child_info; if (child_info)