[gtk+] a11y: Redo TextView cursor/selection signal handling
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] a11y: Redo TextView cursor/selection signal handling
- Date: Wed, 6 Jul 2011 14:50:59 +0000 (UTC)
commit 30930e643f99ee1ae05e5eeed2893b00a10fd2d7
Author: Benjamin Otte <otte redhat com>
Date: Tue Jul 5 23:43:07 2011 +0200
a11y: Redo TextView cursor/selection signal handling
As part of the removal of idles, redo how we emit signals on the
accessible. Should work as good or better than before, but with a lot
less code.
gtk/a11y/gtktextviewaccessible.c | 228 ++++++++------------------------------
gtk/a11y/gtktextviewaccessible.h | 12 +--
2 files changed, 47 insertions(+), 193 deletions(-)
---
diff --git a/gtk/a11y/gtktextviewaccessible.c b/gtk/a11y/gtktextviewaccessible.c
index 4f4e9f4..def856f 100644
--- a/gtk/a11y/gtktextviewaccessible.c
+++ b/gtk/a11y/gtktextviewaccessible.c
@@ -40,13 +40,10 @@ static void delete_range_cb (GtkTextBuffer *buffer,
GtkTextIter *arg1,
GtkTextIter *arg2,
gpointer user_data);
-static void changed_cb (GtkTextBuffer *buffer,
- gpointer user_data);
static void mark_set_cb (GtkTextBuffer *buffer,
GtkTextIter *arg1,
GtkTextMark *arg2,
gpointer user_data);
-static gint insert_idle_handler (gpointer data);
static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
@@ -71,17 +68,6 @@ gtk_text_view_accessible_initialize (AtkObject *obj,
}
static void
-gtk_text_view_accessible_finalize (GObject *object)
-{
- GtkTextViewAccessible *text_view = GTK_TEXT_VIEW_ACCESSIBLE (object);
-
- if (text_view->insert_notify_handler)
- g_source_remove (text_view->insert_notify_handler);
-
- G_OBJECT_CLASS (gtk_text_view_accessible_parent_class)->finalize (object);
-}
-
-static void
gtk_text_view_accessible_notify_gtk (GObject *obj,
GParamSpec *pspec)
{
@@ -126,12 +112,9 @@ gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
static void
gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
- gobject_class->finalize = gtk_text_view_accessible_finalize;
-
class->ref_state_set = gtk_text_view_accessible_ref_state_set;
class->initialize = gtk_text_view_accessible_initialize;
@@ -141,10 +124,6 @@ gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
static void
gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
{
- accessible->signal_name = NULL;
- accessible->previous_insert_offset = -1;
- accessible->previous_selection_bound = -1;
- accessible->insert_notify_handler = 0;
}
static void
@@ -156,10 +135,9 @@ setup_buffer (GtkTextView *view,
buffer = gtk_text_view_get_buffer (view);
/* Set up signal callbacks */
- g_signal_connect (buffer, "insert-text", G_CALLBACK (insert_text_cb), view);
+ g_signal_connect_after (buffer, "insert-text", G_CALLBACK (insert_text_cb), view);
g_signal_connect (buffer, "delete-range", G_CALLBACK (delete_range_cb), view);
- g_signal_connect (buffer, "mark-set", G_CALLBACK (mark_set_cb), view);
- g_signal_connect (buffer, "changed", G_CALLBACK (changed_cb), view);
+ g_signal_connect_after (buffer, "mark-set", G_CALLBACK (mark_set_cb), view);
}
static gchar *
@@ -1163,6 +1141,35 @@ atk_editable_text_interface_init (AtkEditableTextIface *iface)
/* Callbacks */
static void
+gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
+ GtkTextBuffer * buffer)
+{
+ int prev_insert_offset, prev_selection_bound;
+ int insert_offset, selection_bound;
+ GtkTextIter iter;
+
+ prev_insert_offset = accessible->insert_offset;
+ prev_selection_bound = accessible->selection_bound;
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
+ insert_offset = gtk_text_iter_get_offset (&iter);
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
+ selection_bound = gtk_text_iter_get_offset (&iter);
+
+ if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
+ return;
+
+ accessible->insert_offset = insert_offset;
+ accessible->selection_bound = selection_bound;
+
+ if (prev_insert_offset != insert_offset)
+ g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
+
+ if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
+ g_signal_emit_by_name (accessible, "text-selection-changed");
+}
+
+static void
insert_text_cb (GtkTextBuffer *buffer,
GtkTextIter *iter,
gchar *text,
@@ -1176,33 +1183,12 @@ insert_text_cb (GtkTextBuffer *buffer,
accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
- accessible->signal_name = "text_changed::insert";
position = gtk_text_iter_get_offset (iter);
length = g_utf8_strlen (text, len);
- if (accessible->length == 0)
- {
- accessible->position = position;
- accessible->length = length;
- }
- else if (accessible->position + accessible->length == position)
- {
- accessible->length += length;
- }
- else
- {
- /*
- * We have a non-contiguous insert so report what we have
- */
- if (accessible->insert_notify_handler)
- {
- g_source_remove (accessible->insert_notify_handler);
- }
- accessible->insert_notify_handler = 0;
- insert_idle_handler (accessible);
- accessible->position = position;
- accessible->length = length;
- }
+ g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
+
+ gtk_text_view_accessible_update_cursor (accessible, buffer);
}
static void
@@ -1211,73 +1197,21 @@ delete_range_cb (GtkTextBuffer *buffer,
GtkTextIter *end,
gpointer data)
{
- GtkTextView *text = data;
+ GtkTextView *view = data;
GtkTextViewAccessible *accessible;
- gint offset;
- gint length;
+ gint offset, length;
+ accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
offset = gtk_text_iter_get_offset (start);
length = gtk_text_iter_get_offset (end) - offset;
- accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (text)));
- if (accessible->insert_notify_handler)
- {
- g_source_remove (accessible->insert_notify_handler);
- accessible->insert_notify_handler = 0;
- if (accessible->position == offset &&
- accessible->length == length)
- {
- /*
- * Do not bother with insert and delete notifications
- */
- accessible->signal_name = NULL;
- accessible->position = 0;
- accessible->length = 0;
- return;
- }
-
- insert_idle_handler (accessible);
- }
- g_signal_emit_by_name (accessible, "text_changed::delete", offset, length);
-}
-
-static gint
-get_selection_bound (GtkTextBuffer *buffer)
-{
- GtkTextMark *bound;
- GtkTextIter iter;
-
- bound = gtk_text_buffer_get_selection_bound (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, bound);
- return gtk_text_iter_get_offset (&iter);
-}
-
-static void
-emit_text_caret_moved (GtkTextViewAccessible *accessible,
- gint offset)
-{
- /*
- * If we have text which has been inserted notify the user
- */
- if (accessible->insert_notify_handler)
- {
- g_source_remove (accessible->insert_notify_handler);
- accessible->insert_notify_handler = 0;
- insert_idle_handler (accessible);
- }
+ g_signal_emit_by_name (accessible,
+ "text_changed::delete",
+ offset,
+ length);
- if (offset != accessible->previous_insert_offset)
- {
- /*
- * If the caret position has not changed then don't bother notifying
- *
- * When mouse click is used to change caret position, notification
- * is received on button down and button up.
- */
- g_signal_emit_by_name (accessible, "text_caret_moved", offset);
- accessible->previous_insert_offset = offset;
- }
+ gtk_text_view_accessible_update_cursor (accessible, buffer);
}
static void
@@ -1297,84 +1231,12 @@ mark_set_cb (GtkTextBuffer *buffer,
*/
if (mark == gtk_text_buffer_get_insert (buffer))
{
- gint insert_offset, selection_bound;
- gboolean selection_changed;
-
- insert_offset = gtk_text_iter_get_offset (location);
-
- selection_bound = get_selection_bound (buffer);
- if (selection_bound != insert_offset)
- {
- if (selection_bound != accessible->previous_selection_bound ||
- insert_offset != accessible->previous_insert_offset)
- selection_changed = TRUE;
- else
- selection_changed = FALSE;
- }
- else if (accessible->previous_selection_bound != accessible->previous_insert_offset)
- selection_changed = TRUE;
- else
- selection_changed = FALSE;
-
- emit_text_caret_moved (accessible, insert_offset);
- /*
- * insert and selection_bound marks are different to a selection
- * has changed
- */
- if (selection_changed)
- g_signal_emit_by_name (accessible, "text_selection_changed");
- accessible->previous_selection_bound = selection_bound;
+ gtk_text_view_accessible_update_cursor (accessible, buffer);
}
-}
-
-static void
-changed_cb (GtkTextBuffer *buffer,
- gpointer data)
-{
- GtkTextView *text = data;
- GtkTextViewAccessible *accessible;
-
- accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (text)));
- if (accessible->signal_name)
+ else if (mark == gtk_text_buffer_get_selection_bound (buffer))
{
- if (!accessible->insert_notify_handler)
- {
- accessible->insert_notify_handler = gdk_threads_add_idle (insert_idle_handler, accessible);
- }
- return;
+ gtk_text_view_accessible_update_cursor (accessible, buffer);
}
- emit_text_caret_moved (accessible, get_insert_offset (buffer));
- accessible->previous_selection_bound = get_selection_bound (buffer);
-}
-
-static gint
-insert_idle_handler (gpointer data)
-{
- GtkTextViewAccessible *accessible = data;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
-
- g_signal_emit_by_name (data,
- accessible->signal_name,
- accessible->position,
- accessible->length);
- accessible->signal_name = NULL;
- accessible->position = 0;
- accessible->length = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
- if (accessible->insert_notify_handler)
- {
- /*
- * If called from idle handler notify caret moved
- */
- accessible->insert_notify_handler = 0;
- emit_text_caret_moved (accessible, get_insert_offset (buffer));
- accessible->previous_selection_bound = get_selection_bound (buffer);
- }
-
- return FALSE;
}
static gint
diff --git a/gtk/a11y/gtktextviewaccessible.h b/gtk/a11y/gtktextviewaccessible.h
index 3f69fad..dd1ee9e 100644
--- a/gtk/a11y/gtktextviewaccessible.h
+++ b/gtk/a11y/gtktextviewaccessible.h
@@ -38,16 +38,8 @@ struct _GtkTextViewAccessible
{
GtkContainerAccessible parent;
- gint previous_insert_offset;
- gint previous_selection_bound;
- /*
- * These fields store information about text changed
- */
- gchar *signal_name;
- gint position;
- gint length;
-
- guint insert_notify_handler;
+ gint insert_offset;
+ gint selection_bound;
};
struct _GtkTextViewAccessibleClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]