From c08ba636d48bcd7acdfaa68081b37153e88d4f20 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 22 Sep 2021 19:41:06 -0700 Subject: [PATCH] textview: improve undo grouping when overwriting We want to group in more than one undo group when removing a selection and replacing it with a new character or characters, unless we're replacing a single character. In that case, the natural thing is to treat it as an atomic change. --- gtk/gtktextview.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index e37d44c722..381124aceb 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -8401,17 +8401,32 @@ gtk_text_view_commit_text (GtkTextView *text_view, { GtkTextViewPrivate *priv; gboolean had_selection; + GtkTextIter begin, end; + guint length; priv = text_view->priv; gtk_text_view_obscure_mouse_cursor (text_view); gtk_text_buffer_begin_user_action (get_buffer (text_view)); - had_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view), - NULL, NULL); - - gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE, - priv->editable); + had_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view), &begin, &end); + gtk_text_iter_order (&begin, &end); + length = gtk_text_iter_get_offset (&end) - gtk_text_iter_get_offset (&begin); + + if (gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE, priv->editable)) + { + /* If something was deleted, create a second group for the insert. This + * ensures that there are two undo operations. One for the deletion, and + * one for the insertion of new text. However, if there is only a single + * character overwritten, that isn't very useful, just keep the single + * undo group. + */ + if (length > 1) + { + gtk_text_buffer_end_user_action (get_buffer (text_view)); + gtk_text_buffer_begin_user_action (get_buffer (text_view)); + } + } if (!strcmp (str, "\n")) { -- 2.30.2