From f74223735f6e6fb978062ea61491cae812db7f08 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 22 Oct 2024 18:47:15 +0100 Subject: [PATCH 1/3] Simplify, handle mark-deleted signal --- .../highlight-word-selection.vala | 26 +++----- src/Widgets/SourceView.vala | 63 ++++++++----------- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/plugins/highlight-word-selection/highlight-word-selection.vala b/plugins/highlight-word-selection/highlight-word-selection.vala index 5896b5d43..cbf7efd2c 100644 --- a/plugins/highlight-word-selection/highlight-word-selection.vala +++ b/plugins/highlight-word-selection/highlight-word-selection.vala @@ -36,12 +36,10 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A plugins = (Scratch.Services.Interface) object; plugins.hook_document.connect ((doc) => { if (current_source != null) { - current_source.deselected.disconnect (on_deselection); current_source.selection_changed.disconnect (on_selection_changed); } current_source = doc.source_view; - current_source.deselected.connect (on_deselection); current_source.selection_changed.connect (on_selection_changed); }); @@ -50,13 +48,13 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A }); } - public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) { + public void on_selection_changed (string selected_text, ref Gtk.TextIter start, ref Gtk.TextIter end) { var window_search_context = main_window != null ? main_window.search_bar.search_context : null; - - if (window_search_context == null || + if (selected_text != "" && + (window_search_context == null || window_search_context.settings.search_text == "" || - window_search_context.get_occurrences_count () == 0) { - // Perform plugin selection when there is no ongoing and successful search + window_search_context.get_occurrences_count () == 0)) { + // Perform plugin selection when there is no ongoing and successful search current_search_context = new Gtk.SourceSearchContext ( (Gtk.SourceBuffer)current_source.buffer, null @@ -118,13 +116,13 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A ); // Ensure no leading or trailing space - var selected_text = start.get_text (end).strip (); + var stripped_selected_words = start.get_text (end).strip (); - if (selected_text.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) { + if (stripped_selected_words.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) { return; } - current_search_context.settings.search_text = selected_text; + current_search_context.settings.search_text = stripped_selected_words; current_search_context.set_highlight (true); } else if (current_search_context != null) { // Cancel existing search @@ -133,16 +131,8 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A } } - public void on_deselection () { - if (current_search_context != null) { - current_search_context.set_highlight (false); - current_search_context = null; - } - } - public void deactivate () { if (current_source != null) { - current_source.deselected.disconnect (on_deselection); current_source.selection_changed.disconnect (on_selection_changed); } } diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 2759b98bf..a48975341 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -31,11 +31,10 @@ namespace Scratch.Widgets { public FolderManager.ProjectFolderItem project { get; set; default = null; } private string font; - private uint selection_changed_timer = 0; private uint size_allocate_timer = 0; private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; - private string selected_text = ""; + private string prev_selected_text = ""; private SourceGutterRenderer git_diff_gutter_renderer; private const uint THROTTLE_MS = 400; @@ -44,8 +43,7 @@ namespace Scratch.Widgets { public signal void style_changed (Gtk.SourceStyleScheme style); // "selection_changed" signal now only emitted when the selected text changes (position ignored). Listened to by searchbar and highlight word selection plugin - public signal void selection_changed (Gtk.TextIter start_iter, Gtk.TextIter end_iter); - public signal void deselected (); + public signal void selection_changed (string selected_text, Gtk.TextIter start_iter, Gtk.TextIter end_iter); //lang can be null, in the case of *No highlight style* aka Normal text public Gtk.SourceLanguage? language { @@ -99,7 +97,9 @@ namespace Scratch.Widgets { var source_buffer = new Gtk.SourceBuffer (null); set_buffer (source_buffer); source_buffer.highlight_syntax = true; - source_buffer.mark_set.connect (on_mark_set); + source_buffer.mark_set.connect (schedule_selection_changed_event); + // Need to handle this signal else not all deselections are detected + source_buffer.mark_deleted.connect (schedule_selection_changed_event); highlight_current_line = true; var draw_spaces_tag = new Gtk.SourceTag ("draw_spaces"); @@ -597,49 +597,36 @@ namespace Scratch.Widgets { return (int) (height_in_px - (LINES_TO_KEEP * px_per_line)); } - void on_mark_set (Gtk.TextIter loc, Gtk.TextMark mar) { - // Weed out user movement for text selection changes - Gtk.TextIter start, end; - buffer.get_selection_bounds (out start, out end); + private bool continue_selection_timer = false; + private uint selection_changed_timer = 0; + private void schedule_selection_changed_event () { - if (start.equal (last_select_start_iter) && end.equal (last_select_end_iter)) { + if (selection_changed_timer != 0) { + continue_selection_timer = true; return; } - last_select_start_iter.assign (start); - last_select_end_iter.assign (end); - update_draw_spaces (); + selection_changed_timer = Timeout.add (THROTTLE_MS, () => { + if (continue_selection_timer) { + continue_selection_timer = false; + return Source.CONTINUE; + } - if (selection_changed_timer != 0) { - Source.remove (selection_changed_timer); selection_changed_timer = 0; - } - - // Fire deselected immediately - if (start.equal (end)) { - deselected (); - // Don't fire signal till we think select movement is done - } else { - selection_changed_timer = Timeout.add (THROTTLE_MS, selection_changed_event); - } - - } + update_draw_spaces (); + Gtk.TextIter start, end; + var selected_text = ""; + if (buffer.get_selection_bounds (out start, out end)) { + selected_text = buffer.get_text (start, end, true); + } - bool selection_changed_event () { - Gtk.TextIter start, end; - bool selected = buffer.get_selection_bounds (out start, out end); - if (selected) { - var prev_selected_text = selected_text; - selected_text = buffer.get_text (start, end, true); if (selected_text != prev_selected_text) { - selection_changed (start, end); + selection_changed (selected_text, start, end); } - } else { - deselected (); - } - selection_changed_timer = 0; - return false; + prev_selected_text = selected_text; + return Source.REMOVE; + }); } uint refresh_diff_timeout_id = 0; From 19cca3d1574b38537eea0d1ea4ba56e690389303 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 22 Oct 2024 19:17:51 +0100 Subject: [PATCH 2/3] Update spaces immediately --- src/Widgets/SourceView.vala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index a48975341..c1fd5901f 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -539,14 +539,12 @@ namespace Scratch.Widgets { /* Draw spaces in selection the same way if drawn at all */ if (selection && draw_spaces_state in (ScratchDrawSpacesState.FOR_SELECTION | ScratchDrawSpacesState.CURRENT | ScratchDrawSpacesState.ALWAYS)) { - buffer.apply_tag_by_name ("draw_spaces", start, end); return; } if (draw_spaces_state == ScratchDrawSpacesState.CURRENT && get_current_line (out start, out end)) { - buffer.apply_tag_by_name ("draw_spaces", start, end); } } @@ -600,6 +598,8 @@ namespace Scratch.Widgets { private bool continue_selection_timer = false; private uint selection_changed_timer = 0; private void schedule_selection_changed_event () { + // Update spaces immediately to maintain previous behaviour + update_draw_spaces (); if (selection_changed_timer != 0) { continue_selection_timer = true; @@ -613,7 +613,6 @@ namespace Scratch.Widgets { } selection_changed_timer = 0; - update_draw_spaces (); Gtk.TextIter start, end; var selected_text = ""; if (buffer.get_selection_bounds (out start, out end)) { From 9f129cf6368cf124e111995d8de82f4dadea66b7 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 2 Dec 2024 12:54:24 +0000 Subject: [PATCH 3/3] Separate throttle for selection change --- src/Widgets/SourceView.vala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index c1fd5901f..88a772792 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -37,7 +37,8 @@ namespace Scratch.Widgets { private string prev_selected_text = ""; private SourceGutterRenderer git_diff_gutter_renderer; - private const uint THROTTLE_MS = 400; + private const uint SIZE_ALLOCATION_THROTTLE_MS = 400; + private const uint SELECTION_CHANGE_THROTTLE_MS = 100; private double total_delta = 0; private const double SCROLL_THRESHOLD = 1.0; @@ -189,7 +190,7 @@ namespace Scratch.Widgets { size_allocate.connect ((allocation) => { // Throttle for performance if (size_allocate_timer == 0) { - size_allocate_timer = Timeout.add (THROTTLE_MS, () => { + size_allocate_timer = Timeout.add (SIZE_ALLOCATION_THROTTLE_MS, () => { size_allocate_timer = 0; bottom_margin = calculate_bottom_margin (allocation.height); return GLib.Source.REMOVE; @@ -606,7 +607,7 @@ namespace Scratch.Widgets { return; } - selection_changed_timer = Timeout.add (THROTTLE_MS, () => { + selection_changed_timer = Timeout.add (SELECTION_CHANGE_THROTTLE_MS, () => { if (continue_selection_timer) { continue_selection_timer = false; return Source.CONTINUE;