From c50f28dc5178151ebc7f1a3498567d8615c2eed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 12 Jul 2023 16:08:00 -0700 Subject: [PATCH 01/23] =?UTF-8?q?Window:=20DynamicNotebook=20=E2=86=92=20H?= =?UTF-8?q?dy.TabBar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/View/ViewContainer.vala | 1 + src/View/Window.vala | 357 ++++++++++++++++++++---------------- 2 files changed, 201 insertions(+), 157 deletions(-) diff --git a/src/View/ViewContainer.vala b/src/View/ViewContainer.vala index 360175acbf..97d92eeab7 100644 --- a/src/View/ViewContainer.vala +++ b/src/View/ViewContainer.vala @@ -28,6 +28,7 @@ namespace Files.View { public Gtk.Widget? content_item; public bool can_show_folder { get; private set; default = false; } private View.Window? _window = null; + public bool working { get; set; } public View.Window window { get { return _window; diff --git a/src/View/Window.vala b/src/View/Window.vala index 2c34aef7c9..e10d8f13e1 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -53,15 +53,22 @@ public class Files.View.Window : Hdy.ApplicationWindow { } } + public ViewContainer? current_container { + get { + return tab_view.selected_page != null ? + (ViewContainer)(tab_view.selected_page.child) : null; + } + } + public Gtk.Builder ui; public Files.Application marlin_app { get; construct; } private unowned UndoManager undo_manager; public Chrome.HeaderBar top_menu; public Chrome.ViewSwitcher view_switcher; - public Granite.Widgets.DynamicNotebook tabs; + public Hdy.TabView tab_view; + public Hdy.TabBar tab_bar; private Gtk.Paned lside_pane; public SidebarInterface sidebar; - public ViewContainer? current_tab = null; private bool tabs_restored = false; private int restoring_tabs = 0; @@ -167,23 +174,34 @@ public class Files.View.Window : Hdy.ApplicationWindow { custom_title = new Gtk.Label (null) }; - tabs = new Granite.Widgets.DynamicNotebook.with_accellabels ( - new Granite.AccelLabel (_("New Tab"), "t"), - new Granite.AccelLabel (_("Undo Close Tab"), "t") - ) { - show_tabs = true, - allow_restoring = true, - allow_duplication = true, - allow_new_window = true, - group_name = Config.APP_NAME - }; + tab_view = new Hdy.TabView (); - this.configure_event.connect_after ((e) => { - tabs.set_size_request (e.width / 2, -1); - return false; - }); + tab_bar = new Hdy.TabBar () { + autohide = false, + expand_tabs = false, + view = tab_view + }; - tabs.show (); + var tab_box = new Gtk.Box (VERTICAL, 0); + tab_box.add (tab_bar); + tab_box.add (tab_view); + + // tabs = new Granite.Widgets.DynamicNotebook.with_accellabels ( + // new Granite.AccelLabel (_("New Tab"), "t"), + // new Granite.AccelLabel (_("Undo Close Tab"), "t") + // ) { + // show_tabs = true, + // allow_restoring = true, + // allow_duplication = true, + // allow_new_window = true, + // group_name = Config.APP_NAME + // }; + + // TODO Reimplement if needed + // this.configure_event.connect_after ((e) => { + // tabs.set_size_request (e.width / 2, -1); + // return false; + // }); sidebar = new Sidebar.SidebarWindow (); free_space_change.connect (sidebar.on_free_space_change); @@ -193,7 +211,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { position = Files.app_settings.get_int ("sidebar-width") }; lside_pane.pack1 (sidebar, false, false); - lside_pane.pack2 (tabs, true, true); + lside_pane.pack2 (tab_box, true, true); var grid = new Gtk.Grid (); grid.attach (top_menu, 0, 0); @@ -218,18 +236,18 @@ public class Files.View.Window : Hdy.ApplicationWindow { top_menu.escape.connect (grab_focus); top_menu.path_change_request.connect ((loc, flag) => { - current_tab.is_frozen = false; + current_container.is_frozen = false; uri_path_change_request (loc, flag); }); top_menu.focus_location_request.connect ((loc) => { - current_tab.focus_location_if_in_current_directory (loc, true); + current_container.focus_location_if_in_current_directory (loc, true); }); top_menu.focus_in_event.connect (() => { - current_tab.is_frozen = true; + current_container.is_frozen = true; return true; }); top_menu.focus_out_event.connect (() => { - current_tab.is_frozen = false; + current_container.is_frozen = false; return true; }); @@ -268,78 +286,84 @@ public class Files.View.Window : Hdy.ApplicationWindow { return false; }); - tabs.new_tab_requested.connect (() => { - add_tab (); - }); + // tabs.new_tab_requested.connect (() => { + // add_tab (); + // }); + + //TODO Implement handlers for new signals + tab_view.indicator_activated.connect (() => {}); + tab_view.setup_menu.connect (() => {}); - tabs.close_tab_requested.connect ((tab) => { - var view_container = (ViewContainer)(tab.page); - tab.restore_data = view_container.location.get_uri (); + tab_view.close_page.connect ((tab) => { + var view_container = (ViewContainer)(tab.child); + // tab.restore_data = view_container.location.get_uri (); - /* If closing tab is current, set current_tab to null to ensure + /* If closing tab is current, set current_container to null to ensure * closed ViewContainer is destroyed. It will be reassigned in tab_changed */ - if (view_container == current_tab) { - current_tab = null; - } + // if (view_container == current_container) { + // current_container = null; + // } view_container.close (); + tab_view.close_page_finish (tab, false); // No need to confirm - if (tabs.n_tabs == 1) { + if (tab_view.n_pages == 1) { add_tab (); } return true; }); - tabs.tab_switched.connect ((old_tab, new_tab) => { - if (new_tab != null) { - change_tab (tabs.get_tab_position (new_tab)); - } + tab_view.page_reordered.connect ((tab, position) => { + change_tab (position); }); - tabs.tab_restored.connect ((label, restore_data, icon) => { - add_tab_by_uri (restore_data); - }); + //TODO Implement in Gtk4 (Signal absent in TabBar) + // tab_view.tab_restored.connect ((label, restore_data, icon) => { + // add_tab_by_uri (restore_data); + // }); - tabs.tab_duplicated.connect ((tab) => { - add_tab_by_uri (((ViewContainer)(tab.page)).uri); - }); + //TODO Implement in Gtk4 (Signal absent in TabBar) + // tab_view.tab_duplicated.connect ((tab) => { + // add_tab_by_uri (((ViewContainer)(tab.child)).uri); + // }); - tabs.tab_moved.connect ((tab) => { - /* Called when tab dragged out of notebook */ - var vc = (ViewContainer)(tab.page) ; - /* Close view now to disconnect signal handler closures which can trigger after slot destruction */ - vc.close (); + //TODO Reimplement in Gtk4 + tab_view.create_window.connect (() => { + // /* Called when tab dragged out of notebook */ + // var vc = (ViewContainer)(tab.page) ; + // /* Close view now to disconnect signal handler closures which can trigger after slot destruction */ + // vc.close (); - marlin_app.create_window (vc.location, real_mode (vc.view_mode)); + // marlin_app.create_window (vc.location, real_mode (vc.view_mode)); - /* remove_tab function uses Idle loop to close tab */ - remove_tab (tab); + // /* remove_tab function uses Idle loop to close tab */ + // remove_tab (tab); + return marlin_app.create_window ().tab_view; }); - - tabs.tab_added.connect ((tab) => { - var vc = (ViewContainer)(tab.page) ; + tab_view.page_attached.connect ((tab, pos) => { + var vc = (ViewContainer)(tab.child) ; vc.window = this; }); - tabs.tab_removed.connect (on_tab_removed); + tab_view.page_detached.connect (on_page_detached); sidebar.request_focus.connect (() => { - return !current_tab.locked_focus && !top_menu.locked_focus; + return !current_container.locked_focus && !top_menu.locked_focus; }); sidebar.sync_needed.connect (() => { - loading_uri (current_tab.uri); + loading_uri (current_container.uri); }); sidebar.path_change_request.connect (uri_path_change_request); sidebar.connect_server_request.connect (connect_to_server); } - private void on_tab_removed () { - if (tabs.n_tabs == 0) { + private void on_page_detached () { + if (tab_view.n_pages == 0) { add_tab (); } @@ -351,10 +375,10 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void change_tab (int offset) { - ViewContainer? old_tab = current_tab; - current_tab = (ViewContainer)((tabs.get_tab_by_index (offset)).page); + ViewContainer? old_tab = current_container; + tab_view.selected_page = tab_view.get_nth_page (offset); - if (current_tab == null || old_tab == current_tab) { + if (current_container == null || old_tab == current_container) { return; } @@ -367,10 +391,10 @@ public class Files.View.Window : Hdy.ApplicationWindow { old_tab.is_frozen = false; } - loading_uri (current_tab.uri); - current_tab.set_active_state (true, false); /* changing tab should not cause animated scrolling */ - sidebar.sync_uri (current_tab.uri); - top_menu.working = current_tab.is_frozen; + loading_uri (current_container.uri); + current_container.set_active_state (true, false); /* changing tab should not cause animated scrolling */ + sidebar.sync_uri (current_container.uri); + top_menu.working = current_container.is_frozen; save_active_tab_position (); } @@ -388,8 +412,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { var location = GLib.File.new_for_path (PF.UserUtils.get_real_user_home ()); add_tab (location, mode); /* Ensure default tab's slot is active so it can be focused */ - current_tab = (ViewContainer)(tabs.current.page); - current_tab.set_active_state (true, false); + current_container.set_active_state (true, false); } } else { /* Open tabs at each requested location */ @@ -427,12 +450,12 @@ public class Files.View.Window : Hdy.ApplicationWindow { bool is_child; var existing_tab_position = location_is_duplicate (location, out is_child); if (existing_tab_position >= 0) { - tabs.current = tabs.get_tab_by_index (existing_tab_position); + tab_view.selected_page = tab_view.get_nth_page (existing_tab_position); change_tab (existing_tab_position); if (is_child) { /* Select the child */ - ((ViewContainer)(tabs.current.page)).focus_location_if_in_current_directory (location); + current_container.focus_location_if_in_current_directory (location); } return; @@ -441,22 +464,29 @@ public class Files.View.Window : Hdy.ApplicationWindow { mode = real_mode (mode); var content = new View.ViewContainer (this); - var tab = new Granite.Widgets.Tab.with_accellabels ( - "", - null, - content, - new Granite.AccelLabel (_("Close Tab"), "w"), - new Granite.AccelLabel (_("Duplicate Tab"), "t"), - new Granite.AccelLabel (_("Open in New Window"), "n") - ) { - ellipsize_mode = Pango.EllipsizeMode.MIDDLE - }; - - change_tab ((int)tabs.insert_tab (tab, -1)); - tabs.current = tab; + // var tab = new Hdy.TabPage () + // .with_accellabels ( + // "", + // null, + // content, + // new Granite.AccelLabel (_("Close Tab"), "w"), + // new Granite.AccelLabel (_("Duplicate Tab"), "t"), + // new Granite.AccelLabel (_("Open in New Window"), "n") + // ) + // { + // child = content + // }; + + // change_tab ((int)tab_view.insert_tab (tab, -1)); + var tab = tab_view.append (content); + tab_view.selected_page = tab; + /* Capturing ViewContainer object reference in closure prevents its proper destruction + * so capture its unique id instead */ + // var id = content.id; content.tab_name_changed.connect ((tab_name) => { - check_for_tabs_with_same_name (); // Also sets tab_label. + check_for_tabs_with_same_name (); + // set_tab_label (check_for_tab_with_same_name (id, tab_name), tab, tab_name); }); content.loading.connect ((is_loading) => { @@ -471,7 +501,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { } } - tab.working = is_loading; + content.working = is_loading; update_top_menu (); if (restoring_tabs == 0 && !is_loading) { save_tabs (); @@ -498,8 +528,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { parent_path = FileUtils.get_parent_path_from_path (location.get_path ()); int existing_position = 0; - foreach (Granite.Widgets.Tab tab in tabs.tabs) { - var tab_location = ((ViewContainer)(tab.page)).location; + for (uint i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); + var tab_location = ((ViewContainer)(tab.child)).location; string tab_uri = tab_location.get_uri (); if (FileUtils.same_location (uri, tab_uri)) { @@ -518,9 +549,11 @@ public class Files.View.Window : Hdy.ApplicationWindow { /** Compare every tab label with every other and resolve ambiguities **/ private void check_for_tabs_with_same_name () { // Take list copy so foreach clauses can be nested safely - var copy_tabs = tabs.tabs.copy (); - foreach (unowned var tab in tabs.tabs) { - var content = (ViewContainer)(tab.page); + // var copy_tabs = tab_view.tabs.copy (); + for (uint i = 0; i < tab_view.n_pages; i++) { + // foreach (unowned var tab in tab_view.tabs) { + var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); + unowned var content = (ViewContainer)(tab.child); if (content.tab_name == Files.INVALID_TAB_NAME) { set_tab_label (content.tab_name, tab, content.tab_name); continue; @@ -543,8 +576,11 @@ public class Files.View.Window : Hdy.ApplicationWindow { set_tab_label (basename, tab, content.tab_name); // Compare with every other tab for same label - foreach (unowned var tab2 in copy_tabs) { - var content2 = (ViewContainer)(tab2.page); + for (uint j = 0; j < tab_view.n_pages; j++) { + var tab2 = (Hdy.TabPage)(tab_view.get_pages ().get_item (j)); + unowned var content2 = (ViewContainer)(tab2.child); + // foreach (unowned var tab2 in copy_tabs) { + // var content2 = (ViewContainer)(tab2.page); if (content2 == content || content2.tab_name == Files.INVALID_TAB_NAME) { continue; } @@ -571,14 +607,14 @@ public class Files.View.Window : Hdy.ApplicationWindow { } /* Just to append "as Administrator" when appropriate */ - private void set_tab_label (string label, Granite.Widgets.Tab tab, string? tooltip = null) { + private void set_tab_label (string label, Hdy.TabPage tab, string? tooltip = null) { string lab = label; if (Files.is_admin ()) { lab += (" " + _("(as Administrator)")); } - tab.label = lab; + tab.title = lab; /* Needs change to Granite to allow (visible) tooltip amendment. * This compiles because tab is a widget but the tootip is overridden by that set internally */ @@ -588,7 +624,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { tt += (" " + _("(as Administrator)")); } - tab.set_tooltip_text (tt); + tab.tooltip = tt; } } @@ -601,14 +637,20 @@ public class Files.View.Window : Hdy.ApplicationWindow { } public void remove_content (ViewContainer view_container) { - remove_tab (tabs.get_tab_by_widget ((Gtk.Widget)view_container)); + for (uint i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); + if (tab.child == view_container) { + remove_tab (tab); + break; + } + } } - private void remove_tab (Granite.Widgets.Tab? tab) { + private void remove_tab (Hdy.TabPage? tab) { if (tab != null) { /* Use Idle in case of rapid closing of multiple tabs during restore */ Idle.add_full (Priority.LOW, () => { - tab.close (); + tab_view.close_page (tab); return GLib.Source.REMOVE; }); } @@ -642,9 +684,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void action_bookmark (GLib.SimpleAction action, GLib.Variant? param) { /* Note: Duplicate bookmarks will not be created by BookmarkList */ - unowned var selected_files = current_tab.view.get_selected_files (); + unowned var selected_files = current_container.view.get_selected_files (); if (selected_files == null) { - sidebar.add_favorite_uri (current_tab.location.get_uri ()); + sidebar.add_favorite_uri (current_container.location.get_uri ()); } else if (selected_files.first ().next == null) { sidebar.add_favorite_uri (selected_files.first ().data.uri); } // Ignore if more than one item selected @@ -652,7 +694,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void action_find (GLib.SimpleAction action, GLib.Variant? param) { /* Do not initiate search while slot is frozen e.g. during loading */ - if (current_tab == null || current_tab.is_frozen) { + if (current_container == null || current_container.is_frozen) { return; } @@ -684,30 +726,30 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void action_reload () { /* avoid spawning reload when key kept pressed */ - if (tabs.current.working) { + if (((ViewContainer)(tab_view.selected_page.child)).working) { warning ("Too rapid reloading suppressed"); return; } - current_tab.reload (); + current_container.reload (); sidebar.reload (); } private void action_view_mode (GLib.SimpleAction action, GLib.Variant? param) { - if (current_tab == null) { // can occur during startup + if (current_container == null) { // can occur during startup return; } ViewMode mode = real_mode ((ViewMode)(param.get_uint32 ())); - current_tab.change_view_mode (mode); + current_container.change_view_mode (mode); /* ViewContainer takes care of changing appearance */ } private void action_back (SimpleAction action, Variant? param) { - current_tab.go_back (param.get_int32 ()); + current_container.go_back (param.get_int32 ()); } private void action_forward (SimpleAction action, Variant? param) { - current_tab.go_forward (param.get_int32 ()); + current_container.go_forward (param.get_int32 ()); } private void action_go_to (GLib.SimpleAction action, GLib.Variant? param) { @@ -737,7 +779,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { break; case "UP": - current_tab.go_up (); + current_container.go_up (); break; default: @@ -746,19 +788,19 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void action_zoom (GLib.SimpleAction action, GLib.Variant? param) { - if (current_tab != null) { - assert (current_tab.view != null); + if (current_container != null) { + assert (current_container.view != null); switch (param.get_string ()) { case "ZOOM_IN": - current_tab.view.zoom_in (); + current_container.view.zoom_in (); break; case "ZOOM_OUT": - current_tab.view.zoom_out (); + current_container.view.zoom_out (); break; case "ZOOM_NORMAL": - current_tab.view.zoom_normal (); + current_container.view.zoom_normal (); break; default: @@ -774,23 +816,23 @@ public class Files.View.Window : Hdy.ApplicationWindow { break; case "CLOSE": - remove_tab (tabs.current); + remove_tab (tab_view.selected_page); break; case "NEXT": - tabs.next_page (); + tab_view.select_next_page (); break; case "PREVIOUS": - tabs.previous_page (); + tab_view.select_previous_page (); break; case "TAB": - add_tab (current_tab.location, current_tab.view_mode); + add_tab (current_container.location, current_container.view_mode); break; case "WINDOW": - tabs.tab_moved (tabs.current, 0, 0); + tab_view.create_window (); break; default: @@ -845,8 +887,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { } public void after_undo_redo () { - if (current_tab.slot.directory.is_recent) { - current_tab.reload (); + if (current_container.slot.directory.is_recent) { + current_container.reload (); } doing_undo_redo = false; @@ -919,7 +961,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { return mode; case ViewMode.CURRENT: - return current_tab.view_mode; + return current_container.view_mode; default: break; @@ -934,11 +976,11 @@ public class Files.View.Window : Hdy.ApplicationWindow { top_menu.destroy (); /* stop unwanted signals if quit while pathbar in focus */ - tabs.tab_removed.disconnect (on_tab_removed); /* Avoid infinite loop */ + tab_view.page_detached.disconnect (on_page_detached); /* Avoid infinite loop */ - foreach (var tab in tabs.tabs) { - current_tab = null; - ((View.ViewContainer)(tab.page)).close (); + for (uint i = 0; i < tab_view.n_pages; i++) { + var tab_page = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); + ((View.ViewContainer)(tab_page.child)).close (); } this.destroy (); @@ -984,9 +1026,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { } VariantBuilder vb = new VariantBuilder (new VariantType ("a(uss)")); - foreach (var tab in tabs.tabs) { - assert (tab != null); - var view_container = (ViewContainer)(tab.page) ; + for (uint i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); + var view_container = (ViewContainer)(tab.child) ; /* Do not save if "File does not exist" or "Does not belong to you" */ if (!view_container.can_show_folder) { @@ -1005,9 +1047,10 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void save_active_tab_position () { - if (tabs.current != null) { - Files.app_settings.set_int ("active-tab-position", tabs.get_tab_position (tabs.current)); - } + Files.app_settings.set_int ( + "active-tab-position", + tab_view.get_page_position (tab_view.selected_page) + ); } public uint restore_tabs () { @@ -1070,15 +1113,14 @@ public class Files.View.Window : Hdy.ApplicationWindow { active_tab_position = 0; } - tabs.current = tabs.get_tab_by_index (active_tab_position); - current_tab = (ViewContainer?)(tabs.current.page); + tab_view.selected_page = tab_view.get_nth_page (active_tab_position); string path = ""; - if (current_tab != null) { - path = current_tab.get_tip_uri (); + if (current_container != null) { + path = current_container.get_tip_uri (); if (path == null || path == "") { - path = current_tab.get_root_uri (); + path = current_container.get_root_uri (); } } @@ -1089,8 +1131,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void expand_miller_view (string tip_uri, string unescaped_root_uri) { /* It might be more elegant for Miller.vala to handle this */ - var tab = tabs.current; - var view = (ViewContainer)(tab.page) ; + var tab = tab_view.selected_page; + var view = (ViewContainer)(tab.child); var mwcols = (Miller)(view.view) ; var unescaped_tip_uri = FileUtils.sanitize_path (tip_uri); @@ -1120,28 +1162,28 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void update_top_menu () { - if (restoring_tabs > 0 || current_tab == null) { + if (restoring_tabs > 0 || current_container == null) { return; } /* Update browser buttons */ - top_menu.set_back_menu (current_tab.get_go_back_path_list ()); - top_menu.set_forward_menu (current_tab.get_go_forward_path_list ()); - top_menu.can_go_back = current_tab.can_go_back; - top_menu.can_go_forward = (current_tab.can_show_folder && current_tab.can_go_forward); - top_menu.working = current_tab.is_loading; + top_menu.set_back_menu (current_container.get_go_back_path_list ()); + top_menu.set_forward_menu (current_container.get_go_forward_path_list ()); + top_menu.can_go_back = current_container.can_go_back; + top_menu.can_go_forward = (current_container.can_show_folder && current_container.can_go_forward); + top_menu.working = current_container.is_loading; /* Update viewmode switch, action state and settings */ - var mode = current_tab.view_mode; + var mode = current_container.view_mode; view_switcher.set_mode (mode); - view_switcher.sensitive = current_tab.can_show_folder; + view_switcher.sensitive = current_container.can_show_folder; get_action ("view-mode").change_state (new Variant.uint32 (mode)); Files.app_settings.set_enum ("default-viewmode", mode); } private void update_labels (string uri) { - if (current_tab != null) { /* Can happen during restore */ - set_title (current_tab.tab_name); /* Not actually visible on elementaryos */ + if (current_container != null) { /* Can happen during restore */ + set_title (current_container.tab_name); /* Not actually visible on elementaryos */ top_menu.update_location_bar (uri); sidebar.sync_uri (uri); } @@ -1151,12 +1193,13 @@ public class Files.View.Window : Hdy.ApplicationWindow { debug ("Mount %s removed", mount.get_name ()); GLib.File root = mount.get_root (); - foreach (var page in tabs.get_children ()) { - var view_container = (View.ViewContainer)page ; + for (uint i = 0; i < tab_view.get_pages ().get_n_items (); i++) { + // foreach (var page in tab_view.get_children ()) { + var view_container = (View.ViewContainer)(tab_view.get_pages ().get_item (i)) ; GLib.File location = view_container.location; if (location == null || location.has_prefix (root) || location.equal (root)) { - if (view_container == current_tab) { + if (view_container == current_container) { view_container.focus_location (GLib.File.new_for_path (PF.UserUtils.get_real_user_home ())); } else { remove_content (view_container); @@ -1171,14 +1214,14 @@ public class Files.View.Window : Hdy.ApplicationWindow { if (file != null) { switch (flag) { case Files.OpenFlag.NEW_TAB: - add_tab (file, current_tab.view_mode); + add_tab (file, current_container.view_mode); break; case Files.OpenFlag.NEW_WINDOW: - add_window (file, current_tab.view_mode); + add_window (file, current_container.view_mode); break; default: grab_focus (); - current_tab.focus_location (file); + current_container.focus_location (file); break; } } else { @@ -1189,8 +1232,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { /** Use this function to standardise how locations are generated from uris **/ private GLib.File? get_file_from_uri (string uri) { string? current_uri = null; - if (current_tab != null && current_tab.location != null) { - current_uri = current_tab.location.get_uri (); + if (current_container != null && current_container.location != null) { + current_uri = current_container.location.get_uri (); } string path = FileUtils.sanitize_path (uri, current_uri); @@ -1202,6 +1245,6 @@ public class Files.View.Window : Hdy.ApplicationWindow { } public new void grab_focus () { - current_tab.grab_focus (); + current_container.grab_focus (); } } From e69ce0afb17972da37bac15782210bbafb85f0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 12 Jul 2023 16:17:34 -0700 Subject: [PATCH 02/23] New tab button --- src/View/Window.vala | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index e10d8f13e1..58bbbdd6b2 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -176,9 +176,21 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view = new Hdy.TabView (); + var app_instance = (Gtk.Application)(GLib.Application.get_default ()); + + var new_tab_button = new Gtk.Button.from_icon_name ("list-add-symbolic") { + action_name = "win.tab", + action_target = new Variant.string ("NEW") + }; + new_tab_button.tooltip_markup = Granite.markup_accel_tooltip ( + app_instance.get_accels_for_action ("win.tab::NEW"), + _("New Tab") + ); + tab_bar = new Hdy.TabBar () { autohide = false, expand_tabs = false, + start_action_widget = new_tab_button, view = tab_view }; @@ -186,23 +198,6 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_box.add (tab_bar); tab_box.add (tab_view); - // tabs = new Granite.Widgets.DynamicNotebook.with_accellabels ( - // new Granite.AccelLabel (_("New Tab"), "t"), - // new Granite.AccelLabel (_("Undo Close Tab"), "t") - // ) { - // show_tabs = true, - // allow_restoring = true, - // allow_duplication = true, - // allow_new_window = true, - // group_name = Config.APP_NAME - // }; - - // TODO Reimplement if needed - // this.configure_event.connect_after ((e) => { - // tabs.set_size_request (e.width / 2, -1); - // return false; - // }); - sidebar = new Sidebar.SidebarWindow (); free_space_change.connect (sidebar.on_free_space_change); From 8fa41f4d7ebd96d57f3c1193dc3b7c0e0a09ee8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 12 Jul 2023 16:28:02 -0700 Subject: [PATCH 03/23] Fix tab closing --- src/View/Window.vala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 58bbbdd6b2..9b3e11203f 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -289,8 +289,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.indicator_activated.connect (() => {}); tab_view.setup_menu.connect (() => {}); - tab_view.close_page.connect ((tab) => { - var view_container = (ViewContainer)(tab.child); + tab_view.close_page.connect ((page) => { + var view_container = (ViewContainer)(page.child); // tab.restore_data = view_container.location.get_uri (); /* If closing tab is current, set current_container to null to ensure @@ -301,13 +301,13 @@ public class Files.View.Window : Hdy.ApplicationWindow { // } view_container.close (); - tab_view.close_page_finish (tab, false); // No need to confirm + tab_view.close_page_finish (page, true); - if (tab_view.n_pages == 1) { + if (tab_view.n_pages == 0) { add_tab (); } - return true; + return Gdk.EVENT_STOP; }); tab_view.page_reordered.connect ((tab, position) => { From a3619fc14cae3e0169471ff91d0b16440d4bea18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 12 Jul 2023 16:34:38 -0700 Subject: [PATCH 04/23] Create tab menu --- src/View/Window.vala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 9b3e11203f..b1a3777e3a 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -174,7 +174,16 @@ public class Files.View.Window : Hdy.ApplicationWindow { custom_title = new Gtk.Label (null) }; - tab_view = new Hdy.TabView (); + var tab_menumodel = new Menu (); + tab_menumodel.append (_("Close Other Tabs"), null); + tab_menumodel.append (_("Close Tabs to the Right"), null); + tab_menumodel.append (_("Close Tab"), "win.tab::CLOSE"); + tab_menumodel.append (_("Open in New Window"), "win.tab::WINDOW"); + tab_menumodel.append (_("Duplicate Tab"), "win.tab::TAB"); + + tab_view = new Hdy.TabView () { + menu_model = tab_menumodel + }; var app_instance = (Gtk.Application)(GLib.Application.get_default ()); From 5acb41249f5c4885902b70de4e33add0d6425016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 12 Jul 2023 16:41:27 -0700 Subject: [PATCH 05/23] use sections --- src/View/Window.vala | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index b1a3777e3a..1df1a34f88 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -174,15 +174,21 @@ public class Files.View.Window : Hdy.ApplicationWindow { custom_title = new Gtk.Label (null) }; - var tab_menumodel = new Menu (); - tab_menumodel.append (_("Close Other Tabs"), null); - tab_menumodel.append (_("Close Tabs to the Right"), null); - tab_menumodel.append (_("Close Tab"), "win.tab::CLOSE"); - tab_menumodel.append (_("Open in New Window"), "win.tab::WINDOW"); - tab_menumodel.append (_("Duplicate Tab"), "win.tab::TAB"); + var close_tab_section = new Menu (); + close_tab_section.append (_("Close Other Tabs"), null); + close_tab_section.append (_("Close Tabs to the Right"), null); + close_tab_section.append (_("Close Tab"), "win.tab::CLOSE"); + + var open_tab_section = new Menu (); + open_tab_section.append (_("Open in New Window"), "win.tab::WINDOW"); + open_tab_section.append (_("Duplicate Tab"), "win.tab::TAB"); + + var tab_menu = new Menu (); + tab_menu.append_section (null, close_tab_section); + tab_menu.append_section (null, open_tab_section); tab_view = new Hdy.TabView () { - menu_model = tab_menumodel + menu_model = tab_menu }; var app_instance = (Gtk.Application)(GLib.Application.get_default ()); From 4a02eb9a4e3511f35dd689597552d3a7ae43c4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Jul 2023 09:35:42 -0700 Subject: [PATCH 06/23] close button on left --- src/View/Window.vala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/View/Window.vala b/src/View/Window.vala index 1df1a34f88..d7124bb9b3 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -205,6 +205,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_bar = new Hdy.TabBar () { autohide = false, expand_tabs = false, + inverted = true, start_action_widget = new_tab_button, view = tab_view }; From 51471ca3600dd0dbb59984f1b629a641b193328a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 13:10:25 -0700 Subject: [PATCH 07/23] suppress warning --- src/View/Window.vala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 06257b6272..92990f6962 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -55,8 +55,11 @@ public class Files.View.Window : Hdy.ApplicationWindow { public ViewContainer? current_container { get { - return tab_view.selected_page != null ? - (ViewContainer)(tab_view.selected_page.child) : null; + if (tab_view.selected_page != null) { + return (ViewContainer) tab_view.selected_page.child; + } + + return null; } } @@ -793,7 +796,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void action_reload () { /* avoid spawning reload when key kept pressed */ - if (((ViewContainer)(tab_view.selected_page.child)).working) { + if (current_container.working) { warning ("Too rapid reloading suppressed"); return; } @@ -802,7 +805,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void action_view_mode (GLib.SimpleAction action, GLib.Variant? param) { - if (current_container == null) { // can occur during startup + if (tab_view == null || current_container == null) { // can occur during startup return; } From b7a6e978d1abb415e234f3bf264178004929dca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 13:10:49 -0700 Subject: [PATCH 08/23] private current container --- src/View/Window.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 92990f6962..1287eb8413 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -53,7 +53,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { } } - public ViewContainer? current_container { + private ViewContainer? current_container { get { if (tab_view.selected_page != null) { return (ViewContainer) tab_view.selected_page.child; From 4e674ade9c633439f7196a555a63524dff579d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 13:19:05 -0700 Subject: [PATCH 09/23] Set up tab menu on open --- src/View/Window.vala | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 1287eb8413..ca60ba77ef 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -207,21 +207,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { headerbar.pack_start (location_bar); headerbar.pack_end (menu_button); - var close_tab_section = new Menu (); - close_tab_section.append (_("Close Other Tabs"), null); - close_tab_section.append (_("Close Tabs to the Right"), null); - close_tab_section.append (_("Close Tab"), "win.tab::CLOSE"); - - var open_tab_section = new Menu (); - open_tab_section.append (_("Open in New Window"), "win.tab::WINDOW"); - open_tab_section.append (_("Duplicate Tab"), "win.tab::TAB"); - - var tab_menu = new Menu (); - tab_menu.append_section (null, close_tab_section); - tab_menu.append_section (null, open_tab_section); - tab_view = new Hdy.TabView () { - menu_model = tab_menu + menu_model = new Menu () }; var app_instance = (Gtk.Application)(GLib.Application.get_default ()); @@ -355,13 +342,10 @@ public class Files.View.Window : Hdy.ApplicationWindow { return false; }); - // tabs.new_tab_requested.connect (() => { - // add_tab (); - // }); - //TODO Implement handlers for new signals tab_view.indicator_activated.connect (() => {}); - tab_view.setup_menu.connect (() => {}); + + tab_view.setup_menu.connect (tab_view_setup_menu); tab_view.close_page.connect ((page) => { var view_container = (ViewContainer)(page.child); @@ -431,6 +415,28 @@ public class Files.View.Window : Hdy.ApplicationWindow { sidebar.connect_server_request.connect (connect_to_server); } + private void tab_view_setup_menu (Hdy.TabPage? page) { + if (page == null) { + return; + } + + var tab_menu = (Menu) tab_view.menu_model; + tab_menu.remove_all (); + + // TODO: Set up actions for this page specifically + var close_tab_section = new Menu (); + close_tab_section.append (_("Close Other Tabs"), null); + close_tab_section.append (_("Close Tabs to the Right"), null); + close_tab_section.append (_("Close Tab"), "win.tab::CLOSE"); + + var open_tab_section = new Menu (); + open_tab_section.append (_("Open in New Window"), "win.tab::WINDOW"); + open_tab_section.append (_("Duplicate Tab"), "win.tab::TAB"); + + tab_menu.append_section (null, close_tab_section); + tab_menu.append_section (null, open_tab_section); + } + private void on_page_detached () { if (tab_view.n_pages == 0) { add_tab (); From a2881461756f691eee129a1ebcf4c54d79b3f468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 13:55:31 -0700 Subject: [PATCH 10/23] Fix menu per tag --- src/View/Window.vala | 67 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index ca60ba77ef..dc9e6fcd3a 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -420,21 +420,76 @@ public class Files.View.Window : Hdy.ApplicationWindow { return; } + var action_close = new SimpleAction ("tabmenu-close", null); + var action_close_end = new SimpleAction ("tabmenu-close-end", null); + var action_close_others = new SimpleAction ("tabmenu-close-others", null); + var action_duplicate = new SimpleAction ("tabmenu-duplicate", null); + var action_new_window = new SimpleAction ("tabmenu-new-window", null); + + add_action (action_close); + add_action (action_close_end); + add_action (action_close_others); + add_action (action_duplicate); + add_action (action_new_window); + + marlin_app.set_accels_for_action ("win.tabmenu-close", {"W"}); + marlin_app.set_accels_for_action ("win.tabmenu-duplicate", {"T"}); + marlin_app.set_accels_for_action ("win.tabmenu-new-window", {"N"}); + var tab_menu = (Menu) tab_view.menu_model; tab_menu.remove_all (); - // TODO: Set up actions for this page specifically var close_tab_section = new Menu (); - close_tab_section.append (_("Close Other Tabs"), null); - close_tab_section.append (_("Close Tabs to the Right"), null); - close_tab_section.append (_("Close Tab"), "win.tab::CLOSE"); + close_tab_section.append (_("Close Other Tabs"), "win.tabmenu-close-others"); + /// TRANSLATORS: For RTL this should be "to the left" + close_tab_section.append (_("Close Tabs to the Right"), "win.tabmenu-close-end"); + close_tab_section.append (_("Close Tab"), "win.tabmenu-close"); var open_tab_section = new Menu (); - open_tab_section.append (_("Open in New Window"), "win.tab::WINDOW"); - open_tab_section.append (_("Duplicate Tab"), "win.tab::TAB"); + open_tab_section.append (_("Open in New Window"), "win.tabmenu-new-window"); + open_tab_section.append (_("Duplicate Tab"), "win.tabmenu-duplicate"); tab_menu.append_section (null, close_tab_section); tab_menu.append_section (null, open_tab_section); + + action_close.activate.connect (() => { + remove_tab (page); + }); + + var tab_position = tab_view.get_page_position (page) + 1; + if (tab_position == tab_view.n_pages) { + action_close_end.set_enabled (false); + } else { + action_close_end.activate.connect (() => { + for (var i = tab_position; i < tab_view.n_pages; i++) { + remove_tab (tab_view.get_nth_page (i)); + } + }); + } + + if (tab_view.n_pages == 1) { + action_close_others.set_enabled (false); + } else { + action_close_others.activate.connect (() => { + for (var i = 0; i < tab_view.n_pages; i++) { + if (tab_view.get_nth_page (i) == page) { + continue; + } + + remove_tab (tab_view.get_nth_page (i)); + } + }); + } + + action_duplicate.activate.connect (() => { + var view_container = (ViewContainer) page.child; + add_tab (view_container.location, view_container.view_mode); + }); + + action_new_window.activate.connect (() => { + var view_container = (ViewContainer) page.child; + add_window (view_container.location, view_container.view_mode); + }); } private void on_page_detached () { From 8360501b90fbae68843d86aa581d5c57fe86528e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 14:06:12 -0700 Subject: [PATCH 11/23] Reorder tabs to match Ephy --- src/View/Window.vala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index dc9e6fcd3a..e2c4ed8de1 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -439,18 +439,18 @@ public class Files.View.Window : Hdy.ApplicationWindow { var tab_menu = (Menu) tab_view.menu_model; tab_menu.remove_all (); + var open_tab_section = new Menu (); + open_tab_section.append (_("Open in New Window"), "win.tabmenu-new-window"); + open_tab_section.append (_("Duplicate Tab"), "win.tabmenu-duplicate"); + var close_tab_section = new Menu (); + close_tab_section.append (_("Close Tabs to the Right"), "win.tabmenu-close-end"); close_tab_section.append (_("Close Other Tabs"), "win.tabmenu-close-others"); /// TRANSLATORS: For RTL this should be "to the left" - close_tab_section.append (_("Close Tabs to the Right"), "win.tabmenu-close-end"); close_tab_section.append (_("Close Tab"), "win.tabmenu-close"); - var open_tab_section = new Menu (); - open_tab_section.append (_("Open in New Window"), "win.tabmenu-new-window"); - open_tab_section.append (_("Duplicate Tab"), "win.tabmenu-duplicate"); - - tab_menu.append_section (null, close_tab_section); tab_menu.append_section (null, open_tab_section); + tab_menu.append_section (null, close_tab_section); action_close.activate.connect (() => { remove_tab (page); From 34bb4113625f30b1737cd75e545269a287aeefa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 14:39:46 -0700 Subject: [PATCH 12/23] Hook up is loading, fix some other stuff --- src/View/ViewContainer.vala | 1 - src/View/Window.vala | 68 ++++++------------------------------- 2 files changed, 10 insertions(+), 59 deletions(-) diff --git a/src/View/ViewContainer.vala b/src/View/ViewContainer.vala index 97d92eeab7..360175acbf 100644 --- a/src/View/ViewContainer.vala +++ b/src/View/ViewContainer.vala @@ -28,7 +28,6 @@ namespace Files.View { public Gtk.Widget? content_item; public bool can_show_folder { get; private set; default = false; } private View.Window? _window = null; - public bool working { get; set; } public View.Window window { get { return _window; diff --git a/src/View/Window.vala b/src/View/Window.vala index e2c4ed8de1..858525c033 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -342,22 +342,12 @@ public class Files.View.Window : Hdy.ApplicationWindow { return false; }); - //TODO Implement handlers for new signals - tab_view.indicator_activated.connect (() => {}); - tab_view.setup_menu.connect (tab_view_setup_menu); tab_view.close_page.connect ((page) => { - var view_container = (ViewContainer)(page.child); + var view_container = (ViewContainer) page.child; // tab.restore_data = view_container.location.get_uri (); - /* If closing tab is current, set current_container to null to ensure - * closed ViewContainer is destroyed. It will be reassigned in tab_changed - */ - // if (view_container == current_container) { - // current_container = null; - // } - view_container.close (); tab_view.close_page_finish (page, true); @@ -368,31 +358,11 @@ public class Files.View.Window : Hdy.ApplicationWindow { return Gdk.EVENT_STOP; }); - tab_view.page_reordered.connect ((tab, position) => { - change_tab (position); + tab_view.notify["selected-page"].connect (() => { + change_tab (tab_view.selected_page); }); - //TODO Implement in Gtk4 (Signal absent in TabBar) - // tab_view.tab_restored.connect ((label, restore_data, icon) => { - // add_tab_by_uri (restore_data); - // }); - - //TODO Implement in Gtk4 (Signal absent in TabBar) - // tab_view.tab_duplicated.connect ((tab) => { - // add_tab_by_uri (((ViewContainer)(tab.child)).uri); - // }); - - //TODO Reimplement in Gtk4 tab_view.create_window.connect (() => { - // /* Called when tab dragged out of notebook */ - // var vc = (ViewContainer)(tab.page) ; - // /* Close view now to disconnect signal handler closures which can trigger after slot destruction */ - // vc.close (); - - // marlin_app.create_window (vc.location, real_mode (vc.view_mode)); - - // /* remove_tab function uses Idle loop to close tab */ - // remove_tab (tab); return marlin_app.create_window ().tab_view; }); @@ -504,9 +474,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { this.title = title; } - private void change_tab (int offset) { + private void change_tab (Hdy.TabPage page) { ViewContainer? old_tab = current_container; - tab_view.selected_page = tab_view.get_nth_page (offset); + tab_view.selected_page = page; if (current_container == null || old_tab == current_container) { return; @@ -581,7 +551,6 @@ public class Files.View.Window : Hdy.ApplicationWindow { var existing_tab_position = location_is_duplicate (location, out is_child); if (existing_tab_position >= 0) { tab_view.selected_page = tab_view.get_nth_page (existing_tab_position); - change_tab (existing_tab_position); if (is_child) { /* Select the child */ @@ -594,29 +563,12 @@ public class Files.View.Window : Hdy.ApplicationWindow { mode = real_mode (mode); var content = new View.ViewContainer (this); - // var tab = new Hdy.TabPage () - // .with_accellabels ( - // "", - // null, - // content, - // new Granite.AccelLabel (_("Close Tab"), "w"), - // new Granite.AccelLabel (_("Duplicate Tab"), "t"), - // new Granite.AccelLabel (_("Open in New Window"), "n") - // ) - // { - // child = content - // }; - - // change_tab ((int)tab_view.insert_tab (tab, -1)); - var tab = tab_view.append (content); - tab_view.selected_page = tab; - /* Capturing ViewContainer object reference in closure prevents its proper destruction - * so capture its unique id instead */ - // var id = content.id; + + var page = tab_view.append (content); + tab_view.selected_page = page; content.tab_name_changed.connect ((tab_name) => { check_for_tabs_with_same_name (); - // set_tab_label (check_for_tab_with_same_name (id, tab_name), tab, tab_name); }); content.loading.connect ((is_loading) => { @@ -631,7 +583,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { } } - content.working = is_loading; + page.loading = is_loading; update_headerbar (); if (restoring_tabs == 0 && !is_loading) { @@ -857,7 +809,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { private void action_reload () { /* avoid spawning reload when key kept pressed */ - if (current_container.working) { + if (tab_view.selected_page.loading) { warning ("Too rapid reloading suppressed"); return; } From 7299ef4dd1b5306fc0d0dd1dbc23e8d863a60fa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 14:56:38 -0700 Subject: [PATCH 13/23] Set selected page last to fix nav issues --- src/View/Window.vala | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 858525c033..33b772742b 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -475,22 +475,10 @@ public class Files.View.Window : Hdy.ApplicationWindow { } private void change_tab (Hdy.TabPage page) { - ViewContainer? old_tab = current_container; - tab_view.selected_page = page; - - if (current_container == null || old_tab == current_container) { - return; - } - if (restoring_tabs > 0) { //Return if some restored tabs still loading return; } - if (old_tab != null) { - old_tab.set_active_state (false); - old_tab.is_frozen = false; - } - loading_uri (current_container.uri); current_container.set_active_state (true, false); /* changing tab should not cause animated scrolling */ sidebar.sync_uri (current_container.uri); @@ -565,7 +553,6 @@ public class Files.View.Window : Hdy.ApplicationWindow { var content = new View.ViewContainer (this); var page = tab_view.append (content); - tab_view.selected_page = page; content.tab_name_changed.connect ((tab_name) => { check_for_tabs_with_same_name (); @@ -600,6 +587,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { } else { content.add_view (mode, location); } + + tab_view.selected_page = page; } private int location_is_duplicate (GLib.File location, out bool is_child) { @@ -1312,8 +1301,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { debug ("Mount %s removed", mount.get_name ()); GLib.File root = mount.get_root (); - for (uint i = 0; i < tab_view.get_pages ().get_n_items (); i++) { - // foreach (var page in tab_view.get_children ()) { + for (uint i = 0; i < tab_view.n_pages; i++) { var view_container = (View.ViewContainer)(tab_view.get_pages ().get_item (i)) ; GLib.File location = view_container.location; From f27c5b451ea6a149ae95ae5fcc90fca86a0aedbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 15:06:24 -0700 Subject: [PATCH 14/23] Simplify some stuff --- src/View/Window.vala | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 33b772742b..b1a9623f47 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -367,8 +367,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { }); tab_view.page_attached.connect ((tab, pos) => { - var vc = (ViewContainer)(tab.child) ; - vc.window = this; + var view_container = (ViewContainer) tab.child; + view_container.window = this; }); tab_view.page_detached.connect (on_page_detached); @@ -620,10 +620,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { /** Compare every tab label with every other and resolve ambiguities **/ private void check_for_tabs_with_same_name () { - // Take list copy so foreach clauses can be nested safely - // var copy_tabs = tab_view.tabs.copy (); for (uint i = 0; i < tab_view.n_pages; i++) { - // foreach (unowned var tab in tab_view.tabs) { var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); unowned var content = (ViewContainer)(tab.child); if (content.tab_name == Files.INVALID_TAB_NAME) { @@ -651,8 +648,6 @@ public class Files.View.Window : Hdy.ApplicationWindow { for (uint j = 0; j < tab_view.n_pages; j++) { var tab2 = (Hdy.TabPage)(tab_view.get_pages ().get_item (j)); unowned var content2 = (ViewContainer)(tab2.child); - // foreach (unowned var tab2 in copy_tabs) { - // var content2 = (ViewContainer)(tab2.page); if (content2 == content || content2.tab_name == Files.INVALID_TAB_NAME) { continue; } @@ -709,12 +704,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { } public void remove_content (ViewContainer view_container) { - for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); - if (tab.child == view_container) { - remove_tab (tab); - break; - } + if (view_container.parent != null && view_container.parent is Hdy.TabPage) { + remove_tab ((Hdy.TabPage) view_container.parent); } } From 87105ad54742ee734582093e2eeb29af089cec24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 15:19:18 -0700 Subject: [PATCH 15/23] Store a list of closed tabs --- src/View/Window.vala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index b1a9623f47..3dcbda68a9 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -222,11 +222,21 @@ public class Files.View.Window : Hdy.ApplicationWindow { _("New Tab") ); + var tab_history_menu = new Menu (); + + var tab_history_button = new Gtk.MenuButton () { + image = new Gtk.Image.from_icon_name ("document-open-recent-symbolic", MENU), + menu_model = tab_history_menu, + tooltip_text = _("Closed Tabs"), + use_popover = false + }; + tab_bar = new Hdy.TabBar () { autohide = false, expand_tabs = false, inverted = true, start_action_widget = new_tab_button, + end_action_widget = tab_history_button, view = tab_view }; @@ -346,7 +356,12 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.close_page.connect ((page) => { var view_container = (ViewContainer) page.child; - // tab.restore_data = view_container.location.get_uri (); + + var path = view_container.location.get_uri (); + tab_history_menu.append ( + FileUtils.sanitize_path (path, null, false), + null + ); view_container.close (); tab_view.close_page_finish (page, true); From d4ad285fb15ce7a4c330718d53f3aaa142fb9f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 15:23:03 -0700 Subject: [PATCH 16/23] Fix button sensitivity --- src/View/Window.vala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 3dcbda68a9..d30c9dc03f 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -222,11 +222,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { _("New Tab") ); - var tab_history_menu = new Menu (); - var tab_history_button = new Gtk.MenuButton () { image = new Gtk.Image.from_icon_name ("document-open-recent-symbolic", MENU), - menu_model = tab_history_menu, tooltip_text = _("Closed Tabs"), use_popover = false }; @@ -357,8 +354,12 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.close_page.connect ((page) => { var view_container = (ViewContainer) page.child; + if (tab_history_button.menu_model == null) { + tab_history_button.menu_model = new Menu (); + } + var path = view_container.location.get_uri (); - tab_history_menu.append ( + ((Menu) tab_history_button.menu_model).append ( FileUtils.sanitize_path (path, null, false), null ); From c1b80a6b0c242f0d0525a0fbd7d7bde854b0f2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 17:00:17 -0700 Subject: [PATCH 17/23] prototype restore --- src/View/Window.vala | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index d30c9dc03f..68ca29dbf4 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -351,6 +351,25 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.setup_menu.connect (tab_view_setup_menu); + var action_restore = new SimpleAction ("tabhistory-restore", VariantType.STRING); + add_action (action_restore); + + action_restore.activate.connect ((parameter) => { + add_tab_by_uri (parameter.get_string ()); + + var menu = (Menu) tab_history_button.menu_model; + for (var i = 0; i < menu.get_n_items (); i++) { + if (parameter == menu.get_item_attribute_value (i, Menu.ATTRIBUTE_TARGET, VariantType.STRING)) { + menu.remove (i); + break; + } + } + + if (menu.get_n_items () == 0) { + tab_history_button.menu_model = null; + } + }); + tab_view.close_page.connect ((page) => { var view_container = (ViewContainer) page.child; @@ -361,7 +380,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { var path = view_container.location.get_uri (); ((Menu) tab_history_button.menu_model).append ( FileUtils.sanitize_path (path, null, false), - null + "win.tabhistory-restore::%s".printf (path) ); view_container.close (); From b7cbd55e3db5cde8b02926daed915245cbc57ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sun, 16 Jul 2023 17:10:57 -0700 Subject: [PATCH 18/23] Clean up tab history --- src/View/Window.vala | 96 +++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 68ca29dbf4..e79eb8c509 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -40,6 +40,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { {"singleclick-select", null, null, "false", change_state_single_click_select}, {"show-remote-thumbnails", null, null, "true", change_state_show_remote_thumbnails}, {"show-local-thumbnails", null, null, "false", change_state_show_local_thumbnails}, + {"tabhistory-restore", action_tabhistory_restore, "s" }, {"folders-before-files", null, null, "true", change_state_folders_before_files}, {"forward", action_forward, "i"}, {"back", action_back, "i"} @@ -75,6 +76,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { private Chrome.ButtonWithMenu button_forward; private Chrome.ButtonWithMenu button_back; private Chrome.LocationBar? location_bar; + private Gtk.MenuButton tab_history_button; private bool locked_focus { get; set; default = false; } private bool tabs_restored = false; @@ -222,7 +224,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { _("New Tab") ); - var tab_history_button = new Gtk.MenuButton () { + tab_history_button = new Gtk.MenuButton () { image = new Gtk.Image.from_icon_name ("document-open-recent-symbolic", MENU), tooltip_text = _("Closed Tabs"), use_popover = false @@ -351,47 +353,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.setup_menu.connect (tab_view_setup_menu); - var action_restore = new SimpleAction ("tabhistory-restore", VariantType.STRING); - add_action (action_restore); - - action_restore.activate.connect ((parameter) => { - add_tab_by_uri (parameter.get_string ()); - - var menu = (Menu) tab_history_button.menu_model; - for (var i = 0; i < menu.get_n_items (); i++) { - if (parameter == menu.get_item_attribute_value (i, Menu.ATTRIBUTE_TARGET, VariantType.STRING)) { - menu.remove (i); - break; - } - } - - if (menu.get_n_items () == 0) { - tab_history_button.menu_model = null; - } - }); - - tab_view.close_page.connect ((page) => { - var view_container = (ViewContainer) page.child; - - if (tab_history_button.menu_model == null) { - tab_history_button.menu_model = new Menu (); - } - - var path = view_container.location.get_uri (); - ((Menu) tab_history_button.menu_model).append ( - FileUtils.sanitize_path (path, null, false), - "win.tabhistory-restore::%s".printf (path) - ); - - view_container.close (); - tab_view.close_page_finish (page, true); - - if (tab_view.n_pages == 0) { - add_tab (); - } - - return Gdk.EVENT_STOP; - }); + tab_view.close_page.connect (tab_view_close_page); tab_view.notify["selected-page"].connect (() => { change_tab (tab_view.selected_page); @@ -420,6 +382,40 @@ public class Files.View.Window : Hdy.ApplicationWindow { sidebar.connect_server_request.connect (connect_to_server); } + private bool tab_view_close_page (Hdy.TabPage page) { + var view_container = (ViewContainer) page.child; + + if (tab_history_button.menu_model == null) { + tab_history_button.menu_model = new Menu (); + } + + var path = view_container.location.get_uri (); + var path_in_menu = false; + var menu = (Menu) tab_history_button.menu_model; + for (var i = 0; i < menu.get_n_items (); i++) { + if (path == menu.get_item_attribute_value (i, Menu.ATTRIBUTE_TARGET, VariantType.STRING).get_string ()) { + path_in_menu = true; + break; + } + } + + if (!path_in_menu) { + menu.append ( + FileUtils.sanitize_path (path, null, false), + "win.tabhistory-restore::%s".printf (path) + ); + } + + view_container.close (); + tab_view.close_page_finish (page, true); + + if (tab_view.n_pages == 0) { + add_tab (); + } + + return Gdk.EVENT_STOP; + } + private void tab_view_setup_menu (Hdy.TabPage? page) { if (page == null) { return; @@ -832,6 +828,22 @@ public class Files.View.Window : Hdy.ApplicationWindow { sidebar.reload (); } + private void action_tabhistory_restore (SimpleAction action, GLib.Variant? parameter) { + add_tab_by_uri (parameter.get_string ()); + + var menu = (Menu) tab_history_button.menu_model; + for (var i = 0; i < menu.get_n_items (); i++) { + if (parameter == menu.get_item_attribute_value (i, Menu.ATTRIBUTE_TARGET, VariantType.STRING)) { + menu.remove (i); + break; + } + } + + if (menu.get_n_items () == 0) { + tab_history_button.menu_model = null; + } + } + private void action_view_mode (GLib.SimpleAction action, GLib.Variant? param) { if (tab_view == null || current_container == null) { // can occur during startup return; From 391c36d872f6bf8977f172a3d49624538756893d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 17 Jul 2023 07:31:18 -0700 Subject: [PATCH 19/23] Fix translator comment --- src/View/Window.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index e79eb8c509..fb71fe3941 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -445,9 +445,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { open_tab_section.append (_("Duplicate Tab"), "win.tabmenu-duplicate"); var close_tab_section = new Menu (); + /// TRANSLATORS: For RTL this should be "to the left" close_tab_section.append (_("Close Tabs to the Right"), "win.tabmenu-close-end"); close_tab_section.append (_("Close Other Tabs"), "win.tabmenu-close-others"); - /// TRANSLATORS: For RTL this should be "to the left" close_tab_section.append (_("Close Tab"), "win.tabmenu-close"); tab_menu.append_section (null, open_tab_section); From bac787c4889cda1fce2ff26a1f255a34c2927a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 17 Jul 2023 07:39:38 -0700 Subject: [PATCH 20/23] Extra parantheses in casts --- src/View/Window.vala | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index fb71fe3941..b8a988709b 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -632,8 +632,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { int existing_position = 0; for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); - var tab_location = ((ViewContainer)(tab.child)).location; + var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + var tab_location = ((ViewContainer) tab.child).location; string tab_uri = tab_location.get_uri (); if (FileUtils.same_location (uri, tab_uri)) { @@ -652,8 +652,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { /** Compare every tab label with every other and resolve ambiguities **/ private void check_for_tabs_with_same_name () { for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); - unowned var content = (ViewContainer)(tab.child); + var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + unowned var content = (ViewContainer) tab.child; if (content.tab_name == Files.INVALID_TAB_NAME) { set_tab_label (content.tab_name, tab, content.tab_name); continue; @@ -677,8 +677,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { // Compare with every other tab for same label for (uint j = 0; j < tab_view.n_pages; j++) { - var tab2 = (Hdy.TabPage)(tab_view.get_pages ().get_item (j)); - unowned var content2 = (ViewContainer)(tab2.child); + var tab2 = (Hdy.TabPage) tab_view.get_pages ().get_item (j); + unowned var content2 = (ViewContainer) tab2.child; if (content2 == content || content2.tab_name == Files.INVALID_TAB_NAME) { continue; } @@ -1089,8 +1089,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.page_detached.disconnect (on_page_detached); /* Avoid infinite loop */ for (uint i = 0; i < tab_view.n_pages; i++) { - var tab_page = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); - ((View.ViewContainer)(tab_page.child)).close (); + var tab_page = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + ((View.ViewContainer) tab_page.child).close (); } this.destroy (); @@ -1137,8 +1137,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { VariantBuilder vb = new VariantBuilder (new VariantType ("a(uss)")); for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage)(tab_view.get_pages ().get_item (i)); - var view_container = (ViewContainer)(tab.child) ; + var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + var view_container = (ViewContainer) tab.child; /* Do not save if "File does not exist" or "Does not belong to you" */ if (!view_container.can_show_folder) { @@ -1340,7 +1340,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { GLib.File root = mount.get_root (); for (uint i = 0; i < tab_view.n_pages; i++) { - var view_container = (View.ViewContainer)(tab_view.get_pages ().get_item (i)) ; + var view_container = (View.ViewContainer) tab_view.get_pages ().get_item (i); GLib.File location = view_container.location; if (location == null || location.has_prefix (root) || location.equal (root)) { From e4fafc83651b05246b43acb36753998ff401deaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 17 Jul 2023 07:42:45 -0700 Subject: [PATCH 21/23] use get_nth_page --- src/View/Window.vala | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index b8a988709b..59f6dfe793 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -631,8 +631,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { parent_path = FileUtils.get_parent_path_from_path (location.get_path ()); int existing_position = 0; - for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + for (int i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage) tab_view.get_nth_page (i); var tab_location = ((ViewContainer) tab.child).location; string tab_uri = tab_location.get_uri (); @@ -651,8 +651,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { /** Compare every tab label with every other and resolve ambiguities **/ private void check_for_tabs_with_same_name () { - for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + for (int i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage) tab_view.get_nth_page (i); unowned var content = (ViewContainer) tab.child; if (content.tab_name == Files.INVALID_TAB_NAME) { set_tab_label (content.tab_name, tab, content.tab_name); @@ -676,8 +676,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { set_tab_label (basename, tab, content.tab_name); // Compare with every other tab for same label - for (uint j = 0; j < tab_view.n_pages; j++) { - var tab2 = (Hdy.TabPage) tab_view.get_pages ().get_item (j); + for (int j = 0; j < tab_view.n_pages; j++) { + var tab2 = (Hdy.TabPage) tab_view.get_nth_page (j); unowned var content2 = (ViewContainer) tab2.child; if (content2 == content || content2.tab_name == Files.INVALID_TAB_NAME) { continue; @@ -1088,8 +1088,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { tab_view.page_detached.disconnect (on_page_detached); /* Avoid infinite loop */ - for (uint i = 0; i < tab_view.n_pages; i++) { - var tab_page = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + for (int i = 0; i < tab_view.n_pages; i++) { + var tab_page = (Hdy.TabPage) tab_view.get_nth_page (i); ((View.ViewContainer) tab_page.child).close (); } @@ -1136,8 +1136,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { } VariantBuilder vb = new VariantBuilder (new VariantType ("a(uss)")); - for (uint i = 0; i < tab_view.n_pages; i++) { - var tab = (Hdy.TabPage) tab_view.get_pages ().get_item (i); + for (int i = 0; i < tab_view.n_pages; i++) { + var tab = (Hdy.TabPage) tab_view.get_nth_page (i); var view_container = (ViewContainer) tab.child; /* Do not save if "File does not exist" or "Does not belong to you" */ @@ -1339,8 +1339,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { debug ("Mount %s removed", mount.get_name ()); GLib.File root = mount.get_root (); - for (uint i = 0; i < tab_view.n_pages; i++) { - var view_container = (View.ViewContainer) tab_view.get_pages ().get_item (i); + for (int i = 0; i < tab_view.n_pages; i++) { + var view_container = (View.ViewContainer) tab_view.get_nth_page (i); GLib.File location = view_container.location; if (location == null || location.has_prefix (root) || location.equal (root)) { From 258739602760d76ef69f714c132c0c920c098df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 17 Jul 2023 07:44:09 -0700 Subject: [PATCH 22/23] Re-add comment --- src/View/Window.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View/Window.vala b/src/View/Window.vala index 59f6dfe793..6ccb791c30 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -586,7 +586,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { var page = tab_view.append (content); content.tab_name_changed.connect ((tab_name) => { - check_for_tabs_with_same_name (); + check_for_tabs_with_same_name (); // Also sets tab_label }); content.loading.connect ((is_loading) => { From f9b3f3a7fc4e04540fe75ed80219952fe1a7f713 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 18 Jul 2023 17:56:03 +0100 Subject: [PATCH 23/23] Fix issues creating a new window (#2259) --- src/Application.vala | 19 ++++++++++++------- src/View/Window.vala | 30 ++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Application.vala b/src/Application.vala index ad86524bb0..a22961b15f 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -298,6 +298,17 @@ public class Files.Application : Gtk.Application { prefs, "sort-directories-first", GLib.SettingsBindFlags.DEFAULT); } + public View.Window? create_empty_window () { + if (this.get_windows ().length () >= MAX_WINDOWS) { //Can be assumed to be limited in length + return null; + } + + var win = new View.Window (this); + add_window (win as Gtk.Window); + plugins.interface_loaded (win as Gtk.Widget); + return win; + } + public View.Window? create_window (GLib.File? location = null, ViewMode viewmode = ViewMode.PREFERRED) { @@ -308,13 +319,7 @@ public class Files.Application : Gtk.Application { private View.Window? create_window_with_tabs (GLib.File[] locations = {}, ViewMode viewmode = ViewMode.PREFERRED) { - if (this.get_windows ().length () >= MAX_WINDOWS) { //Can be assumed to be limited in length - return null; - } - - var win = new View.Window (this); - add_window (win as Gtk.Window); - plugins.interface_loaded (win as Gtk.Widget); + var win = create_empty_window (); win.open_tabs (locations, viewmode); return win; diff --git a/src/View/Window.vala b/src/View/Window.vala index 6ccb791c30..3b08654bc9 100644 --- a/src/View/Window.vala +++ b/src/View/Window.vala @@ -360,7 +360,7 @@ public class Files.View.Window : Hdy.ApplicationWindow { }); tab_view.create_window.connect (() => { - return marlin_app.create_window ().tab_view; + return marlin_app.create_empty_window ().tab_view; }); tab_view.page_attached.connect ((tab, pos) => { @@ -425,23 +425,23 @@ public class Files.View.Window : Hdy.ApplicationWindow { var action_close_end = new SimpleAction ("tabmenu-close-end", null); var action_close_others = new SimpleAction ("tabmenu-close-others", null); var action_duplicate = new SimpleAction ("tabmenu-duplicate", null); - var action_new_window = new SimpleAction ("tabmenu-new-window", null); + var action_move_to_new_window = new SimpleAction ("tabmenu-move-to-window", null); add_action (action_close); add_action (action_close_end); add_action (action_close_others); add_action (action_duplicate); - add_action (action_new_window); + add_action (action_move_to_new_window); marlin_app.set_accels_for_action ("win.tabmenu-close", {"W"}); marlin_app.set_accels_for_action ("win.tabmenu-duplicate", {"T"}); - marlin_app.set_accels_for_action ("win.tabmenu-new-window", {"N"}); + marlin_app.set_accels_for_action ("win.tabmenu-move-to-window", {"N"}); var tab_menu = (Menu) tab_view.menu_model; tab_menu.remove_all (); var open_tab_section = new Menu (); - open_tab_section.append (_("Open in New Window"), "win.tabmenu-new-window"); + open_tab_section.append (_("Open in New Window"), "win.tabmenu-move-to-window"); open_tab_section.append (_("Duplicate Tab"), "win.tabmenu-duplicate"); var close_tab_section = new Menu (); @@ -487,9 +487,9 @@ public class Files.View.Window : Hdy.ApplicationWindow { add_tab (view_container.location, view_container.view_mode); }); - action_new_window.activate.connect (() => { + action_move_to_new_window.activate.connect (() => { var view_container = (ViewContainer) page.child; - add_window (view_container.location, view_container.view_mode); + move_content_to_new_window (view_container); }); } @@ -734,9 +734,18 @@ public class Files.View.Window : Hdy.ApplicationWindow { return !sidebar.has_favorite_uri (uri); } + private void move_content_to_new_window (ViewContainer view_container) { + add_window (view_container.location, view_container.view_mode); + remove_content (view_container); + } + public void remove_content (ViewContainer view_container) { - if (view_container.parent != null && view_container.parent is Hdy.TabPage) { - remove_tab ((Hdy.TabPage) view_container.parent); + for (int n = 0; n < tab_view.n_pages; n++) { + var tab = tab_view.get_nth_page (n); + if (tab.get_child () == view_container) { + remove_tab (tab); + return; + } } } @@ -942,7 +951,8 @@ public class Files.View.Window : Hdy.ApplicationWindow { break; case "WINDOW": - tab_view.create_window (); + //Move current tab to a new window + move_content_to_new_window (current_container); break; default: