[gedit/gnome-41] tab: backport text-cut-off bug fix
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit/gnome-41] tab: backport text-cut-off bug fix
- Date: Tue, 2 Aug 2022 18:00:36 +0000 (UTC)
commit 48a44f35391457ce04edd5aa6777d2dffcb109a9
Author: Sébastien Wilmet <swilmet informatique-libre be>
Date: Wed Jul 27 11:40:53 2022 +0200
tab: backport text-cut-off bug fix
Cherry-picking the commits from master were not possible.
So it's a backport.
For relevant commits on master:
commit 5adfe2c8b
commit 21ae0bab6
commit be6c7695d
commit 0476a1d44
See https://gitlab.gnome.org/GNOME/gedit/-/issues/42
gedit/gedit-tab.c | 120 ++++++++++++++++++++++++++++++++++++------------------
1 file changed, 80 insertions(+), 40 deletions(-)
---
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index d305f8d7e..f7ca7fe11 100644
--- a/gedit/gedit-tab.c
+++ b/gedit/gedit-tab.c
@@ -60,7 +60,8 @@ struct _GeditTab
GtkSourceFileSaverFlags save_flags;
- guint idle_scroll;
+ guint scroll_timeout;
+ guint scroll_idle;
gint auto_save_interval;
guint auto_save_timeout;
@@ -333,10 +334,16 @@ gedit_tab_dispose (GObject *object)
remove_auto_save_timeout (tab);
- if (tab->idle_scroll != 0)
+ if (tab->scroll_timeout != 0)
{
- g_source_remove (tab->idle_scroll);
- tab->idle_scroll = 0;
+ g_source_remove (tab->scroll_timeout);
+ tab->scroll_timeout = 0;
+ }
+
+ if (tab->scroll_idle != 0)
+ {
+ g_source_remove (tab->scroll_idle);
+ tab->scroll_idle = 0;
}
if (tab->cancellable != NULL)
@@ -1040,14 +1047,36 @@ should_show_progress_info (GTimer **timer,
}
static gboolean
-scroll_to_cursor (GeditTab *tab)
+scroll_timeout_cb (GeditTab *tab)
{
GeditView *view;
view = gedit_tab_get_view (tab);
gedit_view_scroll_to_cursor (view);
- tab->idle_scroll = 0;
+ tab->scroll_timeout = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+scroll_idle_cb (GeditTab *tab)
+{
+ /* The idle is not enough, for a detailed analysis of this, see:
+ * https://wiki.gnome.org/Apps/Gedit/FixingTextCutOffBug
+ * or the commit message that changed this.
+ * (here it's a hack, a proper solution in GTK/GtkTextView should be
+ * found).
+ */
+ if (tab->scroll_timeout == 0)
+ {
+ /* Same number of ms as GtkSearchEntry::search-changed delay.
+ * Small enough to not be noticeable, but needs to be at least a
+ * few frames from the GdkFrameClock (during app startup).
+ */
+ tab->scroll_timeout = g_timeout_add (150, (GSourceFunc)scroll_timeout_cb, tab);
+ }
+
+ tab->scroll_idle = 0;
return G_SOURCE_REMOVE;
}
@@ -1641,48 +1670,68 @@ goto_line (GTask *loading_task)
{
LoaderData *data = g_task_get_task_data (loading_task);
GeditDocument *doc = gedit_tab_get_document (data->tab);
+ gboolean check_is_cursor_position = FALSE;
GtkTextIter iter;
- /* Move the cursor at the requested line if any. */
+ /* To the top by default. */
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), &iter);
+
+ /* At the requested line/column if set. */
if (data->line_pos > 0)
{
- gedit_document_goto_line_offset (doc,
- data->line_pos - 1,
- MAX (0, data->column_pos - 1));
- return;
+ gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (doc),
+ &iter,
+ data->line_pos - 1,
+ MAX (0, data->column_pos - 1));
+ check_is_cursor_position = TRUE;
}
- /* If enabled, move to the position stored in the metadata. */
- if (g_settings_get_boolean (data->tab->editor_settings, GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
+ /* From metadata. */
+ else if (g_settings_get_boolean (data->tab->editor_settings,
+ GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
{
- gchar *pos;
- gint offset;
-
- pos = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
-
- offset = pos != NULL ? atoi (pos) : 0;
- g_free (pos);
+ gchar *position_str;
+ guint64 offset = 0;
- gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
- &iter,
- MAX (0, offset));
+ position_str = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
- /* make sure it's a valid position, if the file
- * changed we may have ended up in the middle of
- * a utf8 character cluster */
- if (!gtk_text_iter_is_cursor_position (&iter))
+ if (position_str != NULL &&
+ g_ascii_string_to_unsigned (position_str,
+ 10,
+ 0,
+ G_MAXINT,
+ &offset,
+ NULL))
{
- gtk_text_iter_set_line_offset (&iter, 0);
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
+ &iter,
+ (gint) offset);
+ check_is_cursor_position = TRUE;
}
+
+ g_free (position_str);
}
- /* Otherwise to the top. */
- else
+ /* Make sure it's a valid position, to not end up in the middle of a
+ * utf8 character cluster.
+ */
+ if (check_is_cursor_position &&
+ !gtk_text_iter_is_cursor_position (&iter))
{
- gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), &iter);
+ gtk_text_iter_set_line_offset (&iter, 0);
}
gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+
+ /* Scroll to the cursor when the document is loaded, we need to do it in
+ * an idle as after the document is loaded the textview is still
+ * redrawing and relocating its internals.
+ */
+ if (data->tab->scroll_idle == 0 &&
+ !gtk_text_iter_is_start (&iter))
+ {
+ data->tab->scroll_idle = g_idle_add ((GSourceFunc)scroll_idle_cb, data->tab);
+ }
}
static gboolean
@@ -1747,15 +1796,6 @@ successful_load (GTask *loading_task)
goto_line (loading_task);
- /* Scroll to the cursor when the document is loaded, we need to do it in
- * an idle as after the document is loaded the textview is still
- * redrawing and relocating its internals.
- */
- if (data->tab->idle_scroll == 0)
- {
- data->tab->idle_scroll = g_idle_add ((GSourceFunc)scroll_to_cursor, data->tab);
- }
-
location = gtk_source_file_loader_get_location (data->loader);
/* If the document is readonly we don't care how many times the file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]