From 085335ca14e633c80070e06968250779f448291a Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Fri, 9 Oct 2026 02:37:25 +0200 Subject: [PATCH] feat(gui): one main menu, on the sidebar's account row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sidebar header had a hamburger beside the brand, and the account row in the footer had its own ⋮ menu; both offered Preferences. The header button sat next to the page's own tools and read as one of them. The account row is now the main menu's button, as in Proton's own apps: Preferences, Keyboard Shortcuts and About, then Sign Out. The whole row opens it, upwards, and F10 still does as the primary menu. --- .../scalable/actions/pdfs-menu-symbolic.svg | 5 --- crates/pdfs-gui/resources/pdfs.gresource.xml | 1 - crates/pdfs-gui/resources/style.css | 4 +- crates/pdfs-gui/src/app/main.rs | 21 +---------- crates/pdfs-gui/src/app/pages/status.rs | 37 ++++++++++++------- 5 files changed, 28 insertions(+), 40 deletions(-) delete mode 100644 crates/pdfs-gui/resources/icons/scalable/actions/pdfs-menu-symbolic.svg diff --git a/crates/pdfs-gui/resources/icons/scalable/actions/pdfs-menu-symbolic.svg b/crates/pdfs-gui/resources/icons/scalable/actions/pdfs-menu-symbolic.svg deleted file mode 100644 index 5796a0f..0000000 --- a/crates/pdfs-gui/resources/icons/scalable/actions/pdfs-menu-symbolic.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/crates/pdfs-gui/resources/pdfs.gresource.xml b/crates/pdfs-gui/resources/pdfs.gresource.xml index 1026a5a..80b0b1b 100644 --- a/crates/pdfs-gui/resources/pdfs.gresource.xml +++ b/crates/pdfs-gui/resources/pdfs.gresource.xml @@ -14,7 +14,6 @@ scalable/actions/pdfs-details-pane-symbolic.svg scalable/actions/pdfs-link-symbolic.svg scalable/actions/pdfs-map-symbolic.svg - scalable/actions/pdfs-menu-symbolic.svg scalable/actions/pdfs-people-symbolic.svg scalable/actions/pdfs-share-symbolic.svg scalable/actions/pdfs-sync-symbolic.svg diff --git a/crates/pdfs-gui/resources/style.css b/crates/pdfs-gui/resources/style.css index e46a333..a21039a 100644 --- a/crates/pdfs-gui/resources/style.css +++ b/crates/pdfs-gui/resources/style.css @@ -18,7 +18,9 @@ .sidebar-status image.warning { color: var(--warning-color); } .sidebar-status image.error { color: var(--error-color); } .sidebar-quota progressbar trough, .sidebar-quota progressbar progress { min-height: 4px; } -.sidebar-account { padding: 4px 4px 4px 8px; } +/* The account row is the main menu's button: a row, not a pushbutton, so + * the name keeps the text weight. */ +button.sidebar-account { padding: 4px 8px; font-weight: normal; } /* A count of what waits on a page, at the end of its sidebar row */ .sidebar-badge { min-width: 10px; diff --git a/crates/pdfs-gui/src/app/main.rs b/crates/pdfs-gui/src/app/main.rs index 8feb958..7f8f67e 100644 --- a/crates/pdfs-gui/src/app/main.rs +++ b/crates/pdfs-gui/src/app/main.rs @@ -831,7 +831,6 @@ fn build_sidebar(footer: >k4::Box) -> (adw::NavigationPage, gtk4::ListBox) { let header = adw::HeaderBar::new(); header.set_title_widget(Some(&brand)); - header.pack_end(&build_primary_menu()); let scroll = gtk4::ScrolledWindow::builder() .hscrollbar_policy(gtk4::PolicyType::Never) @@ -1154,25 +1153,7 @@ fn toast_failure(ui: &Rc, what: &str, message: &str, kind: ErrorKind) { } } -/// The sidebar's primary (hamburger) menu: the app-level entries that don't -/// belong on any one page. -fn build_primary_menu() -> gtk4::MenuButton { - let menu = gio::Menu::new(); - menu.append(Some(&gettext("Preferences")), Some("win.preferences")); - menu.append(Some(&gettext("Keyboard Shortcuts")), Some("win.shortcuts")); - menu.append( - Some(&gettext("About Proton Drive for Linux")), - Some("win.about"), - ); - gtk4::MenuButton::builder() - .icon_name("pdfs-menu-symbolic") - .tooltip_text(gettext("Main menu")) - .primary(true) - .menu_model(&menu) - .build() -} - -/// Back the primary and account menus' entries with window actions. +/// Back the main menu's entries with window actions. fn install_window_actions(ui: &Rc, window: &adw::ApplicationWindow) { let preferences = gio::SimpleAction::new("preferences", None); let ui_prefs = ui.clone(); diff --git a/crates/pdfs-gui/src/app/pages/status.rs b/crates/pdfs-gui/src/app/pages/status.rs index adaece5..fab7142 100644 --- a/crates/pdfs-gui/src/app/pages/status.rs +++ b/crates/pdfs-gui/src/app/pages/status.rs @@ -381,23 +381,34 @@ pub(crate) fn build_main_page() -> MainWidgets { .hexpand(true) .ellipsize(gtk4::pango::EllipsizeMode::Middle) .build(); + // The app's one menu, on the account row the way Proton's own apps keep it: + // app-wide entries first, the account's last. The whole row opens it, and + // F10 too, as the primary menu. + let app_section = gio::Menu::new(); + app_section.append(Some(&gettext("Preferences")), Some("win.preferences")); + app_section.append(Some(&gettext("Keyboard Shortcuts")), Some("win.shortcuts")); + app_section.append( + Some(&gettext("About Proton Drive for Linux")), + Some("win.about"), + ); + let account_section = gio::Menu::new(); + account_section.append(Some(&gettext("Sign Out…")), Some("win.sign-out")); let account_menu = gio::Menu::new(); - account_menu.append(Some(&gettext("Preferences")), Some("win.preferences")); - let sign_out = gio::Menu::new(); - sign_out.append(Some(&gettext("Sign Out…")), Some("win.sign-out")); - account_menu.append_section(None, &sign_out); - let account_button = gtk4::MenuButton::builder() - .icon_name("view-more-symbolic") - .tooltip_text(gettext("Account")) + account_menu.append_section(None, &app_section); + account_menu.append_section(None, &account_section); + let row = gtk4::Box::new(gtk4::Orientation::Horizontal, 10); + row.append(&avatar); + row.append(&account_name); + row.append(>k4::Image::from_icon_name("view-more-symbolic")); + let account = gtk4::MenuButton::builder() + .child(&row) + .tooltip_text(gettext("Main menu")) .menu_model(&account_menu) - .valign(gtk4::Align::Center) + .direction(gtk4::ArrowType::Up) + .primary(true) .build(); - account_button.add_css_class("flat"); - let account = gtk4::Box::new(gtk4::Orientation::Horizontal, 10); + account.add_css_class("flat"); account.add_css_class("sidebar-account"); - account.append(&avatar); - account.append(&account_name); - account.append(&account_button); let footer = gtk4::Box::new(gtk4::Orientation::Vertical, 10); footer.add_css_class("sidebar-footer");