summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-01-03 12:43:30 -0500
committerMatthias Clasen <mclasen@redhat.com>2020-01-03 13:00:53 -0500
commit9c2c5665df42ed13bb43a55997d34ef6dffe6d9d (patch)
tree4c1848cca99c9d27f141d3a6d89a8071a39602d9
parent1be9c6aa3fbc1a667b545c30d80440b6b383f3a5 (diff)
downloadgtk+-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.c37
-rw-r--r--gtk/gtktextlayoutprivate.h9
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;