textview: Render visible marks better
authorMatthias Clasen <mclasen@redhat.com>
Fri, 3 Jan 2020 17:43:30 +0000 (12:43 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 3 Jan 2020 18:00:53 +0000 (13:00 -0500)
The only other visible mark that is in common use
besides insert and selection_bound is dnd_mark, and
we don't want it to blink or be affected by 'cursor'
visibility.

Therefore, cache not just the cursor positions, but
also whether they are insert or selection_bound,
and take that into account when rendering them.

gtk/gtktextlayout.c
gtk/gtktextlayoutprivate.h

index 7b60b13f3f4befacfafe33aef80dd2b1a727c1f7..6d4b41b65a5e62a830fa08e121edf50cdd0a5668 100644 (file)
@@ -1854,18 +1854,22 @@ add_cursor (GtkTextLayout      *layout,
             GtkTextLineSegment *seg,
             gint                start)
 {
+  CursorPosition cursor;
+
+  cursor.pos = start;
+  cursor.is_insert = _gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
+                                                     seg->body.mark.obj);
+  cursor.is_selection_bound = _gtk_text_btree_mark_is_selection_bound (_gtk_text_buffer_get_btree (layout->buffer),
+                                                                       seg->body.mark.obj);
+
   /* Hide insertion cursor when we have a selection or the layout
    * user has hidden the cursor.
    */
-  if (_gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
-                                     seg->body.mark.obj) &&
-      (!layout->cursor_visible ||
-       gtk_text_buffer_get_selection_bounds (layout->buffer, NULL, NULL)))
+  if (cursor.is_insert &&
+      (!layout->cursor_visible || gtk_text_buffer_get_selection_bounds (layout->buffer, NULL, NULL)))
     return;
 
-  if (layout->overwrite_mode &&
-      _gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
-                                     seg->body.mark.obj))
+  if (layout->overwrite_mode && cursor.is_insert)
     {
       GtkTextIter iter;
       gboolean cursor_at_line_end;
@@ -1884,9 +1888,9 @@ add_cursor (GtkTextLayout      *layout,
     }
 
   if (!display->cursors)
-    display->cursors = g_array_new (FALSE, FALSE, sizeof(int));
+    display->cursors = g_array_new (FALSE, FALSE, sizeof(CursorPosition));
 
-  display->cursors = g_array_append_val (display->cursors, start);
+  display->cursors = g_array_append_val (display->cursors, cursor);
 }
 
 static gboolean
@@ -4181,21 +4185,24 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
             {
               int i;
 
-              gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
               for (i = 0; i < line_display->cursors->len; i++)
                 {
-                  int index;
                   PangoDirection dir;
+                  CursorPosition cursor;
 
-                  index = g_array_index(line_display->cursors, int, i);
+                  cursor = g_array_index (line_display->cursors, CursorPosition, i);
                   dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
 
+                  if (cursor.is_insert || cursor.is_selection_bound)
+                    gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
+
                   gtk_snapshot_render_insertion_cursor (crenderer->snapshot, context,
                                                         line_display->x_offset, offset_y + line_display->top_margin,
-                                                        line_display->layout, index, dir);
-                }
+                                                        line_display->layout, cursor.pos, dir);
 
-              gtk_snapshot_pop (crenderer->snapshot);
+                  if (cursor.is_insert || cursor.is_selection_bound)
+                    gtk_snapshot_pop (crenderer->snapshot);
+                }
             }
         } /* line_display->height > 0 */
 
index f408d199dea8c3b156b51ff70582a45056f402ce..5eea90b18aa9688692a4925460815019caf9e100 100644 (file)
@@ -213,13 +213,20 @@ struct _GtkTextAttrAppearance
   GtkTextAppearance appearance;
 };
 
+typedef struct _CursorPosition CursorPosition;
+struct _CursorPosition {
+  int pos;
+  guint is_insert          : 1;
+  guint is_selection_bound : 1;
+};
+
 struct _GtkTextLineDisplay
 {
   PangoLayout *layout;
 
   GskRenderNode *node;
 
-  GArray *cursors;      /* indexes of cursors in the PangoLayout */
+  GArray *cursors;      /* indexes of cursors in the PangoLayout, and mark names */
 
   /* GSequenceIter backpointer for use within cache */
   GSequenceIter *cache_iter;