From 1bdf7423c748ecee51103603ce305683b076ccc1 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Fri, 25 Jul 2025 22:26:36 +0200 Subject: [PATCH 01/11] SessionDialog: Drop unused prefs_button --- gtk2_ardour/session_dialog.cc | 16 ---------------- gtk2_ardour/session_dialog.h | 5 +---- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 3838ab8ef3..4d771c0442 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -129,11 +129,6 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ existing_button.signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::existing_button_pressed), false); existing_button.set_tweaks(ArdourButton::Tweaks(ArdourButton::ForceFlat)); - prefs_button.set_text("SETTINGS"); - prefs_button.set_name ("tab button"); - prefs_button.signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::prefs_button_pressed), false); - prefs_button.set_tweaks(ArdourButton::Tweaks(ArdourButton::ForceFlat)); - Glib::RefPtr grp = SizeGroup::create (Gtk::SIZE_GROUP_BOTH); grp->add_widget(new_button); grp->add_widget(recent_button); @@ -262,7 +257,6 @@ SessionDialog::tab_page_switched(GtkNotebookPage*, guint page_number) new_button.set_active_state (page_number==0 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); recent_button.set_active_state (page_number==1 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); existing_button.set_active_state (page_number==2 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - prefs_button.set_active_state (page_number==3 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); /* clang-format on */ //check the status of each tab and sensitize the 'open' button appropriately @@ -593,16 +587,6 @@ SessionDialog::existing_button_pressed (GdkEventButton*) return true; } -bool -SessionDialog::prefs_button_pressed (GdkEventButton*) -{ - _tabs.set_current_page(3); - - open_button->set_sensitive(false); //do not allow to open a session from this page - - return true; -} - bool SessionDialog::open_button_pressed (GdkEventButton* ev) { diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h index 7896e306ad..c03df4329d 100644 --- a/gtk2_ardour/session_dialog.h +++ b/gtk2_ardour/session_dialog.h @@ -59,8 +59,7 @@ public: { New = 0, Recent, - Open, - Prefs + Open }; SessionDialog (DialogTab initial_tab, const std::string& session_name, const std::string& session_path, @@ -96,14 +95,12 @@ private: ArdourWidgets::ArdourButton new_button; ArdourWidgets::ArdourButton recent_button; ArdourWidgets::ArdourButton existing_button; - ArdourWidgets::ArdourButton prefs_button; Gtk::ComboBoxText timebase_chooser; bool new_button_pressed (GdkEventButton*); bool recent_button_pressed (GdkEventButton*); bool existing_button_pressed (GdkEventButton*); - bool prefs_button_pressed (GdkEventButton*); bool open_button_pressed (GdkEventButton*); From c6fe5355a4fa3595d21a10d28353937b23e9487f Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 21:00:51 +0200 Subject: [PATCH 02/11] SessionDialog: Drop session_selected It did nothing. And it was called in different contexts, making it hard to imagine which single thing it possibly could do. --- gtk2_ardour/session_dialog.cc | 7 ------- gtk2_ardour/session_dialog.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 4d771c0442..238b490a3a 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -558,11 +558,6 @@ SessionDialog::existing_file_selected () } } -void -SessionDialog::session_selected () -{ -} - bool SessionDialog::new_button_pressed (GdkEventButton*) { @@ -865,7 +860,6 @@ SessionDialog::new_name_changed () } if (!new_name_entry.get_text().empty()) { - session_selected (); open_button->set_sensitive (true); } else { open_button->set_sensitive (false); @@ -1126,7 +1120,6 @@ SessionDialog::recent_session_row_selected () { if (recent_session_display.get_selection()->count_selected_rows() > 0) { open_button->set_sensitive (true); - session_selected (); } else { open_button->set_sensitive (false); } diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h index c03df4329d..9045445a4b 100644 --- a/gtk2_ardour/session_dialog.h +++ b/gtk2_ardour/session_dialog.h @@ -169,8 +169,6 @@ private: void recent_context_mennu (GdkEventButton*); void recent_remove_selected (); - void session_selected (); - void existing_file_selected(); void existing_file_activated (); From b11c7bc5732cb25e21059ff350c78512391d29a3 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 20:51:34 +0200 Subject: [PATCH 03/11] SessionDialog: Drop unused Pango::Layout reference --- gtk2_ardour/session_dialog.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h index 9045445a4b..593a6d909c 100644 --- a/gtk2_ardour/session_dialog.h +++ b/gtk2_ardour/session_dialog.h @@ -230,8 +230,6 @@ private: /* always there */ - Glib::RefPtr layout; - Gtk::Label info_scroller_label; std::string::size_type info_scroller_count; bool info_scroller_update(); From 7a9f376149510950c58003eba48402a5801a0743 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sun, 27 Jul 2025 11:15:30 +0200 Subject: [PATCH 04/11] SessionDialog: Drop set_can_focus() for Gtk::CheckButton _disable_plugins _disable_plugins was the only widget in SessionDialog that had set_can_focus(). That made it look like something special was going on there. But that is not the case. "can_focus" is already the default, and there is no point in setting it again. Remove it, and make it a bit more clear what is going on with focus control. --- gtk2_ardour/session_dialog.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 238b490a3a..2a12eb2a9b 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -174,7 +174,6 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ open_button->signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::open_button_pressed), false); _disable_plugins.set_label (_("Safe Mode: Disable all Plugins")); - _disable_plugins.set_can_focus (); _disable_plugins.set_relief (Gtk::RELIEF_NORMAL); _disable_plugins.set_mode (true); _disable_plugins.set_active (ARDOUR::Session::get_disable_all_loaded_plugins()); From 749d4653322140f58b0e64db7adc232e51865fba Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 20:57:23 +0200 Subject: [PATCH 05/11] SessionDialog: Reorder session_dialog.h The file had a bit of structure and grouping, but didn't use it consistently. These changes might not make it perfect, but I think it makes it better. --- gtk2_ardour/session_dialog.h | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h index 593a6d909c..614ab9b8f7 100644 --- a/gtk2_ardour/session_dialog.h +++ b/gtk2_ardour/session_dialog.h @@ -96,24 +96,16 @@ private: ArdourWidgets::ArdourButton recent_button; ArdourWidgets::ArdourButton existing_button; - Gtk::ComboBoxText timebase_chooser; - bool new_button_pressed (GdkEventButton*); bool recent_button_pressed (GdkEventButton*); bool existing_button_pressed (GdkEventButton*); bool open_button_pressed (GdkEventButton*); - Gtk::HBox _info_box; - Gtk::Table _open_table; /* initial choice page */ - void setup_existing_box (); - void setup_recent_sessions (); - Gtk::VBox recent_vbox; - DialogTab _initial_tab; #ifdef MIXBUS @@ -122,9 +114,15 @@ private: void license_button_clicked (); #endif + /* tabs */ + + Gtk::Notebook _tabs; + void tab_page_switched (GtkNotebookPage*, guint page_number); + /* recent sessions */ - void setup_existing_session_page (); + void setup_recent_sessions (); + Gtk::VBox recent_vbox; struct RecentSessionsSorter { @@ -160,7 +158,7 @@ private: Glib::RefPtr recent_session_model; Gtk::ScrolledWindow recent_scroller; Gtk::Label recent_label; - Gtk::FileChooserWidget existing_session_chooser; + int redisplay_recent_sessions (); void recent_session_row_selected (); void recent_session_sort_changed (); @@ -169,10 +167,7 @@ private: void recent_context_mennu (GdkEventButton*); void recent_remove_selected (); - void existing_file_selected(); - void existing_file_activated (); - - /* new sessions */ + /* new sessions (and template stuff) */ void setup_new_session_page (); Gtk::Entry new_name_entry; @@ -219,7 +214,15 @@ private: void new_name_activated (); void populate_session_templates (); - void tab_page_switched(GtkNotebookPage*, guint page_number); + Gtk::ComboBoxText timebase_chooser; + + /* open existing session */ + + void setup_existing_session_page (); + void setup_existing_box (); + Gtk::FileChooserWidget existing_session_chooser; + void existing_file_selected (); + void existing_file_activated (); /* --disable plugins UI */ Gtk::CheckButton _disable_plugins; @@ -230,13 +233,12 @@ private: /* always there */ + Gtk::HBox _info_box; Gtk::Label info_scroller_label; std::string::size_type info_scroller_count; bool info_scroller_update(); sigc::connection info_scroller_connection; void updates_button_clicked (); - - Gtk::Notebook _tabs; }; #endif /* __gtk2_ardour_session_dialog_h__ */ From f79a6a6162bcb9451a68c6e95ac463d48eeacff6 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 20:47:23 +0200 Subject: [PATCH 06/11] SessionDialog: Name the dialog after what it does, not after the initial state The dialog always has 3 different tabs. After changing the tab, the window title became misleading. It seems more helpful to use a windows title that shows the intent of the dialog: Selecting a session. --- gtk2_ardour/session_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 2a12eb2a9b..6e2697c153 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -77,7 +77,7 @@ using namespace ArdourWidgets; using namespace ARDOUR_UI_UTILS; SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_name, const std::string& session_path, const std::string& template_name, bool cancel_not_quit) - : ArdourDialog (initial_tab == New ? _("Session Setup") : _("Recent Sessions"), true, true) + : ArdourDialog (_("Select Session"), true, true) , _initial_tab (initial_tab) , new_name_was_edited (false) , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER) From 4a5351ee3326e0cd165dd71f1df57e860896bdb2 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Fri, 25 Jul 2025 22:27:32 +0200 Subject: [PATCH 07/11] SessionDialog: Add some mnemonics (keyboard shortcuts) The mnemonics only show up when pressing the Alt key and do not do any harm. --- gtk2_ardour/session_dialog.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index 6e2697c153..a206da13ec 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -173,7 +173,8 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ open_button = add_button (Stock::OPEN, RESPONSE_ACCEPT); open_button->signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::open_button_pressed), false); - _disable_plugins.set_label (_("Safe Mode: Disable all Plugins")); + _disable_plugins.set_label (_("Safe Mode: _Disable all Plugins")); + _disable_plugins.set_use_underline (); _disable_plugins.set_relief (Gtk::RELIEF_NORMAL); _disable_plugins.set_mode (true); _disable_plugins.set_active (ARDOUR::Session::get_disable_all_loaded_plugins()); @@ -707,7 +708,9 @@ SessionDialog::setup_new_session_page () session_new_vbox.set_spacing (8); Label* name_label = manage (new Label); - name_label->set_text (_("Session name:")); + name_label->set_text (_("_Session name:")); + name_label->set_use_underline (); + name_label->set_mnemonic_widget (new_name_entry); HBox* name_hbox = manage (new HBox); name_hbox->set_spacing (8); @@ -720,7 +723,9 @@ SessionDialog::setup_new_session_page () //Folder location for the new session Label* new_folder_label = manage (new Label); - new_folder_label->set_text (_("Create session folder in:")); + new_folder_label->set_text (_("_Create session folder in:")); + new_folder_label->set_use_underline (); + new_folder_label->set_mnemonic_widget (new_folder_chooser); HBox* folder_box = manage (new HBox); folder_box->set_spacing (8); folder_box->pack_start (*new_folder_label, false, false); @@ -748,7 +753,9 @@ SessionDialog::setup_new_session_page () //Timebase for the new session Label* session_domain_label = manage (new Label); - session_domain_label->set_text (_("Default Time Domain:")); + session_domain_label->set_text (_("_Default Time Domain:")); + session_domain_label->set_use_underline (); + session_domain_label->set_mnemonic_widget (timebase_chooser); HBox* timebase_box = manage (new HBox); timebase_box->set_spacing (8); timebase_box->pack_start (*session_domain_label, false, false); From 954ad2b6eef28693782ad9f2334931be78e038b2 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 11:47:37 +0200 Subject: [PATCH 08/11] SessionDialog: Use enum instead of hardcoding page numbers The hardcoded numbers were fragile ... especially if the numbers should happen to change in the future ... --- gtk2_ardour/session_dialog.cc | 50 +++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index a206da13ec..c7368114ed 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -76,6 +76,13 @@ using namespace ARDOUR; using namespace ArdourWidgets; using namespace ARDOUR_UI_UTILS; +enum tab_page_numbers { + page_number_new = 0, + page_number_recent = 1, + page_number_open = 2, + page_number_unused +}; + SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_name, const std::string& session_path, const std::string& template_name, bool cancel_not_quit) : ArdourDialog (_("Select Session"), true, true) , _initial_tab (initial_tab) @@ -158,8 +165,11 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ _tabs.set_show_tabs(false); _tabs.set_show_border(false); + // add page_number_new = 0 _tabs.append_page(session_new_vbox); + // add page_number_recent = 1 _tabs.append_page(recent_vbox); + // add page_number_open = 2 _tabs.append_page(existing_session_chooser); session_new_vbox.show_all(); @@ -236,16 +246,16 @@ SessionDialog::on_show () { ArdourDialog::on_show (); - _tabs.set_current_page(3); // force change + _tabs.set_current_page (page_number_unused); // force change switch (_initial_tab) { case New: - _tabs.set_current_page(0); + _tabs.set_current_page (page_number_new); break; case Open: - _tabs.set_current_page(2); + _tabs.set_current_page (page_number_open); break; default: - _tabs.set_current_page(1); + _tabs.set_current_page (page_number_recent); break; } } @@ -254,25 +264,25 @@ void SessionDialog::tab_page_switched(GtkNotebookPage*, guint page_number) { /* clang-format off */ - new_button.set_active_state (page_number==0 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - recent_button.set_active_state (page_number==1 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - existing_button.set_active_state (page_number==2 ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + new_button.set_active_state (page_number==page_number_new ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + recent_button.set_active_state (page_number==page_number_recent ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + existing_button.set_active_state (page_number==page_number_open ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); /* clang-format on */ //check the status of each tab and sensitize the 'open' button appropriately open_button->set_sensitive(false); switch (page_number) { - case 0: + case page_number_new: new_name_changed(); new_name_entry.select_region (0, -1); new_name_entry.grab_focus (); _disable_plugins.hide (); break; - case 1: + case page_number_recent: recent_session_row_selected(); _disable_plugins.show (); break; - case 2: + case page_number_open: existing_file_selected(); _disable_plugins.show (); break; @@ -385,13 +395,13 @@ std::string SessionDialog::session_name (bool& should_be_new) { switch (_tabs.get_current_page()) { - case 0: { + case page_number_new: { should_be_new = true; string val = new_name_entry.get_text (); strip_whitespace_edges (val); return val; } break; - case 1: { + case page_number_recent: { /* Try recent session selection */ TreeIter iter = recent_session_display.get_selection()->get_selected(); if (iter) { @@ -403,7 +413,7 @@ SessionDialog::session_name (bool& should_be_new) return (*iter)[recent_session_columns.visible_name]; } } break; - case 2: { + case page_number_open: { /* existing session chosen from file chooser */ should_be_new = false; return existing_session_chooser.get_filename (); @@ -417,14 +427,14 @@ std::string SessionDialog::session_folder () { switch (_tabs.get_current_page()) { - case 0: + case page_number_new: { std::string val = new_name_entry.get_text(); strip_whitespace_edges (val); std::string legal_session_folder_name = legalize_for_path (val); return Glib::build_filename (new_folder_chooser.get_filename (), legal_session_folder_name); } - case 1: + case page_number_recent: { /* Try recent session selection */ TreeIter iter = recent_session_display.get_selection()->get_selected(); @@ -437,7 +447,7 @@ SessionDialog::session_folder () } } break; - case 2: + case page_number_open: /* existing session chosen from file chooser */ return Glib::path_get_dirname (existing_session_chooser.get_current_folder ()); default: @@ -523,7 +533,7 @@ SessionDialog::setup_existing_box () void SessionDialog::existing_file_selected () { - if (_tabs.get_current_page()!=2) { + if (_tabs.get_current_page () != page_number_open) { //gtk filechooser is threaded; don't allow it to mess with open_button sensitivity when it's not actually visible return; } @@ -561,7 +571,7 @@ SessionDialog::existing_file_selected () bool SessionDialog::new_button_pressed (GdkEventButton*) { - _tabs.set_current_page(0); + _tabs.set_current_page (page_number_new); return true; } @@ -569,7 +579,7 @@ SessionDialog::new_button_pressed (GdkEventButton*) bool SessionDialog::recent_button_pressed (GdkEventButton*) { - _tabs.set_current_page(1); + _tabs.set_current_page (page_number_recent); return true; } @@ -577,7 +587,7 @@ SessionDialog::recent_button_pressed (GdkEventButton*) bool SessionDialog::existing_button_pressed (GdkEventButton*) { - _tabs.set_current_page(2); + _tabs.set_current_page (page_number_open); return true; } From 72ae421e7f87f2bdad076628a45e4d36be927bc8 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 12:06:07 +0200 Subject: [PATCH 09/11] SessionDialog: Use plain notebook tab labels for New/Recent/Open instead of custom ArdourButton In my opinion, the ArdourButton approach for SessionDialog introduced in 524073d8 regressed in some annoying ways: * No keyboard shortcuts. * Big panes look a bit like Tcl/Tk. * YELLING. While it seems like keyboard shortcuts for ArdourButton would be handy in many places, it doesn't seem trivial to add it. Plain GtkNotebook seems to work better: * Keyboard shortcuts for changing tabs. * More standard look. With these changes, New and Recent works pretty well with keyboard navigation. There should only be minor changes when using mouse. The buttons are of course smaller, but that not be a problem for users that can navigate other parts of the Ardour UI. Keyboard navigation in GtkFileChooser remains broken for now. There is thus not much use of keyboard navigation to open the Open page, but we add it anyway. --- gtk2_ardour/session_dialog.cc | 92 +++++++++-------------------------- gtk2_ardour/session_dialog.h | 9 +--- 2 files changed, 24 insertions(+), 77 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index c7368114ed..a532a6ab9e 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -77,9 +77,10 @@ using namespace ArdourWidgets; using namespace ARDOUR_UI_UTILS; enum tab_page_numbers { - page_number_new = 0, - page_number_recent = 1, - page_number_open = 2, + page_number_logo = 0, + page_number_new = 1, + page_number_recent = 2, + page_number_open = 3, page_number_unused }; @@ -120,41 +121,20 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ /* no update message for trax, show license here */ _open_table.attach (_info_box, 1,3, 0,1, FILL, FILL, 0, 6); #endif - - new_button.set_text("NEW"); - new_button.set_name ("tab button"); - new_button.signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::new_button_pressed), false); - new_button.set_tweaks(ArdourButton::Tweaks(ArdourButton::ForceFlat)); - - recent_button.set_text("RECENT"); - recent_button.set_name ("tab button"); - recent_button.signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::recent_button_pressed), false); - recent_button.set_tweaks(ArdourButton::Tweaks(ArdourButton::ForceFlat)); - - existing_button.set_text("OPEN"); - existing_button.set_name ("tab button"); - existing_button.signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::existing_button_pressed), false); - existing_button.set_tweaks(ArdourButton::Tweaks(ArdourButton::ForceFlat)); - - Glib::RefPtr grp = SizeGroup::create (Gtk::SIZE_GROUP_BOTH); - grp->add_widget(new_button); - grp->add_widget(recent_button); - grp->add_widget(existing_button); int top = 0; int row = 0; + // page_number_logo = 0 + Gtk::Image* image; if (find_file (rc, PROGRAM_NAME "-small-splash.png", image_path)) { - Gtk::Image* image; - if ((image = manage (new Gtk::Image (image_path))) != 0) { - _open_table.attach (*image, 0,1, row , row + 1, FILL, FILL); ++row; - grp->add_widget (*image); - } + image = manage (new Gtk::Image (image_path)); + } + if (image != 0) { + _tabs.append_page (logo_empty_page, *image); + } else { + _tabs.append_page (logo_empty_page, PROGRAM_NAME); } - - _open_table.attach (new_button, 0,1, row, row + 1, FILL, FILL); ++row; - _open_table.attach (recent_button, 0,1, row, row + 1, FILL, FILL); ++row; - _open_table.attach (existing_button, 0,1, row, row + 1, FILL, FILL); ++row; ++row; Label *vspacer = manage (new Label()); @@ -162,15 +142,15 @@ SessionDialog::SessionDialog (DialogTab initial_tab, const std::string& session_ _open_table.attach (*vspacer, 1,2, top, row, FILL, FILL|EXPAND, 0, 0); _open_table.attach (_tabs, 2,3, top, row, FILL|EXPAND, FILL|EXPAND, 0, 0); - _tabs.set_show_tabs(false); + _tabs.set_tab_pos (POS_LEFT); _tabs.set_show_border(false); - // add page_number_new = 0 - _tabs.append_page(session_new_vbox); - // add page_number_recent = 1 - _tabs.append_page(recent_vbox); - // add page_number_open = 2 - _tabs.append_page(existing_session_chooser); + // add page_number_new = 1 + _tabs.append_page (session_new_vbox, "_New", true); + // add page_number_recent = 2 + _tabs.append_page (recent_vbox, "_Recent", true); + // add page_number_open = 3 + _tabs.append_page (existing_session_chooser, "Op_en", true); session_new_vbox.show_all(); recent_vbox.show_all(); @@ -263,15 +243,12 @@ SessionDialog::on_show () void SessionDialog::tab_page_switched(GtkNotebookPage*, guint page_number) { - /* clang-format off */ - new_button.set_active_state (page_number==page_number_new ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - recent_button.set_active_state (page_number==page_number_recent ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - existing_button.set_active_state (page_number==page_number_open ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); - /* clang-format on */ - //check the status of each tab and sensitize the 'open' button appropriately open_button->set_sensitive(false); switch (page_number) { + case page_number_logo: + _tabs.set_current_page (1); + break; case page_number_new: new_name_changed(); new_name_entry.select_region (0, -1); @@ -280,6 +257,7 @@ SessionDialog::tab_page_switched(GtkNotebookPage*, guint page_number) break; case page_number_recent: recent_session_row_selected(); + recent_session_display.grab_focus (); _disable_plugins.show (); break; case page_number_open: @@ -568,30 +546,6 @@ SessionDialog::existing_file_selected () } } -bool -SessionDialog::new_button_pressed (GdkEventButton*) -{ - _tabs.set_current_page (page_number_new); - - return true; -} - -bool -SessionDialog::recent_button_pressed (GdkEventButton*) -{ - _tabs.set_current_page (page_number_recent); - - return true; -} - -bool -SessionDialog::existing_button_pressed (GdkEventButton*) -{ - _tabs.set_current_page (page_number_open); - - return true; -} - bool SessionDialog::open_button_pressed (GdkEventButton* ev) { diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h index 614ab9b8f7..a6c2b7eb94 100644 --- a/gtk2_ardour/session_dialog.h +++ b/gtk2_ardour/session_dialog.h @@ -92,14 +92,6 @@ private: Gtk::Button* open_button; Gtk::Button* quit_button; - ArdourWidgets::ArdourButton new_button; - ArdourWidgets::ArdourButton recent_button; - ArdourWidgets::ArdourButton existing_button; - - bool new_button_pressed (GdkEventButton*); - bool recent_button_pressed (GdkEventButton*); - bool existing_button_pressed (GdkEventButton*); - bool open_button_pressed (GdkEventButton*); Gtk::Table _open_table; @@ -117,6 +109,7 @@ private: /* tabs */ Gtk::Notebook _tabs; + Gtk::VBox logo_empty_page; void tab_page_switched (GtkNotebookPage*, guint page_number); /* recent sessions */ From 4ec0d0453c965e888f7132572849996ad8dde371 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sat, 26 Jul 2025 20:49:22 +0200 Subject: [PATCH 10/11] GtkNotebook: When switching page with mnemonic, set new focus *before* calling callbacks Allow signal_switch_page to move focus into the page, instead of forcing focus on the label that just was activated. This is very useful for SessionDialog for allowing the same behaviour when changing page with mouse and keyboard. --- libs/tk/ytk/gtknotebook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/tk/ytk/gtknotebook.c b/libs/tk/ytk/gtknotebook.c index 21095520a6..959cfe5da8 100644 --- a/libs/tk/ytk/gtknotebook.c +++ b/libs/tk/ytk/gtknotebook.c @@ -6596,8 +6596,8 @@ gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child, GtkNotebookPage *page = list->data; gtk_widget_grab_focus (GTK_WIDGET (notebook)); /* Do this first to avoid focusing new page */ - gtk_notebook_switch_page (notebook, page); focus_tabs_in (notebook); + gtk_notebook_switch_page (notebook, page); } return TRUE; From 880303044f92597d822e74f453034c28695667fc Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Sun, 27 Jul 2025 11:06:22 +0200 Subject: [PATCH 11/11] SessionDialog: Add "label" and mnemonic for "New" template list The "New" page moves focus to "Session name", and there was no easy way to get the template list at the top of the page. Fix that by showing the header line (even though the table only has one column in Ardour) and put a mnemonic on "Template". Headers are already shown by default and there is no need to enable them explicitly - just don't hide them. --- gtk2_ardour/session_dialog.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc index a532a6ab9e..89c87b759d 100644 --- a/gtk2_ardour/session_dialog.cc +++ b/gtk2_ardour/session_dialog.cc @@ -769,12 +769,9 @@ SessionDialog::setup_new_session_page () //template_chooser is the treeview showing available templates template_model = TreeStore::create (session_template_columns); template_chooser.set_model (template_model); - template_chooser.append_column (_("Template"), session_template_columns.name); + template_chooser.append_column (_("_Template"), session_template_columns.name); // single column header has value as mnemonic #ifdef MIXBUS template_chooser.append_column (_("Modified With"), session_template_columns.modified_with_short); - template_chooser.set_headers_visible (true); -#else - template_chooser.set_headers_visible (false); //there is only one column and its purpose should be obvious #endif template_chooser.get_selection()->set_mode (SELECTION_SINGLE); template_chooser.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &SessionDialog::template_row_selected));