[gnome-builder] editor: restore cursor position when refocusing



commit ac953b00a86cd6be82ef297cbc3972113de7175e
Author: Christian Hergert <christian hergert me>
Date:   Wed Jan 21 15:58:50 2015 -0800

    editor: restore cursor position when refocusing
    
    Since GtkTextBuffer manages cursor position and selections in the buffer
    rather than in the view, we need to fake things out a bit when we move
    back and forth.
    
    This still doesn't solve some annoyances such as the current line
    highlight being off, or seeing the cursor move when not focused. But
    it's a whole lot better than completely losing your previous cursor
    postiion.
    
    What we should really do, is for Gtk4 move selections to the GtkTextView
    and out of the GtkTextBuffer.

 src/editor/gb-source-view.c |   53 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)
---
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index c59b404..58c6fb7 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -72,6 +72,9 @@ struct _GbSourceViewPrivate
   guint                        buffer_mark_set_handler;
   guint                        buffer_notify_language_handler;
 
+  gint                         saved_line;
+  gint                         saved_line_offset;
+
   guint                        auto_indent : 1;
   guint                        enable_word_completion : 1;
   guint                        insert_matching_brace : 1;
@@ -2027,6 +2030,49 @@ gb_source_view_drag_data_received (GtkWidget        *widget,
     }
 }
 
+static void
+gb_source_view_save_cursor (GbSourceView *view)
+{
+  GtkTextBuffer *buffer;
+  GtkTextMark *insert;
+  GtkTextIter iter;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+  insert = gtk_text_buffer_get_insert (buffer);
+  gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+
+  view->priv->saved_line = gtk_text_iter_get_line (&iter);
+  view->priv->saved_line_offset = gtk_text_iter_get_line_offset (&iter);
+}
+
+static void
+gb_source_view_restore_cursor (GbSourceView *view)
+{
+  GbSourceViewPrivate *priv;
+  GtkTextBuffer *buffer;
+  GtkTextMark *insert;
+  GtkTextIter iter;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  priv = view->priv;
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+  insert = gtk_text_buffer_get_insert (buffer);
+  gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+
+  if ((view->priv->saved_line == gtk_text_iter_get_line (&iter)) &&
+      (view->priv->saved_line_offset == gtk_text_iter_get_line_offset (&iter)))
+    return;
+
+  if (gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter,
+                                                      priv->saved_line,
+                                                      priv->saved_line_offset))
+    gtk_text_buffer_select_range (buffer, &iter, &iter);
+}
+
 static gboolean
 gb_source_view_focus_in_event (GtkWidget     *widget,
                                GdkEventFocus *event)
@@ -2037,6 +2083,8 @@ gb_source_view_focus_in_event (GtkWidget     *widget,
   g_return_val_if_fail (GB_IS_SOURCE_VIEW (widget), FALSE);
   g_return_val_if_fail (event, FALSE);
 
+  gb_source_view_restore_cursor (GB_SOURCE_VIEW (widget));
+
   ret = GTK_WIDGET_CLASS (gb_source_view_parent_class)->focus_in_event (widget, event);
 
   completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (widget));
@@ -2055,6 +2103,8 @@ gb_source_view_focus_out_event (GtkWidget     *widget,
   g_return_val_if_fail (GB_IS_SOURCE_VIEW (widget), FALSE);
   g_return_val_if_fail (event, FALSE);
 
+  gb_source_view_save_cursor (GB_SOURCE_VIEW (widget));
+
   ret = GTK_WIDGET_CLASS (gb_source_view_parent_class)->focus_out_event (widget, event);
 
   completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (widget));
@@ -2385,6 +2435,9 @@ gb_source_view_init (GbSourceView *view)
 
   view->priv->snippets = g_queue_new ();
 
+  view->priv->saved_line = -1;
+  view->priv->saved_line_offset = -1;
+
   g_signal_connect (view,
                     "notify::buffer",
                     G_CALLBACK (gb_source_view_notify_buffer),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]