diff options
Diffstat (limited to 'libview/ev-view-accessible.c')
-rw-r--r-- | libview/ev-view-accessible.c | 746 |
1 files changed, 9 insertions, 737 deletions
diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c index 9be52581..afa52ef0 100644 --- a/libview/ev-view-accessible.c +++ b/libview/ev-view-accessible.c @@ -30,7 +30,6 @@ #include "ev-view-private.h" #include "ev-page-accessible.h" -static void ev_view_accessible_text_iface_init (AtkTextIface *iface); static void ev_view_accessible_action_iface_init (AtkActionIface *iface); static void ev_view_accessible_hypertext_iface_init (AtkHypertextIface *iface); static void ev_view_accessible_document_iface_init (AtkDocumentIface *iface); @@ -72,7 +71,6 @@ struct _EvViewAccessiblePrivate { }; G_DEFINE_TYPE_WITH_CODE (EvViewAccessible, ev_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE, - G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, ev_view_accessible_text_iface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, ev_view_accessible_action_iface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, ev_view_accessible_hypertext_iface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_DOCUMENT, ev_view_accessible_document_iface_init) @@ -188,718 +186,6 @@ ev_view_accessible_init (EvViewAccessible *accessible) accessible->priv = G_TYPE_INSTANCE_GET_PRIVATE (accessible, EV_TYPE_VIEW_ACCESSIBLE, EvViewAccessiblePrivate); } -/* ATs expect to be able to identify sentence boundaries based on content. Valid, - * content-based boundaries may be present at the end of a newline, for instance - * at the end of a heading within a document. Thus being able to distinguish hard - * returns from soft returns is necessary. However, the text we get from Poppler - * for non-tagged PDFs has "\n" inserted at the end of each line resulting in a - * broken accessibility implementation w.r.t. sentences. - */ -static gboolean -treat_as_soft_return (EvView *view, - PangoLogAttr *log_attrs, - gint offset) -{ - EvRectangle *areas = NULL; - guint n_areas = 0; - gdouble line_spacing, this_line_height, next_word_width; - EvRectangle *this_line_start; - EvRectangle *this_line_end; - EvRectangle *next_line_start; - EvRectangle *next_line_end; - EvRectangle *next_word_end; - gint prev_offset, next_offset; - - - if (!log_attrs[offset].is_white) - return FALSE; - - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); - if (n_areas <= offset + 1) - return FALSE; - - prev_offset = offset - 1; - next_offset = offset + 1; - - /* In wrapped text, the character at the start of the next line starts a word. - * Examples where this condition might fail include bullets and images. But it - * also includes things like "(", so also check the next character. - */ - if (!log_attrs[next_offset].is_word_start && - (next_offset + 1 >= n_areas || !log_attrs[next_offset + 1].is_word_start)) - return FALSE; - - /* In wrapped text, the chars on either side of the newline have very similar heights. - * Examples where this condition might fail include a newline at the end of a heading, - * and a newline at the end of a paragraph that is followed by a heading. - */ - this_line_end = areas + prev_offset; - next_line_start = areas + next_offset;; - - this_line_height = this_line_end->y2 - this_line_end->y1; - if (ABS (this_line_height - (next_line_start->y2 - next_line_start->y1)) > 0.25) - return FALSE; - - /* If there is significant white space between this line and the next, odds are this - * is not a soft return in wrapped text. Lines within a typical paragraph are at most - * double-spaced. If the spacing is more than that, assume a hard return is present. - */ - line_spacing = next_line_start->y1 - this_line_end->y2; - if (line_spacing - this_line_height > 1) - return FALSE; - - /* Lines within a typical paragraph have *reasonably* similar x1 coordinates. But - * we cannot count on them being nearly identical. Examples where indentation can - * be present in wrapped text include indenting the first line of the paragraph, - * and hanging indents (e.g. in the works cited within an academic paper). So we'll - * be somewhat tolerant here. - */ - for ( ; prev_offset > 0 && !log_attrs[prev_offset].is_mandatory_break; prev_offset--); - this_line_start = areas + prev_offset; - if (ABS (this_line_start->x1 - next_line_start->x1) > 20) - return FALSE; - - /* Ditto for x2, but this line might be short due to a wide word on the next line. */ - for ( ; next_offset < n_areas && !log_attrs[next_offset].is_word_end; next_offset++); - next_word_end = areas + next_offset; - next_word_width = next_word_end->x2 - next_line_start->x1; - - for ( ; next_offset < n_areas && !log_attrs[next_offset + 1].is_mandatory_break; next_offset++); - next_line_end = areas + next_offset; - if (next_line_end->x2 - (this_line_end->x2 + next_word_width) > 20) - return FALSE; - - return TRUE; -} - -static void -ev_view_accessible_get_range_for_boundary (AtkText *text, - AtkTextBoundary boundary_type, - gint offset, - gint *start_offset, - gint *end_offset) -{ - GtkWidget *widget; - EvView *view; - gint start = 0; - gint end = 0; - PangoLogAttr *log_attrs = NULL; - gulong n_attrs; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - return; - - view = EV_VIEW (widget); - if (!view->page_cache) - return; - - ev_page_cache_get_text_log_attrs (view->page_cache, get_relevant_page (view), &log_attrs, &n_attrs); - if (!log_attrs) - return; - - switch (boundary_type) { - case ATK_TEXT_BOUNDARY_CHAR: - start = offset; - end = offset + 1; - break; - case ATK_TEXT_BOUNDARY_WORD_START: - for (start = offset; start >= 0 && !log_attrs[start].is_word_start; start--); - for (end = offset + 1; end <= n_attrs && !log_attrs[end].is_word_start; end++); - break; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - for (start = offset; start >= 0; start--) { - if (log_attrs[start].is_mandatory_break && treat_as_soft_return (view, log_attrs, start - 1)) - continue; - if (log_attrs[start].is_sentence_start) - break; - } - for (end = offset + 1; end <= n_attrs; end++) { - if (log_attrs[end].is_mandatory_break && treat_as_soft_return (view, log_attrs, end - 1)) - continue; - if (log_attrs[end].is_sentence_start) - break; - } - break; - case ATK_TEXT_BOUNDARY_LINE_START: - for (start = offset; start >= 0 && !log_attrs[start].is_mandatory_break; start--); - for (end = offset + 1; end <= n_attrs && !log_attrs[end].is_mandatory_break; end++); - break; - default: - /* The "END" boundary types are deprecated */ - break; - } - - *start_offset = start; - *end_offset = end; -} - -static gchar * -ev_view_accessible_get_substring (AtkText *text, - gint start_offset, - gint end_offset) -{ - GtkWidget *widget; - EvView *view; - gchar *substring, *normalized; - const gchar* page_text; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - return NULL; - - view = EV_VIEW (widget); - if (!view->page_cache) - return NULL; - - page_text = ev_page_cache_get_text (view->page_cache, get_relevant_page (view)); - start_offset = MAX (0, start_offset); - if (end_offset < 0 || end_offset > g_utf8_strlen (page_text, -1)) - end_offset = strlen (page_text); - - substring = g_utf8_substring (page_text, start_offset, end_offset); - normalized = g_utf8_normalize (substring, -1, G_NORMALIZE_NFKC); - g_free (substring); - - return normalized; -} - -static gunichar -ev_view_accessible_get_character_at_offset (AtkText *text, - gint offset) -{ - gchar *string; - gunichar unichar; - - string = ev_view_accessible_get_substring (text, offset, offset + 1); - unichar = g_utf8_get_char (string); - g_free(string); - - return unichar; -} - -static gchar * -ev_view_accessible_get_text (AtkText *text, - gint start_pos, - gint end_pos) -{ - return ev_view_accessible_get_substring (text, start_pos, end_pos); -} - -static gchar * -ev_view_accessible_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - gchar *retval; - - ev_view_accessible_get_range_for_boundary (text, boundary_type, offset, start_offset, end_offset); - retval = ev_view_accessible_get_substring (text, *start_offset, *end_offset); - - /* If newlines appear inside the text of a sentence (i.e. between the start and - * end offsets returned by ev_view_accessible_get_substring), it interferes with - * the prosody of text-to-speech based-solutions such as a screen reader because - * speech synthesizers tend to pause after the newline char as if it were the end - * of the sentence. - */ - if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_START) - g_strdelimit (retval, "\n", ' '); - - return retval; -} - -static gint -ev_view_accessible_get_character_count (AtkText *text) -{ - GtkWidget *widget; - EvView *view; - gint retval; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return 0; - - view = EV_VIEW (widget); - retval = g_utf8_strlen (ev_page_cache_get_text (view->page_cache, get_relevant_page (view)), -1); - - return retval; -} - -static gint -ev_view_accessible_get_caret_offset (AtkText *text) -{ - GtkWidget *widget; - EvView *view; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return -1; - - view = EV_VIEW (widget); - if (view->caret_enabled) - return view->cursor_offset; - - return -1; -} - -static gboolean -ev_view_accessible_set_caret_offset (AtkText *text, gint offset) -{ - GtkWidget *widget; - EvView *view; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return FALSE; - - view = EV_VIEW (widget); - ev_view_set_caret_cursor_position (view, - view->cursor_page, - offset); - - return TRUE; -} - -static AtkAttributeSet * -add_attribute (AtkAttributeSet *attr_set, - AtkTextAttribute attr_type, - gchar *attr_value) -{ - AtkAttribute *attr = g_new (AtkAttribute, 1); - - attr->name = g_strdup (atk_text_attribute_get_name (attr_type)); - attr->value = attr_value; - - return g_slist_prepend (attr_set, attr); -} - -static AtkAttributeSet * -get_run_attributes (PangoAttrList *attrs, - const gchar *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - AtkAttributeSet *atk_attr_set = NULL; - PangoAttrString *pango_string; - PangoAttrInt *pango_int; - PangoAttrColor *pango_color; - PangoAttrIterator *iter; - gint i, start, end; - gboolean has_attrs = FALSE; - glong text_length; - gchar *attr_value; - - text_length = g_utf8_strlen (text, -1); - if (offset < 0 || offset >= text_length) - return NULL; - - /* Check if there are attributes for the offset, - * and set the attributes range if positive */ - iter = pango_attr_list_get_iterator (attrs); - i = g_utf8_offset_to_pointer (text, offset) - text; - - do { - pango_attr_iterator_range (iter, &start, &end); - if (i >= start && i < end) { - *start_offset = g_utf8_pointer_to_offset (text, text + start); - if (end == G_MAXINT) /* Last iterator */ - end = text_length; - *end_offset = g_utf8_pointer_to_offset (text, text + end); - has_attrs = TRUE; - } - } while (!has_attrs && pango_attr_iterator_next (iter)); - - if (!has_attrs) { - pango_attr_iterator_destroy (iter); - return NULL; - } - - /* Create the AtkAttributeSet from the Pango attributes */ - pango_string = (PangoAttrString *) pango_attr_iterator_get (iter, PANGO_ATTR_FAMILY); - if (pango_string) { - attr_value = g_strdup (pango_string->value); - atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_FAMILY_NAME, attr_value); - } - - pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_SIZE); - if (pango_int) { - attr_value = g_strdup_printf ("%i", pango_int->value / PANGO_SCALE); - atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_SIZE, attr_value); - } - - pango_int = (PangoAttrInt *) pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE); - if (pango_int) { - atk_attr_set = add_attribute (atk_attr_set, - ATK_TEXT_ATTR_UNDERLINE, - g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, - pango_int->value))); - } - - pango_color = (PangoAttrColor *) pango_attr_iterator_get (iter, PANGO_ATTR_FOREGROUND); - if (pango_color) { - attr_value = g_strdup_printf ("%u,%u,%u", - pango_color->color.red, - pango_color->color.green, - pango_color->color.blue); - atk_attr_set = add_attribute (atk_attr_set, ATK_TEXT_ATTR_FG_COLOR, attr_value); - } - - pango_attr_iterator_destroy (iter); - - return atk_attr_set; -} - -static AtkAttributeSet* -ev_view_accessible_get_run_attributes (AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - EvView *view; - GtkWidget *widget; - PangoAttrList *attrs; - const gchar *page_text; - - if (offset < 0) - return NULL; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (!widget) - return NULL; - - view = EV_VIEW (widget); - if (!view->page_cache) - return NULL; - - page_text = ev_page_cache_get_text (view->page_cache, get_relevant_page (view)); - if (!page_text) - return NULL; - - attrs = ev_page_cache_get_text_attrs (view->page_cache, get_relevant_page (view)); - if (!attrs) - return NULL; - - return get_run_attributes (attrs, page_text, offset, start_offset, end_offset); -} - -static AtkAttributeSet* -ev_view_accessible_get_default_attributes (AtkText *text) -{ - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return NULL; - return NULL; -} - -static void -ev_view_accessible_get_character_extents (AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords) -{ - GtkWidget *widget, *toplevel; - EvView *view; - EvRectangle *areas = NULL; - EvRectangle *doc_rect; - guint n_areas = 0; - gint x_widget, y_widget; - GdkRectangle view_rect; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return; - - view = EV_VIEW (widget); - if (!view->page_cache) - return; - - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); - if (!areas || offset >= n_areas) - return; - - doc_rect = areas + offset; - _ev_view_transform_doc_rect_to_view_rect (view, get_relevant_page (view), doc_rect, &view_rect); - view_rect.x -= view->scroll_x; - view_rect.y -= view->scroll_y; - - toplevel = gtk_widget_get_toplevel (widget); - gtk_widget_translate_coordinates (widget, toplevel, 0, 0, &x_widget, &y_widget); - view_rect.x += x_widget; - view_rect.y += y_widget; - - if (coords == ATK_XY_SCREEN) { - gint x_window, y_window; - - gdk_window_get_origin (gtk_widget_get_window (toplevel), &x_window, &y_window); - view_rect.x += x_window; - view_rect.y += y_window; - } - - *x = view_rect.x; - *y = view_rect.y; - *width = view_rect.width; - *height = view_rect.height; -} - -static gint -ev_view_accessible_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - GtkWidget *widget, *toplevel; - EvView *view; - EvRectangle *areas = NULL; - EvRectangle *rect = NULL; - guint n_areas = 0; - guint i; - gint x_widget, y_widget; - gint offset=-1; - GdkPoint view_point; - gdouble doc_x, doc_y; - GtkBorder border; - GdkRectangle page_area; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return -1; - - view = EV_VIEW (widget); - if (!view->page_cache) - return -1; - - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); - if (!areas) - return -1; - - view_point.x = x; - view_point.y = y; - toplevel = gtk_widget_get_toplevel (widget); - gtk_widget_translate_coordinates (widget, toplevel, 0, 0, &x_widget, &y_widget); - view_point.x -= x_widget; - view_point.y -= y_widget; - - if (coords == ATK_XY_SCREEN) { - gint x_window, y_window; - - gdk_window_get_origin (gtk_widget_get_window (toplevel), &x_window, &y_window); - view_point.x -= x_window; - view_point.y -= y_window; - } - - ev_view_get_page_extents (view, get_relevant_page (view), &page_area, &border); - _ev_view_transform_view_point_to_doc_point (view, &view_point, &page_area, &doc_x, &doc_y); - - for (i = 0; i < n_areas; i++) { - rect = areas + i; - if (doc_x >= rect->x1 && doc_x <= rect->x2 && - doc_y >= rect->y1 && doc_y <= rect->y2) - offset = i; - } - - return offset; -} - -static gint -ev_view_accessible_get_n_selections (AtkText *text) -{ - GtkWidget *widget; - EvView *view; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return -1; - - view = EV_VIEW (widget); - if (!EV_IS_SELECTION (view->document) || !view->selection_info.selections) - return 0; - - return 1; -} - -static gboolean -get_selection_bounds (EvView *view, - EvViewSelection *selection, - gint *start_offset, - gint *end_offset) -{ - cairo_rectangle_int_t rect; - gint start, end; - - if (!selection->covered_region || cairo_region_is_empty (selection->covered_region)) - return FALSE; - - cairo_region_get_rectangle (selection->covered_region, 0, &rect); - start = _ev_view_get_caret_cursor_offset_at_doc_point (view, - selection->page, - rect.x / view->scale, - (rect.y + (rect.height / 2)) / view->scale); - if (start == -1) - return FALSE; - - cairo_region_get_rectangle (selection->covered_region, - cairo_region_num_rectangles (selection->covered_region) - 1, - &rect); - end = _ev_view_get_caret_cursor_offset_at_doc_point (view, - selection->page, - (rect.x + rect.width) / view->scale, - (rect.y + (rect.height / 2)) / view->scale); - if (end == -1) - return FALSE; - - *start_offset = start; - *end_offset = end; - - return TRUE; -} - -static gchar * -ev_view_accessible_get_selection (AtkText *text, - gint selection_num, - gint *start_pos, - gint *end_pos) -{ - GtkWidget *widget; - EvView *view; - gchar *selected_text = NULL; - gchar *normalized_text = NULL; - GList *l; - - *start_pos = -1; - *end_pos = -1; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return NULL; - - if (selection_num != 0) - return NULL; - - view = EV_VIEW (widget); - if (!EV_IS_SELECTION (view->document) || !view->selection_info.selections) - return NULL; - - - for (l = view->selection_info.selections; l != NULL; l = l->next) { - EvViewSelection *selection = (EvViewSelection *)l->data; - gint start, end; - - if (selection->page != get_relevant_page (view)) - continue; - - if (get_selection_bounds (view, selection, &start, &end) && start != end) { - EvPage *page; - - page = ev_document_get_page (view->document, selection->page); - - ev_document_doc_mutex_lock (); - selected_text = ev_selection_get_selected_text (EV_SELECTION (view->document), - page, - selection->style, - &(selection->rect)); - - ev_document_doc_mutex_unlock (); - - g_object_unref (page); - - *start_pos = start; - *end_pos = end; - } - - break; - } - - if (selected_text) { - normalized_text = g_utf8_normalize (selected_text, -1, G_NORMALIZE_NFKC); - g_free (selected_text); - } - - return normalized_text; -} - -/* ATK allows for multiple, non-contiguous selections within a single AtkText - * object. Unless and until Evince supports this, selection numbers are ignored. - */ -static gboolean -ev_view_accessible_remove_selection (AtkText *text, - gint selection_num) -{ - GtkWidget *widget; - EvView *view; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return FALSE; - - view = EV_VIEW (widget); - if (ev_view_get_has_selection (view)) { - _ev_view_clear_selection (view); - return TRUE; - } - - return FALSE; -} - -static gboolean -ev_view_accessible_set_selection (AtkText *text, - gint selection_num, - gint start_pos, - gint end_pos) -{ - GtkWidget *widget; - EvView *view; - EvRectangle *areas = NULL; - guint n_areas = 0; - GdkRectangle start_rect, end_rect; - GdkPoint start_point, end_point; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return FALSE; - - view = EV_VIEW (widget); - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); - if (start_pos < 0 || end_pos >= n_areas) - return FALSE; - - _ev_view_transform_doc_rect_to_view_rect (view, get_relevant_page (view), areas + start_pos, &start_rect); - _ev_view_transform_doc_rect_to_view_rect (view, get_relevant_page (view), areas + end_pos - 1, &end_rect); - start_point.x = start_rect.x; - start_point.y = start_rect.y; - end_point.x = end_rect.x + end_rect.width; - end_point.y = end_rect.y + end_rect.height; - _ev_view_set_selection (view, &start_point, &end_point); - - return TRUE; -} - -static gboolean -ev_view_accessible_add_selection (AtkText *text, - gint start_pos, - gint end_pos) -{ - return ev_view_accessible_set_selection (text, 0, start_pos, end_pos); - -} - static gint ev_view_accessible_get_page_count (AtkDocument *atk_document) { @@ -930,26 +216,6 @@ ev_view_accessible_document_iface_init (AtkDocumentIface *iface) iface->get_page_count = ev_view_accessible_get_page_count; } -static void -ev_view_accessible_text_iface_init (AtkTextIface * iface) -{ - iface->get_text = ev_view_accessible_get_text; - iface->get_character_at_offset = ev_view_accessible_get_character_at_offset; - iface->get_text_at_offset = ev_view_accessible_get_text_at_offset; - iface->get_caret_offset = ev_view_accessible_get_caret_offset; - iface->set_caret_offset = ev_view_accessible_set_caret_offset; - iface->get_character_count = ev_view_accessible_get_character_count; - iface->get_n_selections = ev_view_accessible_get_n_selections; - iface->get_selection = ev_view_accessible_get_selection; - iface->add_selection = ev_view_accessible_add_selection; - iface->remove_selection = ev_view_accessible_remove_selection; - iface->set_selection = ev_view_accessible_set_selection; - iface->get_run_attributes = ev_view_accessible_get_run_attributes; - iface->get_default_attributes = ev_view_accessible_get_default_attributes; - iface->get_character_extents = ev_view_accessible_get_character_extents; - iface->get_offset_at_point = ev_view_accessible_get_offset_at_point; -} - static gboolean ev_view_accessible_idle_do_action (gpointer data) { @@ -1168,6 +434,7 @@ ev_view_accessible_cursor_moved (EvView *view, EvViewAccessible *accessible) { EvViewAccessiblePrivate* priv = accessible->priv; + EvPageAccessible *page_accessible = NULL; if (priv->previous_cursor_page != page) { priv->previous_cursor_page = page; @@ -1176,14 +443,19 @@ ev_view_accessible_cursor_moved (EvView *view, g_signal_emit_by_name (accessible, "page-changed", page + 1); } - g_signal_emit_by_name (accessible, "text-caret-moved", offset); + page_accessible = g_ptr_array_index (priv->children, page); + g_signal_emit_by_name (page_accessible, "text-caret-moved", offset); } static void ev_view_accessible_selection_changed (EvView *view, - EvViewAccessible *accessible) + EvViewAccessible *view_accessible) { - g_signal_emit_by_name (accessible, "text-selection-changed"); + AtkObject *page_accessible; + + page_accessible = g_ptr_array_index (view_accessible->priv->children, + get_relevant_page (view)); + g_signal_emit_by_name (page_accessible, "text-selection-changed"); } static void |