From e4d60c8dfcf7c1633d9868dd91a65afcdf48dfb7 Mon Sep 17 00:00:00 2001 From: Pascal Date: Wed, 6 Dec 2023 21:39:31 +0100 Subject: [PATCH] add default menu bar in dioxus-desktop to resolve #1691 fixup naming and expose disable_default_menu_bar with builder function --- packages/desktop/src/cfg.rs | 8 +++++ packages/desktop/src/webview.rs | 64 +++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/packages/desktop/src/cfg.rs b/packages/desktop/src/cfg.rs index 07281e364..ba42ffa01 100644 --- a/packages/desktop/src/cfg.rs +++ b/packages/desktop/src/cfg.rs @@ -36,6 +36,7 @@ pub struct Config { pub(crate) root_name: String, pub(crate) background_color: Option<(u8, u8, u8, u8)>, pub(crate) last_window_close_behaviour: WindowCloseBehaviour, + pub(crate) disable_default_menu_bar: bool, } type DropHandler = Box bool>; @@ -65,9 +66,16 @@ impl Config { root_name: "main".to_string(), background_color: None, last_window_close_behaviour: WindowCloseBehaviour::LastWindowExitsApp, + disable_default_menu_bar: false, } } + /// Set whether the default menu bar should be disabled. + pub fn with_disable_default_menu_bar(mut self, disable: bool) -> Self { + self.disable_default_menu_bar = disable; + self + } + /// set the directory from which assets will be searched in release mode pub fn with_resource_directory(mut self, path: impl Into) -> Self { self.resource_dir = Some(path.into()); diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs index 6e6d26b17..9beae702a 100644 --- a/packages/desktop/src/webview.rs +++ b/packages/desktop/src/webview.rs @@ -4,6 +4,7 @@ use crate::{desktop_context::UserWindowEvent, Config}; use tao::event_loop::{EventLoopProxy, EventLoopWindowTarget}; pub use wry; pub use wry::application as tao; +use wry::application::menu::{MenuBar, MenuItem}; use wry::application::window::Window; use wry::webview::{WebContext, WebView, WebViewBuilder}; @@ -12,13 +13,18 @@ pub fn build( event_loop: &EventLoopWindowTarget, proxy: EventLoopProxy, ) -> (WebView, WebContext) { - let builder = cfg.window.clone(); - let window = builder.with_visible(false).build(event_loop).unwrap(); + let mut builder = cfg.window.clone(); let file_handler = cfg.file_drop_handler.take(); let custom_head = cfg.custom_head.clone(); let index_file = cfg.custom_index.clone(); let root_name = cfg.root_name.clone(); + if !cfg.disable_default_menu_bar { + builder = builder.with_menu(create_default_menu_bar()); + } + + let window = builder.with_visible(false).build(event_loop).unwrap(); + // We assume that if the icon is None in cfg, then the user just didnt set it if cfg.window.window.window_icon.is_none() { window.set_window_icon(Some( @@ -96,3 +102,57 @@ pub fn build( (webview.build().unwrap(), web_context) } + +/// Creates a standard menu bar depending on the platform +fn create_default_menu_bar() -> MenuBar { + let mut menu_bar = MenuBar::new(); + + // since it is uncommon on windows to have an "application menu" + // we add a "window" menu to be more consistent across platforms with the standard menu + let mut window_menu = MenuBar::new(); + #[cfg(target_os = "macos")] + { + window_menu.add_native_item(MenuItem::EnterFullScreen); + window_menu.add_native_item(MenuItem::Zoom); + window_menu.add_native_item(MenuItem::Separator); + } + + window_menu.add_native_item(MenuItem::Hide); + + #[cfg(target_os = "macos")] + { + window_menu.add_native_item(MenuItem::HideOthers); + window_menu.add_native_item(MenuItem::ShowAll); + } + + window_menu.add_native_item(MenuItem::Minimize); + window_menu.add_native_item(MenuItem::CloseWindow); + window_menu.add_native_item(MenuItem::Separator); + window_menu.add_native_item(MenuItem::Quit); + menu_bar.add_submenu("Window", true, window_menu); + + // since tao supports none of the below items on linux we should only add them on macos/windows + #[cfg(not(target_os = "linux"))] + { + let mut edit_menu = MenuBar::new(); + #[cfg(target_os = "macos")] + { + edit_menu.add_native_item(MenuItem::Undo); + edit_menu.add_native_item(MenuItem::Redo); + edit_menu.add_native_item(MenuItem::Separator); + } + + edit_menu.add_native_item(MenuItem::Cut); + edit_menu.add_native_item(MenuItem::Copy); + edit_menu.add_native_item(MenuItem::Paste); + + #[cfg(target_os = "macos")] + { + edit_menu.add_native_item(MenuItem::Separator); + edit_menu.add_native_item(MenuItem::SelectAll); + } + menu_bar.add_submenu("Edit", true, edit_menu); + } + + menu_bar +}