From 4116ed28e53a90ed32081e5c47c3bbf88d6c59e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 14:44:29 -0700 Subject: [PATCH 01/18] SearchBar: use actions for next/previous --- src/Widgets/SearchBar.vala | 40 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 4b9f5803e..5079278f7 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -69,9 +69,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - private Gtk.Button tool_arrow_up; - private Gtk.Button tool_arrow_down; - /** * Is the search cyclic? e.g., when you are at the bottom, if you press * "Down", it will go at the start of the file to search for the content @@ -109,8 +106,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var app_instance = (Scratch.Application) GLib.Application.get_default (); - tool_arrow_down = new Gtk.Button.from_icon_name ("go-down-symbolic", SMALL_TOOLBAR) { - sensitive = false, + var tool_arrow_down = new Gtk.Button.from_icon_name ("go-down-symbolic", SMALL_TOOLBAR) { + action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT, tooltip_markup = Granite.markup_accel_tooltip ( app_instance.get_accels_for_action ( MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT @@ -118,10 +115,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou _("Search next") ) }; - tool_arrow_down.clicked.connect (search_next); - tool_arrow_up = new Gtk.Button.from_icon_name ("go-up-symbolic", SMALL_TOOLBAR) { - sensitive = false, + var tool_arrow_up = new Gtk.Button.from_icon_name ("go-up-symbolic", SMALL_TOOLBAR) { + action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS, tooltip_markup = Granite.markup_accel_tooltip ( app_instance.get_accels_for_action ( MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS @@ -129,7 +125,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou _("Search previous") ) }; - tool_arrow_up.clicked.connect (search_previous); cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")); @@ -588,6 +583,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou // Update search occurrence label, tool arrows and replace buttons in sync private void update_search_widgets () { + var find_next_action = Utils.action_from_group (MainWindow.ACTION_FIND_NEXT, window.actions); + var find_previous_action = Utils.action_from_group (MainWindow.ACTION_FIND_PREVIOUS, window.actions); + cancel_update_search_widgets (); update_search_label_timeout_id = Timeout.add (100, () => { update_search_label_timeout_id = 0; @@ -595,8 +593,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou debug ("update occurrence with null context"); replace_tool_button.sensitive = false; replace_all_tool_button.sensitive = false; - tool_arrow_up.sensitive = false; - tool_arrow_down.sensitive = false; + find_next_action.set_enabled (false); + find_previous_action.set_enabled (false); return Source.REMOVE; } @@ -630,12 +628,12 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou search_entry.text == "" || count_of_search == 0) { - tool_arrow_up.sensitive = false; - tool_arrow_down.sensitive = false; + find_previous_action.set_enabled (false); + find_next_action.set_enabled (false); } else { if (cycle_search_button.active) { - tool_arrow_down.sensitive = true; - tool_arrow_up.sensitive =true; + find_next_action.set_enabled (true); + find_previous_action.set_enabled (true); } else { Gtk.TextIter? tmp_start_iter, tmp_end_iter; @@ -650,19 +648,19 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou is_in_end = end_iter.compare (tmp_end_iter) == 0; if (!is_in_end) { - tool_arrow_down.sensitive = search_context.forward ( + find_next_action.set_enabled (search_context.forward ( end_iter, out tmp_start_iter, out tmp_end_iter, null - ); + )); } else { - tool_arrow_down.sensitive = false; + find_next_action.set_enabled (false); } if (!is_in_start) { - tool_arrow_up.sensitive = search_context.backward ( + find_previous_action.set_enabled (search_context.backward ( start_iter, out tmp_start_iter, out end_iter, null - ); + )); } else { - tool_arrow_up.sensitive = false; + find_next_action.set_enabled (false); } } } From 29d81bf3085b9a084f6d9857ee4d1cd0203b8c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 15:00:36 -0700 Subject: [PATCH 02/18] SearchBar: add replace actions --- src/Widgets/SearchBar.vala | 40 +++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 5079278f7..e33bc1260 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -81,8 +81,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private Gtk.SearchEntry search_entry; private Gtk.SearchEntry replace_entry; private Gtk.Label search_occurence_count_label; - private Gtk.Button replace_tool_button; - private Gtk.Button replace_all_tool_button; private Scratch.Widgets.SourceView? text_view = null; private Gtk.TextBuffer? text_buffer = null; private Gtk.SourceSearchContext? search_context; @@ -90,11 +88,25 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private Gtk.Revealer revealer; private Gtk.EventControllerKey key_controller; + private SimpleActionGroup action_group; + public SearchBar (MainWindow window) { Object (window: window); } construct { + var replace_action = new SimpleAction ("replace", null); + replace_action.activate.connect (action_replace); + + var replace_all_action = new SimpleAction ("replace-all", null); + replace_all_action.activate.connect (action_replace_all); + + action_group = new SimpleActionGroup (); + action_group.add_action (replace_action); + action_group.add_action (replace_all_action); + + insert_action_group ("search", action_group); + this.orientation = HORIZONTAL; search_entry = new Gtk.SearchEntry () { hexpand = true, @@ -215,11 +227,13 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou primary_icon_name = "edit-symbolic" }; - replace_tool_button = new Gtk.Button.with_label (_("Replace")); - replace_tool_button.clicked.connect (on_replace_entry_activate); + var replace_tool_button = new Gtk.Button.with_label (_("Replace")) { + action_name = "search.replace" + }; - replace_all_tool_button = new Gtk.Button.with_label (_("Replace all")); - replace_all_tool_button.clicked.connect (on_replace_all_entry_activate); + var replace_all_tool_button = new Gtk.Button.with_label (_("Replace all")) { + action_name = "search.replace-all" + }; var replace_grid = new Gtk.Grid () { margin_top = 3, @@ -252,7 +266,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou search_next (); } }); - replace_entry.activate.connect (on_replace_entry_activate); + replace_entry.activate.connect (action_replace); var flowbox = new Gtk.FlowBox () { selection_mode = Gtk.SelectionMode.NONE, @@ -447,7 +461,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou update_search_widgets (); } - private void on_replace_entry_activate () { + private void action_replace () { if (text_buffer == null) { warning ("No valid buffer to replace"); return; @@ -469,7 +483,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - private void on_replace_all_entry_activate () { + private void action_replace_all () { if (text_buffer == null || this.window.get_current_document () == null) { debug ("No valid buffer to replace"); return; @@ -591,8 +605,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou update_search_label_timeout_id = 0; if (search_context == null) { debug ("update occurrence with null context"); - replace_tool_button.sensitive = false; - replace_all_tool_button.sensitive = false; + ((SimpleAction) action_group.lookup_action ("replace")).set_enabled (false); + ((SimpleAction) action_group.lookup_action ("replace-all")).set_enabled (false); find_next_action.set_enabled (false); find_previous_action.set_enabled (false); return Source.REMOVE; @@ -620,8 +634,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - replace_tool_button.sensitive = location_of_search > 0; - replace_all_tool_button.sensitive = count_of_search > 0; + ((SimpleAction) action_group.lookup_action ("replace")).set_enabled (location_of_search > 0); + ((SimpleAction) action_group.lookup_action ("replace-all")).set_enabled (count_of_search > 0); // Update tool arrows if (text_buffer == null || From d103a6357bca8e836bc6febe7a136ba04b6b8c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 15:36:51 -0700 Subject: [PATCH 03/18] Use settings actions, bind to settings --- src/Widgets/SearchBar.vala | 71 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index e33bc1260..76136abe7 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -74,10 +74,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou * "Down", it will go at the start of the file to search for the content * of the search entry. **/ - private Granite.SwitchModelButton cycle_search_button ; - private Gtk.ComboBoxText case_sensitive_search_button; - private Granite.SwitchModelButton regex_search_button; - private Granite.SwitchModelButton whole_word_search_button; private Gtk.SearchEntry search_entry; private Gtk.SearchEntry replace_entry; private Gtk.Label search_occurence_count_label; @@ -95,6 +91,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } construct { + var cyclic_search_action = settings.create_action ("cyclic-search"); + var wholeword_search_action = settings.create_action ("wholeword-search"); + var case_sensitive_search_action = settings.create_action ("case-sensitive-search"); + var regex_search_action = settings.create_action ("regex-search"); + var replace_action = new SimpleAction ("replace", null); replace_action.activate.connect (action_replace); @@ -102,8 +103,12 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou replace_all_action.activate.connect (action_replace_all); action_group = new SimpleActionGroup (); + action_group.add_action (case_sensitive_search_action); + action_group.add_action (cyclic_search_action); + action_group.add_action (regex_search_action); action_group.add_action (replace_action); action_group.add_action (replace_all_action); + action_group.add_action (wholeword_search_action); insert_action_group ("search", action_group); @@ -138,9 +143,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou ) }; - cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")); + var cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")) { + action_name = "search.cyclic-search" + }; - case_sensitive_search_button = new Gtk.ComboBoxText (); + var case_sensitive_search_button = new Gtk.ComboBoxText (); case_sensitive_search_button.append ("never", _("Never")); case_sensitive_search_button.append ("mixed", _("Mixed Case")); case_sensitive_search_button.append ("always", _("Always")); @@ -153,8 +160,13 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou case_sensitive_box.add (case_sensitive_search_button); case_sensitive_box.get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM); - regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")); - whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")); + var regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")) { + action_name = "search.regex-search" + }; + + var whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")) { + action_name = "search.wholeword-search" + }; var search_option_box = new Gtk.Box (VERTICAL, 0) { margin_top = 3, @@ -180,30 +192,19 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou }; search_menubutton.add (search_buttonbox); - cycle_search_button.toggled.connect (on_search_parameters_changed); - case_sensitive_search_button.changed.connect (on_search_parameters_changed); - whole_word_search_button.toggled.connect (on_search_parameters_changed); - regex_search_button.toggled.connect (on_search_parameters_changed); + settings.changed["case-sensitive-search"].connect (on_search_parameters_changed); + settings.changed["cyclic-search"].connect (on_search_parameters_changed); + settings.changed["regex-search"].connect (on_search_parameters_changed); + settings.changed["wholeword-search"].connect (on_search_parameters_changed); // Bind some application settings - settings.bind ("cyclic-search", cycle_search_button, "active", DEFAULT); - settings.bind ("wholeword-search", whole_word_search_button, "active", DEFAULT); settings.bind ("case-sensitive-search", case_sensitive_search_button, "active-id", DEFAULT); - settings.bind ("regex-search", regex_search_button, "active", DEFAULT); // These settings are ignored when regex searching - regex_search_button.bind_property ( - "active", cycle_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN - ); - regex_search_button.bind_property ( - "active", whole_word_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN - ); - regex_search_button.bind_property ( - "active", case_sensitive_search_label, "sensitive", SYNC_CREATE | INVERT_BOOLEAN - ); - regex_search_button.bind_property ( - "active", case_sensitive_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN - ); + settings.bind ("regex-search", cycle_search_button, "sensitive", INVERT_BOOLEAN); + settings.bind ("regex-search", whole_word_search_button, "sensitive", INVERT_BOOLEAN); + settings.bind ("regex-search", case_sensitive_search_button, "sensitive", INVERT_BOOLEAN); + settings.bind ("regex-search", case_sensitive_search_label, "sensitive", INVERT_BOOLEAN); var search_box = new Gtk.Box (HORIZONTAL, 0) { margin_top = 3, @@ -311,8 +312,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou this.text_buffer = text_view.get_buffer (); this.text_buffer.changed.connect (on_text_buffer_changed); this.search_context = new Gtk.SourceSearchContext (text_buffer as Gtk.SourceBuffer, null); - search_context.settings.wrap_around = cycle_search_button.active; - search_context.settings.regex_enabled = regex_search_button.active; + search_context.settings.wrap_around = settings.get_boolean ("cyclic-search"); + search_context.settings.regex_enabled = settings.get_boolean ("regex-search"); search_context.settings.search_text = search_entry.text; on_text_buffer_changed (); } @@ -367,7 +368,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou Gtk.TextIter? start_iter, end_iter; if (text_buffer != null) { text_buffer.get_selection_bounds (out start_iter, out end_iter); - if (!search_for_iter_backward (start_iter, out end_iter) && cycle_search_button.active) { + if (!search_for_iter_backward (start_iter, out end_iter) && settings.get_boolean ("cyclic-search")) { text_buffer.get_end_iter (out start_iter); search_for_iter_backward (start_iter, out end_iter); } @@ -381,7 +382,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou Gtk.TextIter? start_iter, end_iter, end_iter_tmp; if (text_buffer != null) { text_buffer.get_selection_bounds (out start_iter, out end_iter); - if (!search_for_iter (end_iter, out end_iter_tmp) && cycle_search_button.active) { + if (!search_for_iter (end_iter, out end_iter_tmp) && settings.get_boolean ("cyclic-search")) { text_buffer.get_start_iter (out start_iter); search_for_iter (start_iter, out end_iter); } @@ -507,7 +508,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou if (search_context != null) { var search_string = search_entry.text; search_context.settings.search_text = search_string; - var case_mode = (CaseSensitiveMode)(case_sensitive_search_button.active); + var case_mode = settings.get_enum ("case-sensitive-search"); switch (case_mode) { case CaseSensitiveMode.NEVER: search_context.settings.case_sensitive = false; @@ -525,8 +526,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou assert_not_reached (); } - search_context.settings.at_word_boundaries = whole_word_search_button.active; - search_context.settings.regex_enabled = regex_search_button.active; + search_context.settings.at_word_boundaries = settings.get_boolean ("wholeword-search"); + search_context.settings.regex_enabled = settings.get_boolean ("regex-search"); } update_search_widgets (); @@ -645,7 +646,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou find_previous_action.set_enabled (false); find_next_action.set_enabled (false); } else { - if (cycle_search_button.active) { + if (settings.get_boolean ("cyclic-search")) { find_next_action.set_enabled (true); find_previous_action.set_enabled (true); } else { From eed08391579f4904aa4d900a75f11087eb588cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 15:41:27 -0700 Subject: [PATCH 04/18] Bind directly to settings actually --- src/Widgets/SearchBar.vala | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 76136abe7..cd3f9f962 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -91,11 +91,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } construct { - var cyclic_search_action = settings.create_action ("cyclic-search"); - var wholeword_search_action = settings.create_action ("wholeword-search"); - var case_sensitive_search_action = settings.create_action ("case-sensitive-search"); - var regex_search_action = settings.create_action ("regex-search"); - var replace_action = new SimpleAction ("replace", null); replace_action.activate.connect (action_replace); @@ -103,12 +98,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou replace_all_action.activate.connect (action_replace_all); action_group = new SimpleActionGroup (); - action_group.add_action (case_sensitive_search_action); - action_group.add_action (cyclic_search_action); - action_group.add_action (regex_search_action); action_group.add_action (replace_action); action_group.add_action (replace_all_action); - action_group.add_action (wholeword_search_action); insert_action_group ("search", action_group); @@ -143,9 +134,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou ) }; - var cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")) { - action_name = "search.cyclic-search" - }; + var cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")); var case_sensitive_search_button = new Gtk.ComboBoxText (); case_sensitive_search_button.append ("never", _("Never")); @@ -160,13 +149,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou case_sensitive_box.add (case_sensitive_search_button); case_sensitive_box.get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM); - var regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")) { - action_name = "search.regex-search" - }; + var regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")); - var whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")) { - action_name = "search.wholeword-search" - }; + var whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")); var search_option_box = new Gtk.Box (VERTICAL, 0) { margin_top = 3, @@ -199,6 +184,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou // Bind some application settings settings.bind ("case-sensitive-search", case_sensitive_search_button, "active-id", DEFAULT); + settings.bind ("case-sensitive-search", cycle_search_button, "active", DEFAULT); + settings.bind ("cyclic-search", cycle_search_button, "active", DEFAULT); + settings.bind ("regex-search", regex_search_button, "active", DEFAULT); + settings.bind ("wholeword-search", whole_word_search_button, "active", DEFAULT); // These settings are ignored when regex searching settings.bind ("regex-search", cycle_search_button, "sensitive", INVERT_BOOLEAN); From c056095a785fc32c26b19a74c6a5c954ec11ce27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 18:01:51 -0700 Subject: [PATCH 05/18] reduce diff --- src/Widgets/SearchBar.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index cd3f9f962..857827315 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -183,11 +183,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou settings.changed["wholeword-search"].connect (on_search_parameters_changed); // Bind some application settings - settings.bind ("case-sensitive-search", case_sensitive_search_button, "active-id", DEFAULT); - settings.bind ("case-sensitive-search", cycle_search_button, "active", DEFAULT); settings.bind ("cyclic-search", cycle_search_button, "active", DEFAULT); - settings.bind ("regex-search", regex_search_button, "active", DEFAULT); settings.bind ("wholeword-search", whole_word_search_button, "active", DEFAULT); + settings.bind ("case-sensitive-search", case_sensitive_search_button, "active-id", DEFAULT); + settings.bind ("regex-search", regex_search_button, "active", DEFAULT); + // These settings are ignored when regex searching settings.bind ("regex-search", cycle_search_button, "sensitive", INVERT_BOOLEAN); From 5f403c8f397b03f152c4f49315893763ff4d7ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 24 Aug 2026 18:02:33 -0700 Subject: [PATCH 06/18] fix extra whitespace --- src/Widgets/SearchBar.vala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 857827315..9cef806b4 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -188,7 +188,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou settings.bind ("case-sensitive-search", case_sensitive_search_button, "active-id", DEFAULT); settings.bind ("regex-search", regex_search_button, "active", DEFAULT); - // These settings are ignored when regex searching settings.bind ("regex-search", cycle_search_button, "sensitive", INVERT_BOOLEAN); settings.bind ("regex-search", whole_word_search_button, "sensitive", INVERT_BOOLEAN); From c35acc5b6a43bde471be60db144b6b25c4510663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 09:09:46 -0700 Subject: [PATCH 07/18] constants for action names --- src/Widgets/SearchBar.vala | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 9f82e10ce..c98b20b39 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -54,6 +54,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } + private const string ACTION_GROUP = "search"; + private const string ACTION_PREFIX = ACTION_GROUP + "."; + private const string ACTION_REPLACE = "replace"; + private const string ACTION_REPLACE_ALL = "replace-all"; + /** * Is the search cyclic? e.g., when you are at the bottom, if you press * "Down", it will go at the start of the file to search for the content @@ -76,17 +81,17 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } construct { - var replace_action = new SimpleAction ("replace", null); + var replace_action = new SimpleAction (ACTION_REPLACE, null); replace_action.activate.connect (action_replace); - var replace_all_action = new SimpleAction ("replace-all", null); + var replace_all_action = new SimpleAction (ACTION_REPLACE_ALL, null); replace_all_action.activate.connect (action_replace_all); action_group = new SimpleActionGroup (); action_group.add_action (replace_action); action_group.add_action (replace_all_action); - insert_action_group ("search", action_group); + insert_action_group (ACTION_GROUP, action_group); this.orientation = HORIZONTAL; search_entry = new Gtk.SearchEntry () { @@ -202,11 +207,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou }; var replace_tool_button = new Gtk.Button.with_label (_("Replace")) { - action_name = "search.replace" + action_name = ACTION_PREFIX + ACTION_REPLACE }; var replace_all_tool_button = new Gtk.Button.with_label (_("Replace all")) { - action_name = "search.replace-all" + action_name = ACTION_PREFIX + ACTION_REPLACE_ALL }; var replace_grid = new Gtk.Grid () { @@ -557,8 +562,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou update_search_label_timeout_id = 0; if (search_context == null) { debug ("update occurrence with null context"); - ((SimpleAction) action_group.lookup_action ("replace")).set_enabled (false); - ((SimpleAction) action_group.lookup_action ("replace-all")).set_enabled (false); + ((SimpleAction) action_group.lookup_action (ACTION_REPLACE)).set_enabled (false); + ((SimpleAction) action_group.lookup_action (ACTION_REPLACE_ALL)).set_enabled (false); find_next_action.set_enabled (false); find_previous_action.set_enabled (false); return Source.REMOVE; @@ -586,8 +591,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - ((SimpleAction) action_group.lookup_action ("replace")).set_enabled (location_of_search > 0); - ((SimpleAction) action_group.lookup_action ("replace-all")).set_enabled (count_of_search > 0); + ((SimpleAction) action_group.lookup_action (ACTION_REPLACE)).set_enabled (location_of_search > 0); + ((SimpleAction) action_group.lookup_action (ACTION_REPLACE_ALL)).set_enabled (count_of_search > 0); // Update tool arrows if (text_buffer == null || From d0649c2b27f4fd407a9f4b2f48a0af584bb4de9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 09:14:49 -0700 Subject: [PATCH 08/18] Avoid memory leak, cache action not group --- src/Widgets/SearchBar.vala | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index c98b20b39..c8af6b203 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -74,20 +74,21 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private Gtk.Revealer revealer; private Gtk.EventControllerKey key_controller; - private SimpleActionGroup action_group; + private SimpleAction replace_action; + private SimpleAction replace_all_action; public SearchBar (MainWindow window) { Object (window: window); } construct { - var replace_action = new SimpleAction (ACTION_REPLACE, null); + replace_action = new SimpleAction (ACTION_REPLACE, null); replace_action.activate.connect (action_replace); - var replace_all_action = new SimpleAction (ACTION_REPLACE_ALL, null); + replace_all_action = new SimpleAction (ACTION_REPLACE_ALL, null); replace_all_action.activate.connect (action_replace_all); - action_group = new SimpleActionGroup (); + var action_group = new SimpleActionGroup (); action_group.add_action (replace_action); action_group.add_action (replace_all_action); @@ -554,16 +555,16 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou // Update search occurrence label, tool arrows and replace buttons in sync private void update_search_widgets () { - var find_next_action = Utils.action_from_group (MainWindow.ACTION_FIND_NEXT, window.actions); - var find_previous_action = Utils.action_from_group (MainWindow.ACTION_FIND_PREVIOUS, window.actions); - cancel_update_search_widgets (); update_search_label_timeout_id = Timeout.add (100, () => { + var find_next_action = Utils.action_from_group (MainWindow.ACTION_FIND_NEXT, window.actions); + var find_previous_action = Utils.action_from_group (MainWindow.ACTION_FIND_PREVIOUS, window.actions); + update_search_label_timeout_id = 0; if (search_context == null) { debug ("update occurrence with null context"); - ((SimpleAction) action_group.lookup_action (ACTION_REPLACE)).set_enabled (false); - ((SimpleAction) action_group.lookup_action (ACTION_REPLACE_ALL)).set_enabled (false); + replace_action.set_enabled (false); + replace_all_action.set_enabled (false); find_next_action.set_enabled (false); find_previous_action.set_enabled (false); return Source.REMOVE; @@ -591,8 +592,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - ((SimpleAction) action_group.lookup_action (ACTION_REPLACE)).set_enabled (location_of_search > 0); - ((SimpleAction) action_group.lookup_action (ACTION_REPLACE_ALL)).set_enabled (count_of_search > 0); + replace_action.set_enabled (location_of_search > 0); + replace_all_action.set_enabled (count_of_search > 0); // Update tool arrows if (text_buffer == null || From 06d5064e0686bdae53b4b500c387639d5890ff5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 09:22:30 -0700 Subject: [PATCH 09/18] Set find action enabled all in one place --- src/MainWindow.vala | 2 -- src/Widgets/SearchBar.vala | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 5a6d1e761..0ff58eb34 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1340,8 +1340,6 @@ public class Scratch.MainWindow : Hdy.Window { var is_current_doc = get_current_document () != null; Utils.action_from_group (ACTION_FIND, actions).set_enabled (is_current_doc); Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions).set_enabled (is_current_doc); - Utils.action_from_group (ACTION_FIND_NEXT, actions).set_enabled (is_current_doc); - Utils.action_from_group (ACTION_FIND_PREVIOUS, actions).set_enabled (is_current_doc); var can_global_search = is_current_doc || git_manager.active_project_path != null; Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (can_global_search); diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index c8af6b203..c08c05f0a 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -560,6 +560,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var find_next_action = Utils.action_from_group (MainWindow.ACTION_FIND_NEXT, window.actions); var find_previous_action = Utils.action_from_group (MainWindow.ACTION_FIND_PREVIOUS, window.actions); + var is_current_doc = window.get_current_document () != null; + find_next_action.set_enabled (is_current_doc); + find_previous_action.set_enabled (is_current_doc); + update_search_label_timeout_id = 0; if (search_context == null) { debug ("update occurrence with null context"); From 8fff45650856fee1602bbab9132f5d60b003f785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 09:38:14 -0700 Subject: [PATCH 10/18] Make find actions self contained --- src/MainWindow.vala | 15 ----------- src/Widgets/SearchBar.vala | 51 ++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 0ff58eb34..18f7a7382 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -51,8 +51,6 @@ public class Scratch.MainWindow : Hdy.Window { public const string ACTION_PREFIX = ACTION_GROUP + "."; public const string ACTION_FIND = "action-find"; public const string ACTION_CLONE_REPO = "action-clone-repo"; - public const string ACTION_FIND_NEXT = "action-find-next"; - public const string ACTION_FIND_PREVIOUS = "action-find-previous"; public const string ACTION_FIND_GLOBAL = "action-find-global"; public const string ACTION_OPEN = "action-open"; public const string ACTION_OPEN_FOLDER = "action-open-folder"; @@ -106,8 +104,6 @@ public class Scratch.MainWindow : Hdy.Window { private const ActionEntry[] ACTION_ENTRIES = { { ACTION_CLONE_REPO, action_clone_repo }, { ACTION_FIND, action_find, "s"}, - { ACTION_FIND_NEXT, action_find_next }, - { ACTION_FIND_PREVIOUS, action_find_previous }, { ACTION_FIND_GLOBAL, action_find_global, "s" }, { ACTION_OPEN, action_open }, { ACTION_OPEN_FOLDER, action_open_folder, "s" }, @@ -192,8 +188,6 @@ public class Scratch.MainWindow : Hdy.Window { static construct { action_accelerators.set (ACTION_FIND + "::", "f"); - action_accelerators.set (ACTION_FIND_NEXT, "g"); - action_accelerators.set (ACTION_FIND_PREVIOUS, "g"); action_accelerators.set (ACTION_FIND_GLOBAL + "::", "f"); action_accelerators.set (ACTION_OPEN, "o"); action_accelerators.set (ACTION_OPEN_PROJECT, "o"); @@ -1302,15 +1296,6 @@ public class Scratch.MainWindow : Hdy.Window { } } - private void action_find_next () { - search_bar.search_next (); - } - - private void action_find_previous () { - search_bar.search_previous (); - } - - private void action_find_global (SimpleAction action, Variant? param) { if (!search_bar.is_focused || search_bar.search_text == "") { set_selected_text_for_search (); diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index c08c05f0a..43fe870d2 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -54,8 +54,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - private const string ACTION_GROUP = "search"; - private const string ACTION_PREFIX = ACTION_GROUP + "."; + public const string ACTION_GROUP = "find"; + public const string ACTION_PREFIX = ACTION_GROUP + "."; + public const string ACTION_FIND_NEXT = "action-find-next"; + public const string ACTION_FIND_PREVIOUS = "action-find-previous"; private const string ACTION_REPLACE = "replace"; private const string ACTION_REPLACE_ALL = "replace-all"; @@ -74,6 +76,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private Gtk.Revealer revealer; private Gtk.EventControllerKey key_controller; + private SimpleAction find_next_action; + private SimpleAction find_previous_action; private SimpleAction replace_action; private SimpleAction replace_all_action; @@ -82,6 +86,12 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } construct { + find_next_action = new SimpleAction (ACTION_FIND_NEXT, null); + find_next_action.activate.connect (action_find_next); + + find_previous_action = new SimpleAction (ACTION_FIND_PREVIOUS, null); + find_previous_action.activate.connect (action_find_previous); + replace_action = new SimpleAction (ACTION_REPLACE, null); replace_action.activate.connect (action_replace); @@ -89,11 +99,17 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou replace_all_action.activate.connect (action_replace_all); var action_group = new SimpleActionGroup (); + action_group.add_action (find_next_action); + action_group.add_action (find_previous_action); action_group.add_action (replace_action); action_group.add_action (replace_all_action); insert_action_group (ACTION_GROUP, action_group); + var app_instance = (Scratch.Application) GLib.Application.get_default (); + app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT, {"g"}); + app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS, {"g"}); + this.orientation = HORIZONTAL; search_entry = new Gtk.SearchEntry () { hexpand = true, @@ -103,24 +119,18 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou search_occurence_count_label = new Gtk.Label (_("No Results")); search_occurence_count_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL); - var app_instance = (Scratch.Application) GLib.Application.get_default (); - var tool_arrow_down = new Gtk.Button.from_icon_name ("go-down-symbolic", SMALL_TOOLBAR) { - action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT, + action_name = ACTION_PREFIX + ACTION_FIND_NEXT, tooltip_markup = Granite.markup_accel_tooltip ( - app_instance.get_accels_for_action ( - MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT - ), + app_instance.get_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT), _("Search next") ) }; var tool_arrow_up = new Gtk.Button.from_icon_name ("go-up-symbolic", SMALL_TOOLBAR) { - action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS, + action_name = ACTION_PREFIX + ACTION_FIND_PREVIOUS, tooltip_markup = Granite.markup_accel_tooltip ( - app_instance.get_accels_for_action ( - MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS - ), + app_instance.get_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS), _("Search previous") ) }; @@ -243,7 +253,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou }); search_entry.icon_release.connect ((p0, p1) => { if (p0 == Gtk.EntryIconPosition.PRIMARY) { - search_next (); + action_find_next (); } }); replace_entry.activate.connect (action_replace); @@ -336,7 +346,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou return true; } - public void search_previous () { + private void action_find_previous () { /* Get selection range */ Gtk.TextIter? start_iter, end_iter; if (text_buffer != null) { @@ -350,7 +360,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - public void search_next () { + private void action_find_next () { /* Get selection range */ Gtk.TextIter? start_iter, end_iter, end_iter_tmp; if (text_buffer != null) { @@ -390,11 +400,11 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou switch (key) { case "Return": case "Up": - search_previous (); + action_find_previous (); return true; case "Return": case "Down": - search_next (); + action_find_next (); return true; case "Tab": focus_replace_entry (); @@ -403,10 +413,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } else { switch (Gdk.keyval_name (keyval)) { case "Up": - search_previous (); + action_find_previous (); return true; case "Down": - search_next (); + action_find_next (); return true; case "Tab": focus_search_entry (); @@ -557,9 +567,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private void update_search_widgets () { cancel_update_search_widgets (); update_search_label_timeout_id = Timeout.add (100, () => { - var find_next_action = Utils.action_from_group (MainWindow.ACTION_FIND_NEXT, window.actions); - var find_previous_action = Utils.action_from_group (MainWindow.ACTION_FIND_PREVIOUS, window.actions); - var is_current_doc = window.get_current_document () != null; find_next_action.set_enabled (is_current_doc); find_previous_action.set_enabled (is_current_doc); From bd541ba21e4cc6d6f6fc86bd7dc068f504de28f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 09:50:27 -0700 Subject: [PATCH 11/18] Fix action keys --- src/MainWindow.vala | 14 ++++++++ src/Widgets/SearchBar.vala | 66 ++++---------------------------------- 2 files changed, 20 insertions(+), 60 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 18f7a7382..8a14da170 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -51,6 +51,8 @@ public class Scratch.MainWindow : Hdy.Window { public const string ACTION_PREFIX = ACTION_GROUP + "."; public const string ACTION_FIND = "action-find"; public const string ACTION_CLONE_REPO = "action-clone-repo"; + public const string ACTION_FIND_NEXT = "action-find-next"; + public const string ACTION_FIND_PREVIOUS = "action-find-previous"; public const string ACTION_FIND_GLOBAL = "action-find-global"; public const string ACTION_OPEN = "action-open"; public const string ACTION_OPEN_FOLDER = "action-open-folder"; @@ -104,6 +106,8 @@ public class Scratch.MainWindow : Hdy.Window { private const ActionEntry[] ACTION_ENTRIES = { { ACTION_CLONE_REPO, action_clone_repo }, { ACTION_FIND, action_find, "s"}, + { ACTION_FIND_NEXT, action_find_next }, + { ACTION_FIND_PREVIOUS, action_find_previous }, { ACTION_FIND_GLOBAL, action_find_global, "s" }, { ACTION_OPEN, action_open }, { ACTION_OPEN_FOLDER, action_open_folder, "s" }, @@ -188,6 +192,8 @@ public class Scratch.MainWindow : Hdy.Window { static construct { action_accelerators.set (ACTION_FIND + "::", "f"); + action_accelerators.set (ACTION_FIND_NEXT, "g"); + action_accelerators.set (ACTION_FIND_PREVIOUS, "g"); action_accelerators.set (ACTION_FIND_GLOBAL + "::", "f"); action_accelerators.set (ACTION_OPEN, "o"); action_accelerators.set (ACTION_OPEN_PROJECT, "o"); @@ -1296,6 +1302,14 @@ public class Scratch.MainWindow : Hdy.Window { } } + private void action_find_next () { + search_bar.action_find_next (); + } + + private void action_find_previous () { + search_bar.action_find_previous (); + } + private void action_find_global (SimpleAction action, Variant? param) { if (!search_bar.is_focused || search_bar.search_text == "") { set_selected_text_for_search (); diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 43fe870d2..1b2640727 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -74,7 +74,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private Gtk.SourceSearchContext? search_context; private uint update_search_label_timeout_id = 0; private Gtk.Revealer revealer; - private Gtk.EventControllerKey key_controller; private SimpleAction find_next_action; private SimpleAction find_previous_action; @@ -107,8 +106,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou insert_action_group (ACTION_GROUP, action_group); var app_instance = (Scratch.Application) GLib.Application.get_default (); - app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT, {"g"}); - app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS, {"g"}); + app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT, {"Return", "Down"}); + app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS, {"Return", "Up"}); this.orientation = HORIZONTAL; search_entry = new Gtk.SearchEntry () { @@ -122,7 +121,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var tool_arrow_down = new Gtk.Button.from_icon_name ("go-down-symbolic", SMALL_TOOLBAR) { action_name = ACTION_PREFIX + ACTION_FIND_NEXT, tooltip_markup = Granite.markup_accel_tooltip ( - app_instance.get_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT), + {"g"}, _("Search next") ) }; @@ -130,7 +129,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var tool_arrow_up = new Gtk.Button.from_icon_name ("go-up-symbolic", SMALL_TOOLBAR) { action_name = ACTION_PREFIX + ACTION_FIND_PREVIOUS, tooltip_markup = Granite.markup_accel_tooltip ( - app_instance.get_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS), + {"g"}, _("Search previous") ) }; @@ -151,7 +150,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou case_sensitive_box.get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM); var regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")); - var whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")); var search_option_box = new Gtk.Box (VERTICAL, 0) { @@ -274,11 +272,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou add (revealer); update_search_widgets (); - - key_controller = new Gtk.EventControllerKey (window) { - propagation_phase = CAPTURE - }; - key_controller.key_pressed.connect (on_key_pressed); } public void set_text_view (Scratch.Widgets.SourceView? text_view) { @@ -346,7 +339,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou return true; } - private void action_find_previous () { + public void action_find_previous () { /* Get selection range */ Gtk.TextIter? start_iter, end_iter; if (text_buffer != null) { @@ -360,7 +353,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } } - private void action_find_next () { + public void action_find_next () { /* Get selection range */ Gtk.TextIter? start_iter, end_iter, end_iter_tmp; if (text_buffer != null) { @@ -382,53 +375,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou replace_entry.grab_focus (); } - private bool on_key_pressed (uint keyval, uint keycode, Gdk.ModifierType state) { - if (!(search_entry.has_focus || replace_entry.has_focus)) { - return false; - } - /* We don't need to perform search if there is nothing to search... */ - if (search_entry.text == "") { - return false; - } - - string key = Gdk.keyval_name (keyval); - if (Gdk.ModifierType.SHIFT_MASK in state) { - key = "" + key; - } - - if (search_entry.has_focus) { - switch (key) { - case "Return": - case "Up": - action_find_previous (); - return true; - case "Return": - case "Down": - action_find_next (); - return true; - case "Tab": - focus_replace_entry (); - return true; - } - } else { - switch (Gdk.keyval_name (keyval)) { - case "Up": - action_find_previous (); - return true; - case "Down": - action_find_next (); - return true; - case "Tab": - focus_search_entry (); - return true; - } - - return false; - } - - return false; - } - private void action_replace () { if (text_buffer == null) { warning ("No valid buffer to replace"); From 768a40a8f29a4a9c52fa0d553a779f0352cdbc08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:31:58 -0700 Subject: [PATCH 12/18] Revert settings changes --- src/Widgets/SearchBar.vala | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 1b2640727..e9e8f2fee 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -66,6 +66,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou * "Down", it will go at the start of the file to search for the content * of the search entry. **/ + private Granite.SwitchModelButton cycle_search_button; + private Gtk.ComboBoxText case_sensitive_search_button; + private Granite.SwitchModelButton regex_search_button; + private Granite.SwitchModelButton whole_word_search_button; private Gtk.SearchEntry search_entry; private Gtk.SearchEntry replace_entry; private Gtk.Label search_occurence_count_label; @@ -134,9 +138,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou ) }; - var cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")); + cycle_search_button = new Granite.SwitchModelButton (_("Cyclic Search")); - var case_sensitive_search_button = new Gtk.ComboBoxText (); + case_sensitive_search_button = new Gtk.ComboBoxText (); case_sensitive_search_button.append ("never", _("Never")); case_sensitive_search_button.append ("mixed", _("Mixed Case")); case_sensitive_search_button.append ("always", _("Always")); @@ -149,8 +153,8 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou case_sensitive_box.add (case_sensitive_search_button); case_sensitive_box.get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM); - var regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")); - var whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")); + regex_search_button = new Granite.SwitchModelButton (_("Use Regular Expressions")); + whole_word_search_button = new Granite.SwitchModelButton (_("Match Whole Words")); var search_option_box = new Gtk.Box (VERTICAL, 0) { margin_top = 3, @@ -176,10 +180,10 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou }; search_menubutton.add (search_buttonbox); - settings.changed["case-sensitive-search"].connect (on_search_parameters_changed); - settings.changed["cyclic-search"].connect (on_search_parameters_changed); - settings.changed["regex-search"].connect (on_search_parameters_changed); - settings.changed["wholeword-search"].connect (on_search_parameters_changed); + cycle_search_button.toggled.connect (on_search_parameters_changed); + case_sensitive_search_button.connect (on_search_parameters_changed); + whole_word_search_button.toggled.connect (on_search_parameters_changed); + regex_search_button.toggled.connect (on_search_parameters_changed); // Bind some application settings settings.bind ("cyclic-search", cycle_search_button, "active", DEFAULT); @@ -188,10 +192,18 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou settings.bind ("regex-search", regex_search_button, "active", DEFAULT); // These settings are ignored when regex searching - settings.bind ("regex-search", cycle_search_button, "sensitive", INVERT_BOOLEAN); - settings.bind ("regex-search", whole_word_search_button, "sensitive", INVERT_BOOLEAN); - settings.bind ("regex-search", case_sensitive_search_button, "sensitive", INVERT_BOOLEAN); - settings.bind ("regex-search", case_sensitive_search_label, "sensitive", INVERT_BOOLEAN); + regex_search_button.bind_property ( + "active", cycle_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN + ); + regex_search_button.bind_property ( + "active", whole_word_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN + ); + regex_search_button.bind_property ( + "active", case_sensitive_search_label, "sensitive", SYNC_CREATE | INVERT_BOOLEAN + ); + regex_search_button.bind_property ( + "active", case_sensitive_search_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN + ); var search_box = new Gtk.Box (HORIZONTAL, 0) { margin_top = 3, @@ -294,7 +306,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou this.text_buffer = text_view.get_buffer (); this.text_buffer.changed.connect (update_search_widgets); this.search_context = new Gtk.SourceSearchContext (text_buffer as Gtk.SourceBuffer, null); - search_context.settings.wrap_around = settings.get_boolean ("cyclic-search"); + search_context.settings.wrap_around = cycle_search_button.active; search_context.settings.regex_enabled = settings.get_boolean ("regex-search"); search_context.settings.search_text = search_entry.text; update_search_widgets (); From 39364796613aa1343c649cbb3a3b88cf8d0685de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:34:18 -0700 Subject: [PATCH 13/18] Revert more --- src/Widgets/SearchBar.vala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index e9e8f2fee..1cd2f3fc4 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -66,7 +66,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou * "Down", it will go at the start of the file to search for the content * of the search entry. **/ - private Granite.SwitchModelButton cycle_search_button; + private Granite.SwitchModelButton cycle_search_button ; private Gtk.ComboBoxText case_sensitive_search_button; private Granite.SwitchModelButton regex_search_button; private Granite.SwitchModelButton whole_word_search_button; @@ -181,7 +181,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou search_menubutton.add (search_buttonbox); cycle_search_button.toggled.connect (on_search_parameters_changed); - case_sensitive_search_button.connect (on_search_parameters_changed); + case_sensitive_search_button.changed.connect (on_search_parameters_changed); whole_word_search_button.toggled.connect (on_search_parameters_changed); regex_search_button.toggled.connect (on_search_parameters_changed); @@ -307,7 +307,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou this.text_buffer.changed.connect (update_search_widgets); this.search_context = new Gtk.SourceSearchContext (text_buffer as Gtk.SourceBuffer, null); search_context.settings.wrap_around = cycle_search_button.active; - search_context.settings.regex_enabled = settings.get_boolean ("regex-search"); + search_context.settings.regex_enabled = regex_search_button.active; search_context.settings.search_text = search_entry.text; update_search_widgets (); } @@ -433,7 +433,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou if (search_context != null) { var search_string = search_entry.text; search_context.settings.search_text = search_string; - var case_mode = settings.get_enum ("case-sensitive-search"); + var case_mode = (CaseSensitiveMode)(case_sensitive_search_button.active); switch (case_mode) { case CaseSensitiveMode.NEVER: search_context.settings.case_sensitive = false; @@ -452,7 +452,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou } search_context.settings.at_word_boundaries = settings.get_boolean ("wholeword-search"); - search_context.settings.regex_enabled = settings.get_boolean ("regex-search"); + search_context.settings.regex_enabled = regex_search_button.active; } update_search_widgets (); From 6b1c70e3ad2838d80303760714f5e028acfa555d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:35:55 -0700 Subject: [PATCH 14/18] Fix more reverts --- src/Widgets/SearchBar.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 1cd2f3fc4..3279b1b52 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -356,7 +356,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou Gtk.TextIter? start_iter, end_iter; if (text_buffer != null) { text_buffer.get_selection_bounds (out start_iter, out end_iter); - if (!search_for_iter_backward (start_iter, out end_iter) && settings.get_boolean ("cyclic-search")) { + if (!search_for_iter_backward (start_iter, out end_iter) && cycle_search_button.active) { text_buffer.get_end_iter (out start_iter); search_for_iter_backward (start_iter, out end_iter); } @@ -370,7 +370,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou Gtk.TextIter? start_iter, end_iter, end_iter_tmp; if (text_buffer != null) { text_buffer.get_selection_bounds (out start_iter, out end_iter); - if (!search_for_iter (end_iter, out end_iter_tmp) && settings.get_boolean ("cyclic-search")) { + if (!search_for_iter (end_iter, out end_iter_tmp) && cycle_search_button.active) { text_buffer.get_start_iter (out start_iter); search_for_iter (start_iter, out end_iter); } @@ -451,7 +451,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou assert_not_reached (); } - search_context.settings.at_word_boundaries = settings.get_boolean ("wholeword-search"); + search_context.settings.at_word_boundaries = whole_word_search_button.active; search_context.settings.regex_enabled = regex_search_button.active; } @@ -572,7 +572,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou find_previous_action.set_enabled (false); find_next_action.set_enabled (false); } else { - if (settings.get_boolean ("cyclic-search")) { + if (cycle_search_button.active) { find_next_action.set_enabled (true); find_previous_action.set_enabled (true); } else { From b786a2d6faffd88c927dc500bf4c52786bf26ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:37:53 -0700 Subject: [PATCH 15/18] Don't hardcode accels --- src/Widgets/SearchBar.vala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 3279b1b52..964b97170 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -125,7 +125,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var tool_arrow_down = new Gtk.Button.from_icon_name ("go-down-symbolic", SMALL_TOOLBAR) { action_name = ACTION_PREFIX + ACTION_FIND_NEXT, tooltip_markup = Granite.markup_accel_tooltip ( - {"g"}, + app_instance.get_accels_for_action ( + MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT + ), _("Search next") ) }; @@ -133,7 +135,9 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou var tool_arrow_up = new Gtk.Button.from_icon_name ("go-up-symbolic", SMALL_TOOLBAR) { action_name = ACTION_PREFIX + ACTION_FIND_PREVIOUS, tooltip_markup = Granite.markup_accel_tooltip ( - {"g"}, + app_instance.get_accels_for_action ( + MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS + ), _("Search previous") ) }; From 8ad1b7bb3659eb90693539d3b345778fd58fd4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:39:56 -0700 Subject: [PATCH 16/18] revert changes to global shortcut action --- src/MainWindow.vala | 2 ++ src/Widgets/SearchBar.vala | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 8a14da170..ee5d76430 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1339,6 +1339,8 @@ public class Scratch.MainWindow : Hdy.Window { var is_current_doc = get_current_document () != null; Utils.action_from_group (ACTION_FIND, actions).set_enabled (is_current_doc); Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions).set_enabled (is_current_doc); + Utils.action_from_group (ACTION_FIND_NEXT, actions).set_enabled (is_current_doc); + Utils.action_from_group (ACTION_FIND_PREVIOUS, actions).set_enabled (is_current_doc); var can_global_search = is_current_doc || git_manager.active_project_path != null; Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (can_global_search); diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 964b97170..28df0f4e1 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -529,10 +529,6 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou private void update_search_widgets () { cancel_update_search_widgets (); update_search_label_timeout_id = Timeout.add (100, () => { - var is_current_doc = window.get_current_document () != null; - find_next_action.set_enabled (is_current_doc); - find_previous_action.set_enabled (is_current_doc); - update_search_label_timeout_id = 0; if (search_context == null) { debug ("update occurrence with null context"); From 199853ef2fc3ed80d486458a0524b209cf940c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:41:33 -0700 Subject: [PATCH 17/18] Add comment --- src/Widgets/SearchBar.vala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 28df0f4e1..553b412d6 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -126,6 +126,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou action_name = ACTION_PREFIX + ACTION_FIND_NEXT, tooltip_markup = Granite.markup_accel_tooltip ( app_instance.get_accels_for_action ( + // Accels for window, not accels for when this is focused MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_NEXT ), _("Search next") @@ -136,6 +137,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou action_name = ACTION_PREFIX + ACTION_FIND_PREVIOUS, tooltip_markup = Granite.markup_accel_tooltip ( app_instance.get_accels_for_action ( + // Accels for window, not accels for when this is focused MainWindow.ACTION_PREFIX + MainWindow.ACTION_FIND_PREVIOUS ), _("Search previous") From d7d94a8e26d647525f4a76e61a72fc58fea20569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 25 Aug 2026 13:43:34 -0700 Subject: [PATCH 18/18] Fix replace when activating --- src/Widgets/SearchBar.vala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 553b412d6..c85d68bf8 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -110,7 +110,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou insert_action_group (ACTION_GROUP, action_group); var app_instance = (Scratch.Application) GLib.Application.get_default (); - app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT, {"Return", "Down"}); + app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_NEXT, {"Down"}); app_instance.set_accels_for_action (ACTION_PREFIX + ACTION_FIND_PREVIOUS, {"Return", "Up"}); this.orientation = HORIZONTAL; @@ -272,6 +272,7 @@ public class Scratch.Widgets.SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayou action_find_next (); } }); + search_entry.activate.connect (action_find_next); replace_entry.activate.connect (action_replace); var flowbox = new Gtk.FlowBox () {