Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add default menu bar in dioxus-desktop to resolve #1691 #1696

Merged
merged 6 commits into from
Jan 4, 2024
Merged
10 changes: 10 additions & 0 deletions packages/desktop/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) enable_default_menu_bar: bool,
}

type DropHandler = Box<dyn Fn(&Window, FileDropEvent) -> bool>;
Expand Down Expand Up @@ -65,9 +66,18 @@ impl Config {
root_name: "main".to_string(),
background_color: None,
last_window_close_behaviour: WindowCloseBehaviour::LastWindowExitsApp,
enable_default_menu_bar: true,
}
}

/// Set whether the default menu bar should be enabled.
///
/// > Note: `enable` is `true` by default. To disable the default menu bar pass `false`.
pub fn with_default_menu_bar(mut self, enable: bool) -> Self {
self.enable_default_menu_bar = enable;
self
}

/// set the directory from which assets will be searched in release mode
pub fn with_resource_directory(mut self, path: impl Into<PathBuf>) -> Self {
self.resource_dir = Some(path.into());
Expand Down
1 change: 1 addition & 0 deletions packages/desktop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use tao::{
event::{Event, StartCause, WindowEvent},
event_loop::ControlFlow,
};
pub use webview::build_default_menu_bar;
pub use wry;
pub use wry::application as tao;
use wry::application::event_loop::EventLoopBuilder;
Expand Down
66 changes: 65 additions & 1 deletion packages/desktop/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::http::Response;
use wry::webview::{WebContext, WebView, WebViewBuilder};
Expand All @@ -13,13 +14,18 @@ pub fn build(
event_loop: &EventLoopWindowTarget<UserWindowEvent>,
proxy: EventLoopProxy<UserWindowEvent>,
) -> (WebView, WebContext, AssetHandlerRegistry) {
let builder = cfg.window.clone();
let window = builder.with_visible(false).build(event_loop).unwrap();
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.enable_default_menu_bar {
builder = builder.with_menu(build_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(
Expand Down Expand Up @@ -129,3 +135,61 @@ pub fn build(

(webview.build().unwrap(), web_context, asset_handlers)
}

/// Builds a standard menu bar depending on the users platform. It may be used as a starting point
/// to further customize the menu bar and pass it to a [`WindowBuilder`](tao::window::WindowBuilder).
/// > Note: The default menu bar enables macOS shortcuts like cut/copy/paste.
/// > The menu bar differs per platform because of constraints introduced
/// > by [`MenuItem`](tao::menu::MenuItem).
pub fn build_default_menu_bar() -> MenuBar {
pascalbehmenburg marked this conversation as resolved.
Show resolved Hide resolved
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
}
Loading