From ce4c2292416969901af2c55735905fae5b7ed594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Mon, 7 Apr 2014 18:29:30 +0200 Subject: a11y: managing atk states on EvPageAccessible This includes: * Implements ref_state_set on EvPageAccessible * Notify FOCUSED state changes https://bugzilla.gnome.org/show_bug.cgi?id=724965 origin commit: https://git.gnome.org/browse/evince/commit/?h=gnome-3-14&id=c421a90 --- libview/ev-page-accessible.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ libview/ev-view-accessible.c | 47 ++++++++++++++++++++++++++++++++++++++++++ libview/ev-view-accessible.h | 1 + 3 files changed, 97 insertions(+) diff --git a/libview/ev-page-accessible.c b/libview/ev-page-accessible.c index 77ae988f..2fcc0680 100644 --- a/libview/ev-page-accessible.c +++ b/libview/ev-page-accessible.c @@ -180,6 +180,54 @@ ev_page_accessible_ref_relation_set (AtkObject *accessible) return relation_set; } +/* page accessible's state set is a copy ev-view accessible's state + * set but removing ATK_STATE_SHOWING if the page is not on screen and + * ATK_STATE_FOCUSED if it is not the relevant page. */ +static AtkStateSet * +ev_page_accessible_ref_state_set (AtkObject *accessible) +{ + AtkStateSet *state_set; + AtkStateSet *copy_set; + AtkStateSet *view_accessible_state_set; + EvPageAccessible *self; + EvView *view; + gint relevant_page; + + g_return_val_if_fail (EV_IS_PAGE_ACCESSIBLE (accessible), NULL); + self = EV_PAGE_ACCESSIBLE (accessible); + view = ev_page_accessible_get_view (self); + + state_set = ATK_OBJECT_CLASS (ev_page_accessible_parent_class)->ref_state_set (accessible); + atk_state_set_clear_states (state_set); + + view_accessible_state_set = atk_object_ref_state_set (ATK_OBJECT (self->priv->view_accessible)); + copy_set = atk_state_set_or_sets (state_set, view_accessible_state_set); + + if (self->priv->page >= view->start_page && self->priv->page <= view->end_page) + atk_state_set_add_state (copy_set, ATK_STATE_SHOWING); + else + atk_state_set_remove_state (copy_set, ATK_STATE_SHOWING); + + relevant_page = ev_view_accessible_get_relevant_page (self->priv->view_accessible); + if (atk_state_set_contains_state (view_accessible_state_set, ATK_STATE_FOCUSED) && + self->priv->page == relevant_page) + atk_state_set_add_state (copy_set, ATK_STATE_FOCUSED); + else + atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSED); + + relevant_page = ev_view_accessible_get_relevant_page (self->priv->view_accessible); + if (atk_state_set_contains_state (view_accessible_state_set, ATK_STATE_FOCUSED) && + self->priv->page == relevant_page) + atk_state_set_add_state (copy_set, ATK_STATE_FOCUSED); + else + atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSED); + + g_object_unref (state_set); + g_object_unref (view_accessible_state_set); + + return copy_set; +} + static void ev_page_accessible_class_init (EvPageAccessibleClass *klass) { @@ -190,6 +238,7 @@ ev_page_accessible_class_init (EvPageAccessibleClass *klass) atk_class->get_parent = ev_page_accessible_get_parent; atk_class->ref_relation_set = ev_page_accessible_ref_relation_set; + atk_class->ref_state_set = ev_page_accessible_ref_state_set; g_object_class->get_property = ev_page_accessible_get_property; g_object_class->set_property = ev_page_accessible_set_property; diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c index 3f448379..ae55ddd4 100644 --- a/libview/ev-view-accessible.c +++ b/libview/ev-view-accessible.c @@ -310,7 +310,16 @@ ev_view_accessible_cursor_moved (EvView *view, EvPageAccessible *page_accessible = NULL; if (priv->previous_cursor_page != page) { + AtkObject *previous_page = NULL; + AtkObject *current_page = NULL; + + previous_page = g_ptr_array_index (priv->children, + priv->previous_cursor_page); + atk_object_notify_state_change (previous_page, ATK_STATE_FOCUSED, FALSE); priv->previous_cursor_page = page; + current_page = g_ptr_array_index (priv->children, page); + atk_object_notify_state_change (current_page, ATK_STATE_FOCUSED, TRUE); + /* +1 as user start to count on 1, but evince starts on 0 */ g_signal_emit_by_name (accessible, "page-changed", page + 1); } @@ -410,6 +419,27 @@ ev_view_accessible_set_model (EvViewAccessible *accessible, accessible); } +static gboolean +ev_view_accessible_focus_changed (GtkWidget *widget, + GdkEventFocus *event, + EvViewAccessible *self) +{ + AtkObject *page_accessible; + + g_return_val_if_fail (EV_IS_VIEW (widget), FALSE); + g_return_val_if_fail (EV_IS_VIEW_ACCESSIBLE (self), FALSE); + + if (self->priv->children == NULL) + return FALSE; + + page_accessible = g_ptr_array_index (self->priv->children, + get_relevant_page (EV_VIEW (widget))); + atk_object_notify_state_change (page_accessible, + ATK_STATE_FOCUSED, event->in); + + return FALSE; +} + AtkObject * ev_view_accessible_new (GtkWidget *widget) { @@ -427,6 +457,12 @@ ev_view_accessible_new (GtkWidget *widget) g_signal_connect (widget, "selection-changed", G_CALLBACK (ev_view_accessible_selection_changed), accessible); + g_signal_connect (widget, "focus-in-event", + G_CALLBACK (ev_view_accessible_focus_changed), + accessible); + g_signal_connect (widget, "focus-out-event", + G_CALLBACK (ev_view_accessible_focus_changed), + accessible); view = EV_VIEW (widget); if (view->model) @@ -436,3 +472,14 @@ ev_view_accessible_new (GtkWidget *widget) return accessible; } +gint +ev_view_accessible_get_relevant_page (EvViewAccessible *accessible) +{ + EvView *view; + + g_return_val_if_fail (EV_IS_VIEW_ACCESSIBLE (accessible), -1); + + view = EV_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible))); + + return get_relevant_page (view); +} diff --git a/libview/ev-view-accessible.h b/libview/ev-view-accessible.h index 9b62d347..38af95a4 100644 --- a/libview/ev-view-accessible.h +++ b/libview/ev-view-accessible.h @@ -53,6 +53,7 @@ AtkObject *ev_view_accessible_new (GtkWidget *widget); void ev_view_accessible_set_model (EvViewAccessible *accessible, EvDocumentModel *model); gint ev_view_accessible_get_n_pages (EvViewAccessible *accessible); +gint ev_view_accessible_get_relevant_page (EvViewAccessible *accessible); #endif /* __EV_VIEW_ACCESSIBLE_H__ */ -- cgit v1.2.1