diff --git a/plugins/highlight-word-selection/highlight-word-selection.vala b/plugins/highlight-word-selection/highlight-word-selection.vala index 9306321f2e..390fe79ae1 100644 --- a/plugins/highlight-word-selection/highlight-word-selection.vala +++ b/plugins/highlight-word-selection/highlight-word-selection.vala @@ -34,12 +34,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); }); @@ -48,9 +46,10 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A }); } - public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) requires (main_window != null) { - if (!main_window.has_successful_search ()) { - // Perform plugin selection when there is no ongoing and successful search + public void on_selection_changed (string selected_text, ref Gtk.TextIter start, ref Gtk.TextIter end) { + if (selected_text != "" && + !main_window.has_successful_search ()) { + // Perform plugin selection when there is no ongoing and successful search current_search_context = new Gtk.SourceSearchContext ( (Gtk.SourceBuffer)current_source.buffer, null @@ -112,13 +111,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 @@ -127,16 +126,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 2759b98bfe..88a772792c 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -31,21 +31,20 @@ 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; + 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; 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 +98,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"); @@ -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; @@ -539,14 +540,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); } } @@ -597,49 +596,37 @@ 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); - - if (start.equal (last_select_start_iter) && end.equal (last_select_end_iter)) { - return; - } - - last_select_start_iter.assign (start); - last_select_end_iter.assign (end); + 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) { - Source.remove (selection_changed_timer); - selection_changed_timer = 0; + continue_selection_timer = true; + return; } - // 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); - } + selection_changed_timer = Timeout.add (SELECTION_CHANGE_THROTTLE_MS, () => { + if (continue_selection_timer) { + continue_selection_timer = false; + return Source.CONTINUE; + } - } + selection_changed_timer = 0; + 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;