[gtksourceview/wip/bug-732418: 2/2] gutter: always invalidate the whole GdkWindow



commit 1acdb5e2f835d52eb5242be4be777daf6d7bbd3e
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Thu Jul 17 17:20:25 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 |   64 ++++++++++++++++++++++++++++----------
 1 files changed, 47 insertions(+), 17 deletions(-)
---
diff --git a/gtksourceview/gtksourcegutter.c b/gtksourceview/gtksourcegutter.c
index 85ec699..d658930 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 */
 
 /**
@@ -904,7 +937,6 @@ on_view_draw (GtkSourceView   *view,
        GdkWindow *window;
        GtkTextView *text_view;
        GArray *sizes;
-       GdkRectangle clip;
        gint y1, y2;
        GArray *numbers;
        GArray *pixels;
@@ -936,18 +968,16 @@ on_view_draw (GtkSourceView   *view,
        gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window);
 
        text_view = GTK_TEXT_VIEW (view);
-
-       if (!gdk_cairo_get_clip_rectangle (cr, &clip))
-       {
-               return FALSE;
-       }
+       buffer = gtk_text_view_get_buffer (text_view);
 
        gutter->priv->is_drawing = TRUE;
 
-       buffer = gtk_text_view_get_buffer (text_view);
-
-       y1 = clip.y;
-       y2 = y1 + clip.height;
+       /* gdk_cairo_get_clip_rectangle() is not used, because when a drawing is
+        * needed the whole GdkWindow is always invalidated. See the comment at
+        * window_invalidate_handler().
+        */
+       y1 = 0;
+       y2 = gdk_window_get_height (window);
 
        /* get the extents of the line printing */
        gtk_text_view_window_to_buffer_coords (text_view,


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