[gtksourceview/wip/search] search: async highlighting



commit fe936ebf28ca33479a11b21cfc79c6168cc584a6
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Wed Jun 19 18:33:49 2013 +0200

    search: async highlighting

 gtksourceview/gtksourcesearch.c |  156 ++++++++++++++++++++++++++++-----------
 1 files changed, 112 insertions(+), 44 deletions(-)
---
diff --git a/gtksourceview/gtksourcesearch.c b/gtksourceview/gtksourcesearch.c
index ad2e84f..7aa2beb 100644
--- a/gtksourceview/gtksourcesearch.c
+++ b/gtksourceview/gtksourcesearch.c
@@ -36,8 +36,16 @@ struct _GtkSourceSearchPrivate
        gint text_nb_lines;
        GtkTextSearchFlags flags;
 
-       /* Contains the remaining region to highlight */
-       GtkTextRegion *region;
+       /* The search occurrences are highlighted when they become visible. It
+        * would be useless to highlight all the buffer, if only a small part is
+        * visible, which is usually the case.
+        * region_not_highlighted is NULL if the search is disabled.
+        * region_to_highlight contains the region to highlight later (in an
+        * idle callback), so the highlighting is asynchronous.
+        */
+       GtkTextRegion *region_not_highlighted;
+       GtkTextRegion *region_to_highlight;
+       gulong idle_highlight_id;
 
        GtkTextTag *found_tag;
 };
@@ -115,10 +123,22 @@ text_tag_set_highest_priority (GtkTextTag    *tag,
 static void
 clear_search (GtkSourceSearch *search)
 {
-       if (search->priv->region != NULL)
+       if (search->priv->region_not_highlighted != NULL)
+       {
+               gtk_text_region_destroy (search->priv->region_not_highlighted, TRUE);
+               search->priv->region_not_highlighted = NULL;
+       }
+
+       if (search->priv->region_to_highlight != NULL)
+       {
+               gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+               search->priv->region_to_highlight = NULL;
+       }
+
+       if (search->priv->idle_highlight_id != 0)
        {
-               gtk_text_region_destroy (search->priv->region, TRUE);
-               search->priv->region = NULL;
+               g_source_remove (search->priv->idle_highlight_id);
+               search->priv->idle_highlight_id = 0;
        }
 
        if (search->priv->found_tag != NULL)
@@ -136,14 +156,14 @@ clear_search (GtkSourceSearch *search)
 }
 
 static void
-add_subregion (GtkSourceSearch *search,
-              GtkTextIter     *subregion_start,
-              GtkTextIter     *subregion_end)
+add_not_highlighted_subregion (GtkSourceSearch *search,
+                              GtkTextIter     *subregion_start,
+                              GtkTextIter     *subregion_end)
 {
        GtkTextIter start = *subregion_start;
        GtkTextIter end = *subregion_end;
 
-       if (search->priv->region == NULL)
+       if (search->priv->region_not_highlighted == NULL)
        {
                return;
        }
@@ -158,7 +178,7 @@ add_subregion (GtkSourceSearch *search,
                gtk_text_iter_forward_to_line_end (&end);
        }
 
-       gtk_text_region_add (search->priv->region, &start, &end);
+       gtk_text_region_add (search->priv->region_not_highlighted, &start, &end);
 
        gtk_text_iter_backward_lines (&start, search->priv->text_nb_lines);
        gtk_text_iter_forward_lines (&end, search->priv->text_nb_lines);
@@ -184,10 +204,10 @@ update (GtkSourceSearch *search)
                return;
        }
 
-       search->priv->region = gtk_text_region_new (search->priv->buffer);
+       search->priv->region_not_highlighted = gtk_text_region_new (search->priv->buffer);
 
        gtk_text_buffer_get_bounds (search->priv->buffer, &start, &end);
-       add_subregion (search, &start, &end);
+       add_not_highlighted_subregion (search, &start, &end);
 }
 
 static void
@@ -204,7 +224,7 @@ insert_text_after_cb (GtkSourceSearch *search,
        gtk_text_iter_backward_chars (&start,
                                      g_utf8_strlen (text, length));
 
-       add_subregion (search, &start, &end);
+       add_not_highlighted_subregion (search, &start, &end);
 }
 
 static void
@@ -212,7 +232,7 @@ delete_range_after_cb (GtkSourceSearch *search,
                       GtkTextIter     *start,
                       GtkTextIter     *end)
 {
-       add_subregion (search, start, end);
+       add_not_highlighted_subregion (search, start, end);
 }
 
 static void
@@ -242,12 +262,7 @@ _gtk_source_search_dispose (GObject *object)
 {
        GtkSourceSearch *search = GTK_SOURCE_SEARCH (object);
 
-       if (search->priv->region != NULL)
-       {
-               gtk_text_region_destroy (search->priv->region, TRUE);
-               search->priv->region = NULL;
-       }
-
+       clear_search (search);
        g_clear_object (&search->priv->buffer);
 
        G_OBJECT_CLASS (_gtk_source_search_parent_class)->dispose (object);
@@ -425,6 +440,15 @@ highlight_subregion (GtkSourceSearch *search,
 
        iter = *start;
 
+       if (search->priv->region_not_highlighted != NULL)
+       {
+               gtk_text_region_subtract (search->priv->region_not_highlighted, start, end);
+       }
+       else
+       {
+               g_warning ("search: region_not_highlighted is NULL");
+       }
+
        if (gtk_text_iter_is_end (end))
        {
                end = NULL;
@@ -455,6 +479,50 @@ highlight_subregion (GtkSourceSearch *search,
        } while (found);
 }
 
+static void
+highlight_region (GtkSourceSearch *search,
+                 GtkTextRegion   *region_to_highlight)
+{
+       gint nb_subregions = gtk_text_region_subregions (region_to_highlight);
+       GtkTextIter start_search;
+       GtkTextIter end_search;
+
+       if (nb_subregions == 0)
+       {
+               return;
+       }
+
+       gtk_text_region_nth_subregion (region_to_highlight,
+                                      0,
+                                      &start_search,
+                                      NULL);
+
+       gtk_text_region_nth_subregion (region_to_highlight,
+                                      nb_subregions - 1,
+                                      NULL,
+                                      &end_search);
+
+       gtk_text_iter_order (&start_search, &end_search);
+
+       highlight_subregion (search, &start_search, &end_search);
+}
+
+static gboolean
+idle_highlight_cb (GtkSourceSearch *search)
+{
+       search->priv->idle_highlight_id = 0;
+
+       if (search->priv->region_to_highlight != NULL)
+       {
+               highlight_region (search, search->priv->region_to_highlight);
+
+               gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+               search->priv->region_to_highlight = NULL;
+       }
+
+       return FALSE;
+}
+
 void
 _gtk_source_search_update_highlight (GtkSourceSearch   *search,
                                     const GtkTextIter *start,
@@ -462,20 +530,17 @@ _gtk_source_search_update_highlight (GtkSourceSearch   *search,
                                     gboolean           synchronous)
 {
        GtkTextRegion *region_to_highlight;
-       GtkTextIter start_search;
-       GtkTextIter end_search;
-       gint nb_subregions;
 
        g_return_if_fail (GTK_SOURCE_IS_SEARCH (search));
        g_return_if_fail (start != NULL);
        g_return_if_fail (end != NULL);
 
-       if (dispose_has_run (search) || search->priv->region == NULL)
+       if (dispose_has_run (search) || search->priv->region_not_highlighted == NULL)
        {
                return;
        }
 
-       region_to_highlight = gtk_text_region_intersect (search->priv->region,
+       region_to_highlight = gtk_text_region_intersect (search->priv->region_not_highlighted,
                                                         start,
                                                         end);
 
@@ -484,25 +549,28 @@ _gtk_source_search_update_highlight (GtkSourceSearch   *search,
                return;
        }
 
-       nb_subregions = gtk_text_region_subregions (region_to_highlight);
-       g_assert (nb_subregions >= 1);
-
-       gtk_text_region_nth_subregion (region_to_highlight,
-                                      0,
-                                      &start_search,
-                                      NULL);
-
-       gtk_text_region_nth_subregion (region_to_highlight,
-                                      nb_subregions - 1,
-                                      NULL,
-                                      &end_search);
-
-       gtk_text_iter_order (&start_search, &end_search);
-
-       highlight_subregion (search, &start_search, &end_search);
+       if (synchronous)
+       {
+               highlight_region (search, region_to_highlight);
+               gtk_text_region_destroy (region_to_highlight, TRUE);
+       }
+       else
+       {
+               if (search->priv->region_to_highlight != NULL)
+               {
+                       /* We destroy the old region to highlight, because it is
+                        * now useless to highlight it, the visible region on
+                        * the screen is the new region.
+                        */
+                       gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+               }
 
-       /* Remove the just highlighted region */
-       gtk_text_region_subtract (search->priv->region, start, end);
+               search->priv->region_to_highlight = region_to_highlight;
 
-       gtk_text_region_destroy (region_to_highlight, TRUE);
+               if (search->priv->idle_highlight_id == 0)
+               {
+                       search->priv->idle_highlight_id =
+                               g_idle_add ((GSourceFunc)idle_highlight_cb, search);
+               }
+       }
 }


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