From 303155ee94da9e47aff010487b4a5dfb23fefefc Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 11:59:55 +0000 Subject: [PATCH 1/6] Convert to popover --- src/Widgets/Sidebar.vala | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Widgets/Sidebar.vala b/src/Widgets/Sidebar.vala index 2f95327ea..79b1cf5d3 100644 --- a/src/Widgets/Sidebar.vala +++ b/src/Widgets/Sidebar.vala @@ -77,25 +77,28 @@ public class Code.Sidebar : Gtk.Grid { var actionbar = new Gtk.ActionBar (); actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR); - var collapse_all_menu_item = new GLib.MenuItem (_("Collapse All"), Scratch.MainWindow.ACTION_PREFIX - + Scratch.MainWindow.ACTION_COLLAPSE_ALL_FOLDERS); + var collapse_all_menu_item = new Gtk.ModelButton () { + text = _("Collapse All"), + action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_COLLAPSE_ALL_FOLDERS + }; - var order_projects_menu_item = new GLib.MenuItem (_("Alphabetize"), Scratch.MainWindow.ACTION_PREFIX - + Scratch.MainWindow.ACTION_ORDER_FOLDERS); + var order_projects_menu_item = new Gtk.ModelButton () { + text = _("Alphabetize"), + action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_ORDER_FOLDERS + }; - var project_menu = new GLib.Menu (); - project_menu.append_item (collapse_all_menu_item); - project_menu.append_item (order_projects_menu_item); - project_menu_model = project_menu; + var project_menu = new Gtk.Box (VERTICAL, 0); + project_menu.add (collapse_all_menu_item); + project_menu.add (order_projects_menu_item); + project_menu.show_all (); + var project_menu_model = new Gtk.Popover (null); + project_menu_model.add (project_menu); - var label = new Gtk.Label ( _("Manage project folders…")) { - halign = START - }; var project_menu_button = new Gtk.MenuButton () { hexpand = true, - use_popover = false, - menu_model = project_menu_model, - child = label + halign = START, + popover = project_menu_model, + label = _("Manage project folders…") }; actionbar.pack_start (project_menu_button); From 154e24dee89c3ea8dd203eaa2ea65b8bc939ef89 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 12:25:01 +0000 Subject: [PATCH 2/6] Allow insert plugin item --- plugins/fuzzy-search/fuzzy-search.vala | 26 ++++++++++---------------- src/Widgets/Sidebar.vala | 19 +++++++++++++++++-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/plugins/fuzzy-search/fuzzy-search.vala b/plugins/fuzzy-search/fuzzy-search.vala index 41ebeec14..e8a935704 100644 --- a/plugins/fuzzy-search/fuzzy-search.vala +++ b/plugins/fuzzy-search/fuzzy-search.vala @@ -10,11 +10,12 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A public Object object { owned get; set construct; } private const uint ACCEL_KEY = Gdk.Key.F; private const Gdk.ModifierType ACCEL_MODTYPE = Gdk.ModifierType.MOD1_MASK; + private const string FUZZY_FINDER_ID = "fuzzy-finder"; private Scratch.Services.FuzzySearchIndexer indexer; private MainWindow window = null; private Scratch.Services.Interface plugins; - private GLib.MenuItem fuzzy_menuitem; + // private GLib.MenuItem fuzzy_menuitem; private GLib.Cancellable cancellable; private const string ACTION_GROUP = "fuzzysearch"; @@ -88,25 +89,18 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A handle_opened_projects_change (); - fuzzy_menuitem = new GLib.MenuItem (_("Find Project Files"), ACTION_PREFIX + ACTION_SHOW ); + var fuzzy_menuitem = new Gtk.ModelButton () { + text = _("Find Project Files"), + action_name = ACTION_PREFIX + ACTION_SHOW + }; - var menu = window.sidebar.project_menu_model as GLib.Menu; - menu.append_item (fuzzy_menuitem); + fuzzy_menuitem.show (); + window.sidebar.add_project_menu_widget (FUZZY_FINDER_ID, fuzzy_menuitem); } private void remove_actions () { - var sidebar_menu = window.sidebar.project_menu_model as GLib.Menu; - int length = sidebar_menu.get_n_items (); - for (var i = length - 1; i >= 0; i--) { - var action_name = sidebar_menu.get_item_attribute_value ( - i, - GLib.Menu.ATTRIBUTE_ACTION, - GLib.VariantType.STRING - ).get_string (); - if (action_name.has_prefix (ACTION_PREFIX)) { - sidebar_menu.remove (i); - } - } + var sidebar_menu = window.sidebar.project_menu; + window.sidebar.remove_project_menu_widget (FUZZY_FINDER_ID); var application = (Gtk.Application) GLib.Application.get_default (); var app = (Scratch.Application) application; diff --git a/src/Widgets/Sidebar.vala b/src/Widgets/Sidebar.vala index 79b1cf5d3..ccd4c1ded 100644 --- a/src/Widgets/Sidebar.vala +++ b/src/Widgets/Sidebar.vala @@ -25,7 +25,8 @@ public class Code.Sidebar : Gtk.Grid { public Gtk.Stack stack { get; private set; } public Code.ChooseProjectButton choose_project_button { get; private set; } public Hdy.HeaderBar headerbar { get; private set; } - public GLib.MenuModel project_menu_model { get; construct; } + public Gtk.Box project_menu { get; private set; } + private HashTable project_menu_map; // May show progress in different way in future public bool cloning_in_progress { get { @@ -87,7 +88,7 @@ public class Code.Sidebar : Gtk.Grid { action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_ORDER_FOLDERS }; - var project_menu = new Gtk.Box (VERTICAL, 0); + project_menu = new Gtk.Box (VERTICAL, 0); project_menu.add (collapse_all_menu_item); project_menu.add (order_projects_menu_item); project_menu.show_all (); @@ -134,6 +135,20 @@ public class Code.Sidebar : Gtk.Grid { Gtk.TargetEntry uris = {"text/uri-list", 0, TargetType.URI_LIST}; Gtk.drag_dest_set (this, Gtk.DestDefaults.ALL, {uris}, Gdk.DragAction.COPY); drag_data_received.connect (drag_received); + + project_menu_map = new HashTable (str_hash, str_equal); + } + + public void add_project_menu_widget (string id, Gtk.Widget widget) { + project_menu.add (widget); + project_menu_map.@set (id, widget); + } + + public void remove_project_menu_widget (string id) { + var item = project_menu_map.take (id); + if (item != null) { + item.destroy (); + } } private void drag_received (Gtk.Widget w, From f67a75692e66469c13600f080815784786618c85 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 12:54:46 +0000 Subject: [PATCH 3/6] Show accel string; use separator --- plugins/fuzzy-search/fuzzy-search.vala | 17 +++++++++++------ src/Widgets/Sidebar.vala | 12 ++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/plugins/fuzzy-search/fuzzy-search.vala b/plugins/fuzzy-search/fuzzy-search.vala index e8a935704..450d42d83 100644 --- a/plugins/fuzzy-search/fuzzy-search.vala +++ b/plugins/fuzzy-search/fuzzy-search.vala @@ -15,7 +15,6 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A private Scratch.Services.FuzzySearchIndexer indexer; private MainWindow window = null; private Scratch.Services.Interface plugins; - // private GLib.MenuItem fuzzy_menuitem; private GLib.Cancellable cancellable; private const string ACTION_GROUP = "fuzzysearch"; @@ -29,9 +28,11 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A private GLib.Settings folder_settings; private static Gee.MultiMap action_accelerators = new Gee.HashMultiMap (); + private static string accel_string; static construct { - action_accelerators.set (ACTION_SHOW, @"$(Gdk.keyval_name (ACCEL_KEY))"); + accel_string = @"$(Gdk.keyval_name (ACCEL_KEY))"; + action_accelerators.set (ACTION_SHOW, accel_string); } public void update_state () { @@ -89,12 +90,16 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A handle_opened_projects_change (); - var fuzzy_menuitem = new Gtk.ModelButton () { - text = _("Find Project Files"), - action_name = ACTION_PREFIX + ACTION_SHOW + var label = new Granite.AccelLabel (_("Search Project Files…")) { + action_name = ACTION_PREFIX + ACTION_SHOW, + accel_string = accel_string }; + var fuzzy_menuitem = new Gtk.Button () { // Cannot change child of ModelButton + action_name = ACTION_PREFIX + ACTION_SHOW, + child = label + }; + fuzzy_menuitem.get_style_context ().add_class ("flat"); - fuzzy_menuitem.show (); window.sidebar.add_project_menu_widget (FUZZY_FINDER_ID, fuzzy_menuitem); } diff --git a/src/Widgets/Sidebar.vala b/src/Widgets/Sidebar.vala index ccd4c1ded..1af0be81c 100644 --- a/src/Widgets/Sidebar.vala +++ b/src/Widgets/Sidebar.vala @@ -27,6 +27,7 @@ public class Code.Sidebar : Gtk.Grid { public Hdy.HeaderBar headerbar { get; private set; } public Gtk.Box project_menu { get; private set; } private HashTable project_menu_map; + private Gtk.Separator project_menu_separator; // Divides plugin items from core items // May show progress in different way in future public bool cloning_in_progress { get { @@ -140,8 +141,14 @@ public class Code.Sidebar : Gtk.Grid { } public void add_project_menu_widget (string id, Gtk.Widget widget) { + if (project_menu_map.size () == 0) { + project_menu_separator = new Gtk.Separator (HORIZONTAL); + project_menu.add (project_menu_separator); + } + project_menu.add (widget); project_menu_map.@set (id, widget); + project_menu.show_all (); } public void remove_project_menu_widget (string id) { @@ -149,6 +156,11 @@ public class Code.Sidebar : Gtk.Grid { if (item != null) { item.destroy (); } + + if (project_menu_map.size () == 0) { + project_menu_separator.destroy (); + } + } private void drag_received (Gtk.Widget w, From bdc4e534e0dc13310a03e4cd95b278e46690293f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 14:14:44 +0000 Subject: [PATCH 4/6] Reorder folders on add folder if option true --- src/FolderManager/FileView.vala | 17 ++++++++++++++--- src/MainWindow.vala | 11 +++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index 2bb5035b3..eff964a15 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -63,6 +63,7 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane public ActionGroup toplevel_action_group { get; private set; } public string icon_name { get; set; } public string title { get; set; } + public bool order_folders { get; set; default = true; } public FileView (Scratch.Services.PluginsManager plugins_manager) { plugins = plugins_manager; @@ -85,6 +86,12 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane toplevel_action_group = get_action_group (MainWindow.ACTION_GROUP); assert_nonnull (toplevel_action_group); }); + + notify["order-folders"].connect (() => { + if (order_folders) { + reorder_folders (); + } + }); } private void action_close_folder (SimpleAction action, GLib.Variant? parameter) { @@ -168,9 +175,9 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane } } - public void order_folders () { + private void reorder_folders () { + // This is not efficient but SourceList does not currently allow `insert_sorted` or setting a sort function var list = new Gee.ArrayList (); - foreach (var child in root.children) { root.remove (child as ProjectFolderItem); list.add (child as ProjectFolderItem); @@ -567,8 +574,12 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane // Process any closed signals emitted before proceeding Idle.add (() => { var folder_root = new ProjectFolderItem (folder, this); // Constructor adds project to GitManager - this.root.add (folder_root); + this.root.add (folder_root); // TODO Implement add_sorted; rename_items_with_same_name (folder_root); + if (order_folders) { + reorder_folders (); + } + folder_root.expanded = expand; folder_root.closed.connect (() => { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index bcf37aeb6..3a87d4024 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -141,7 +141,7 @@ namespace Scratch { { ACTION_OPEN_FOLDER, action_open_folder, "s" }, { ACTION_OPEN_PROJECT, action_open_project }, { ACTION_COLLAPSE_ALL_FOLDERS, action_collapse_all_folders }, - { ACTION_ORDER_FOLDERS, action_order_folders }, + { ACTION_ORDER_FOLDERS, action_order_folders, null, "true" }, { ACTION_PREFERENCES, action_preferences }, { ACTION_REVERT, action_revert }, { ACTION_SAVE, action_save }, @@ -347,6 +347,10 @@ namespace Scratch { sidebar_action.set_state (saved_state.get_boolean ("sidebar-visible")); update_toolbar_button (ACTION_TOGGLE_SIDEBAR, saved_state.get_boolean ("sidebar-visible")); + // var order_folders_action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions); + // order_folders_action.set_state (saved_state.get_boolean ("order-folders")); + // update_toolbar_button (ACTION_ORDER_FOLDERS, saved_state.get_boolean ("order-folders")); + var outline_action = Utils.action_from_group (ACTION_TOGGLE_OUTLINE, actions); outline_action.set_state (saved_state.get_boolean ("outline-visible")); update_toolbar_button (ACTION_TOGGLE_OUTLINE, saved_state.get_boolean ("outline-visible")); @@ -1126,7 +1130,10 @@ namespace Scratch { } private void action_order_folders () { - folder_manager_view.order_folders (); + var action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions); + var to_show = !action.get_state ().get_boolean (); + action.set_state (to_show); + folder_manager_view.order_folders = to_show; } private void action_save () { From 1bedcc44fa5ce4bcf37ec27963c2ba215260fb58 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 14:35:02 +0000 Subject: [PATCH 5/6] Persist order-folders setting --- data/io.elementary.code.gschema.xml | 5 +++++ src/MainWindow.vala | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml index 0f78a64f7..58e76f580 100644 --- a/data/io.elementary.code.gschema.xml +++ b/data/io.elementary.code.gschema.xml @@ -58,6 +58,11 @@ Terminal visibility Whether or not the terminal pane is visible + + true + Sort open projects + Keep the open projects in alphabetical order + '' Last opened path diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 3a87d4024..ecf6d0e60 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -347,9 +347,8 @@ namespace Scratch { sidebar_action.set_state (saved_state.get_boolean ("sidebar-visible")); update_toolbar_button (ACTION_TOGGLE_SIDEBAR, saved_state.get_boolean ("sidebar-visible")); - // var order_folders_action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions); - // order_folders_action.set_state (saved_state.get_boolean ("order-folders")); - // update_toolbar_button (ACTION_ORDER_FOLDERS, saved_state.get_boolean ("order-folders")); + var order_folders_action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions); + order_folders_action.set_state (saved_state.get_boolean ("order-folders")); var outline_action = Utils.action_from_group (ACTION_TOGGLE_OUTLINE, actions); outline_action.set_state (saved_state.get_boolean ("outline-visible")); @@ -571,6 +570,7 @@ namespace Scratch { Scratch.saved_state.bind ("sidebar-visible", sidebar, "visible", SettingsBindFlags.DEFAULT); Scratch.saved_state.bind ("outline-visible", document_view , "outline_visible", SettingsBindFlags.DEFAULT); Scratch.saved_state.bind ("terminal-visible", terminal, "visible", SettingsBindFlags.DEFAULT); + Scratch.saved_state.bind ("order-folders", folder_manager_view, "order-folders", SettingsBindFlags.DEFAULT); // Plugins hook HookFunc hook_func = () => { plugins.hook_window (this); From 6cfef40f1df7efdfec81b0de3688a6ac64f3ed39 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 5 Nov 2025 14:40:22 +0000 Subject: [PATCH 6/6] Don't change label --- plugins/fuzzy-search/fuzzy-search.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/fuzzy-search/fuzzy-search.vala b/plugins/fuzzy-search/fuzzy-search.vala index 450d42d83..21fc73e54 100644 --- a/plugins/fuzzy-search/fuzzy-search.vala +++ b/plugins/fuzzy-search/fuzzy-search.vala @@ -90,7 +90,7 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A handle_opened_projects_change (); - var label = new Granite.AccelLabel (_("Search Project Files…")) { + var label = new Granite.AccelLabel (_("Find Project Files")) { action_name = ACTION_PREFIX + ACTION_SHOW, accel_string = accel_string };