[gtksourceview] gutter: always invalidate the whole GdkWindow



commit 822e4c5ee71ed4e447fd14a8dc1c1ded751efece
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Thu Jul 17 22:27:29 2014 +0200

    gutter: always invalidate the whole GdkWindow
    
    Call gdk_window_set_invalidate_handler() in update_gutter_size(),
    because the GdkWindow is created only when its size is greater than 0.
    update_gutter_size() is already called when the widget is realized, so
    it ensures that the invalidate handler is set at least once.
    
    The performances should not be a problem, because the gutter was already
    redrawn completely on each mouse motion event in the gutter (not when
    moving the mouse in the text view).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=732418

 gtksourceview/gtksourcegutter.c |   47 +++++++++++++++++++++++++++++++++-----
 1 files changed, 40 insertions(+), 7 deletions(-)
---
diff --git a/gtksourceview/gtksourcegutter.c b/gtksourceview/gtksourcegutter.c
index 85ec699..90ea9d1 100644
--- a/gtksourceview/gtksourcegutter.c
+++ b/gtksourceview/gtksourcegutter.c
@@ -123,6 +123,13 @@ static void on_view_style_updated (GtkSourceView    *view,
 static void do_redraw (GtkSourceGutter *gutter);
 static void update_gutter_size (GtkSourceGutter *gutter);
 
+static GdkWindow *
+get_window (GtkSourceGutter *gutter)
+{
+       return gtk_text_view_get_window (GTK_TEXT_VIEW (gutter->priv->view),
+                                        gutter->priv->window_type);
+}
+
 static void
 on_renderer_size_changed (GtkSourceGutterRenderer *renderer,
                           GParamSpec              *spec,
@@ -388,15 +395,48 @@ calculate_gutter_size (GtkSourceGutter  *gutter,
 }
 
 static void
+window_invalidate_handler (GdkWindow      *window,
+                          cairo_region_t *region)
+{
+       cairo_rectangle_int_t rect;
+
+       /* Always invalidate the whole window.
+        * When the text is modified in a GtkTextBuffer, GtkTextView tries to
+        * redraw the smallest required region. But the information displayed in
+        * the gutter may become invalid in a bigger region.
+        * See https://bugzilla.gnome.org/show_bug.cgi?id=732418 for an example
+        * where line numbers are not updated correctly when splitting a wrapped
+        * line.
+        * The performances should not be a big problem here. Correctness is
+        * more important than performances.
+        */
+
+       rect.x = 0;
+       rect.y = 0;
+       rect.width = gdk_window_get_width (window);
+       rect.height = gdk_window_get_height (window);
+
+       cairo_region_union_rectangle (region, &rect);
+}
+
+static void
 update_gutter_size (GtkSourceGutter *gutter)
 {
        gint width;
+       GdkWindow *window;
 
        width = calculate_gutter_size (gutter, NULL);
 
        gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (gutter->priv->view),
                                              gutter->priv->window_type,
                                              width);
+
+       window = get_window (gutter);
+
+       if (window != NULL)
+       {
+               gdk_window_set_invalidate_handler (window, window_invalidate_handler);
+       }
 }
 
 static gboolean
@@ -613,13 +653,6 @@ gtk_source_gutter_new (GtkSourceView     *view,
                             NULL);
 }
 
-static GdkWindow *
-get_window (GtkSourceGutter *gutter)
-{
-       return gtk_text_view_get_window (GTK_TEXT_VIEW (gutter->priv->view),
-                                        gutter->priv->window_type);
-}
-
 /* Public API */
 
 /**


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