diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-01-03 12:43:30 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-01-03 13:00:53 -0500 |
commit | 9c2c5665df42ed13bb43a55997d34ef6dffe6d9d (patch) | |
tree | 4c1848cca99c9d27f141d3a6d89a8071a39602d9 | |
parent | 1be9c6aa3fbc1a667b545c30d80440b6b383f3a5 (diff) | |
download | gtk+-9c2c5665df42ed13bb43a55997d34ef6dffe6d9d.tar.gz |
textview: Render visible marks better
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.
-rw-r--r-- | gtk/gtktextlayout.c | 37 | ||||
-rw-r--r-- | gtk/gtktextlayoutprivate.h | 9 |
2 files changed, 30 insertions, 16 deletions
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 7b60b13f3f..6d4b41b65a 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -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 */ diff --git a/gtk/gtktextlayoutprivate.h b/gtk/gtktextlayoutprivate.h index f408d199de..5eea90b18a 100644 --- a/gtk/gtktextlayoutprivate.h +++ b/gtk/gtktextlayoutprivate.h @@ -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; |