[gtksourceview] Try to optimize away time spent tracking the clipboard
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] Try to optimize away time spent tracking the clipboard
- Date: Sun, 29 Mar 2015 20:17:49 +0000 (UTC)
commit c468273e8ad77feab60db18cd1700c6267240211
Author: Paolo Borelli <pborelli gnome org>
Date: Sun Mar 29 21:32:32 2015 +0200
Try to optimize away time spent tracking the clipboard
When doing operations that consist of many insert and deletes we
clear the selection and then restore it at the end of the operation
otherwise gtk spends a lot of time updating the clipboard content.
gtksourceview/gtksourcebuffer-private.h | 6 +++
gtksourceview/gtksourcebuffer.c | 67 +++++++++++++++++++++++++++++++
gtksourceview/gtksourcesearchcontext.c | 4 ++
gtksourceview/gtksourceview.c | 4 ++
4 files changed, 81 insertions(+), 0 deletions(-)
---
diff --git a/gtksourceview/gtksourcebuffer-private.h b/gtksourceview/gtksourcebuffer-private.h
index 40dd368..14eb968 100644
--- a/gtksourceview/gtksourcebuffer-private.h
+++ b/gtksourceview/gtksourcebuffer-private.h
@@ -63,6 +63,12 @@ GtkSourceBracketMatchType
_gtk_source_buffer_find_bracket_match (GtkSourceBuffer *buffer,
GtkTextIter *orig);
+G_GNUC_INTERNAL
+void _gtk_source_buffer_save_and_clear_selection (GtkSourceBuffer *buffer);
+
+G_GNUC_INTERNAL
+void _gtk_source_buffer_restore_selection (GtkSourceBuffer *buffer);
+
G_END_DECLS
#endif /* __GTK_SOURCE_BUFFER_PRIVATE_H__ */
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index c77b4c7..7663a86 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -177,6 +177,9 @@ struct _GtkSourceBufferPrivate
GtkSourceUndoManager *undo_manager;
gint max_undo_levels;
+ GtkTextMark *tmp_insert_mark;
+ GtkTextMark *tmp_selection_bound_mark;
+
GList *search_contexts;
GtkTextTag *invalid_char_tag;
@@ -2318,6 +2321,68 @@ gtk_source_buffer_iter_backward_to_context_class_toggle (GtkSourceBuffer *buffer
}
}
+/*
+ * GtkTextView wastes a lot of time tracking the clipboard content if
+ * we do insert/delete operations while there is a selection.
+ * These two utilities store the current selection with marks before
+ * doing an edit operation and restore it at the end.
+ */
+void
+_gtk_source_buffer_save_and_clear_selection (GtkSourceBuffer *buffer)
+{
+ GtkTextBuffer *buf;
+
+ g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
+
+ buf = GTK_TEXT_BUFFER (buffer);
+
+ /* Note we cannot use buffer_get_selection_bounds since it
+ * orders the iters while we want to know the position of
+ * each mark.
+ */
+ if (gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer)))
+ {
+ GtkTextIter insert_iter;
+ GtkTextIter selection_bound_iter;
+
+ g_assert (buffer->priv->tmp_insert_mark == NULL);
+ g_assert (buffer->priv->tmp_selection_bound_mark == NULL);
+
+ gtk_text_buffer_get_iter_at_mark (buf, &insert_iter, gtk_text_buffer_get_insert (buf));
+ gtk_text_buffer_get_iter_at_mark (buf, &selection_bound_iter,
gtk_text_buffer_get_selection_bound (buf));
+ buffer->priv->tmp_insert_mark = gtk_text_buffer_create_mark (buf, NULL, &insert_iter, FALSE);
+ buffer->priv->tmp_selection_bound_mark = gtk_text_buffer_create_mark (buf, NULL,
&selection_bound_iter, FALSE);
+
+ gtk_text_buffer_place_cursor (buf, &insert_iter);
+ }
+}
+
+void
+_gtk_source_buffer_restore_selection (GtkSourceBuffer *buffer)
+{
+ g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
+
+ if (buffer->priv->tmp_insert_mark != NULL &&
+ buffer->priv->tmp_selection_bound_mark != NULL)
+ {
+ GtkTextBuffer *buf;
+ GtkTextIter insert_iter;
+ GtkTextIter selection_bound_iter;
+
+ buf = GTK_TEXT_BUFFER (buffer);
+
+ gtk_text_buffer_get_iter_at_mark (buf, &insert_iter, buffer->priv->tmp_insert_mark);
+ gtk_text_buffer_get_iter_at_mark (buf, &selection_bound_iter,
buffer->priv->tmp_selection_bound_mark);
+
+ gtk_text_buffer_select_range (buf, &insert_iter, &selection_bound_iter);
+
+ gtk_text_buffer_delete_mark (buf, buffer->priv->tmp_insert_mark);
+ gtk_text_buffer_delete_mark (buf, buffer->priv->tmp_selection_bound_mark);
+ buffer->priv->tmp_insert_mark = NULL;
+ buffer->priv->tmp_selection_bound_mark = NULL;
+ }
+}
+
static gchar *
do_lower_case (GtkTextBuffer *buffer,
const GtkTextIter *start,
@@ -2585,6 +2650,7 @@ gtk_source_buffer_join_lines (GtkSourceBuffer *buffer,
text_buffer = GTK_TEXT_BUFFER (buffer);
end_mark = gtk_text_buffer_create_mark (text_buffer, NULL, end, FALSE);
+ _gtk_source_buffer_save_and_clear_selection (buffer);
gtk_text_buffer_begin_user_action (text_buffer);
move_to_line_text_end (start);
@@ -2625,6 +2691,7 @@ gtk_source_buffer_join_lines (GtkSourceBuffer *buffer,
}
gtk_text_buffer_end_user_action (text_buffer);
+ _gtk_source_buffer_restore_selection (buffer);
gtk_text_buffer_delete_mark (text_buffer, end_mark);
}
diff --git a/gtksourceview/gtksourcesearchcontext.c b/gtksourceview/gtksourcesearchcontext.c
index 2a47945..5f1a4fb 100644
--- a/gtksourceview/gtksourcesearchcontext.c
+++ b/gtksourceview/gtksourcesearchcontext.c
@@ -3713,6 +3713,8 @@ gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (search->priv->buffer),
FALSE);
+ _gtk_source_buffer_save_and_clear_selection (GTK_SOURCE_BUFFER (search->priv->buffer));
+
gtk_text_buffer_get_start_iter (search->priv->buffer, &iter);
gtk_text_buffer_begin_user_action (search->priv->buffer);
@@ -3738,6 +3740,8 @@ gtk_source_search_context_replace_all (GtkSourceSearchContext *search,
gtk_text_buffer_end_user_action (search->priv->buffer);
+ _gtk_source_buffer_restore_selection GTK_SOURCE_BUFFER ((search->priv->buffer));
+
gtk_source_buffer_set_highlight_matching_brackets (GTK_SOURCE_BUFFER (search->priv->buffer),
highlight_matching_brackets);
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index b6f0a03..8f0e1ea 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -4109,7 +4109,9 @@ gtk_source_view_key_press_event (GtkWidget *widget,
/* shift+tab: always unindent */
if (event->state & GDK_SHIFT_MASK)
{
+ _gtk_source_buffer_save_and_clear_selection (GTK_SOURCE_BUFFER (buf));
gtk_source_view_unindent_lines (view, &s, &e);
+ _gtk_source_buffer_restore_selection (GTK_SOURCE_BUFFER (buf));
return TRUE;
}
@@ -4121,7 +4123,9 @@ gtk_source_view_key_press_event (GtkWidget *widget,
((gtk_text_iter_starts_line (&s) && gtk_text_iter_ends_line (&e)) ||
(gtk_text_iter_get_line (&s) != gtk_text_iter_get_line (&e))))
{
+ _gtk_source_buffer_save_and_clear_selection (GTK_SOURCE_BUFFER (buf));
gtk_source_view_indent_lines (view, &s, &e);
+ _gtk_source_buffer_restore_selection (GTK_SOURCE_BUFFER (buf));
return TRUE;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]