Fix muda segfault

This commit is contained in:
Jonathan Kelley committed 2024-01-11 14:50:21 -08:00
1 parent f7bf156422
commit 08c522d5b3
4 files changed
+128 -103

No files matched your search

-1
View File
@@ -55,7 +55,6 @@ impl Config {
);
Self {
// event_handler: None,
window,
protocols: Vec::new(),
file_drop_handler: None,
+76 -56
View File
@@ -1,78 +1,98 @@
use std::any::Any;
use tao::window::Window;
#[allow(unused)]
pub fn build_menu(window: &Window, default_menu_bar: bool) {
if default_menu_bar {
#[cfg(not(any(target_os = "ios", target_os = "android")))]
impl_::build_menu_bar(impl_::build_default_menu_bar(), window)
pub fn build_menu(window: &Window, default_menu_bar: bool) -> Option<Box<dyn Any>> {
let mut menu = None;
if cfg!(not(any(target_os = "ios", target_os = "android"))) {
menu = Some(Box::new(impl_::build_menu_bar(default_menu_bar, window)) as Box<dyn Any>);
}
menu
}
#[cfg(not(any(target_os = "ios", target_os = "android")))]
mod impl_ {
use super::*;
use muda::{Menu, PredefinedMenuItem, Submenu};
#[allow(unused)]
pub fn build_menu_bar(menu: Menu, window: &Window) {
#[cfg(target_os = "windows")]
use tao::platform::windows::WindowExtWindows;
#[cfg(target_os = "windows")]
menu.init_for_hwnd(window.hwnd());
// #[cfg(target_os = "linux")]
// {
// use tao::platform::unix::WindowExtUnix;
// menu.init_for_gtk_window(window, None);
// menu.init_for_gtk_window(window, Some(&ertical_gtk_box));
// }
#[cfg(target_os = "macos")]
menu.init_for_nsapp();
}
use muda::{Menu, MenuItem, PredefinedMenuItem, Submenu};
/// 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() -> Menu {
#[allow(unused)]
pub fn build_menu_bar(default: bool, window: &Window) -> Menu {
let menu = Menu::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 window_menu = Submenu::new("Window", true);
window_menu
.append_items(&[
&PredefinedMenuItem::fullscreen(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::hide(None),
&PredefinedMenuItem::hide_others(None),
&PredefinedMenuItem::show_all(None),
&PredefinedMenuItem::maximize(None),
&PredefinedMenuItem::minimize(None),
&PredefinedMenuItem::close_window(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::quit(None),
])
.unwrap();
#[cfg(target_os = "windows")]
{
use tao::platform::windows::WindowExtWindows;
menu.init_for_hwnd(window.hwnd());
}
let edit_menu = Submenu::new("Window", true);
edit_menu
.append_items(&[
&PredefinedMenuItem::undo(None),
&PredefinedMenuItem::redo(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::cut(None),
&PredefinedMenuItem::copy(None),
&PredefinedMenuItem::paste(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::select_all(None),
])
.unwrap();
#[cfg(target_os = "linux")]
{
use tao::platform::unix::WindowExtUnix;
menu.init_for_gtk_window(window, window.default_vbox())
.unwrap();
}
menu.append_items(&[&window_menu, &edit_menu]).unwrap();
#[cfg(target_os = "macos")]
{
use tao::platform::macos::WindowExtMacOS;
menu.init_for_nsapp();
}
if default {
// 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 window_menu = Submenu::new("Window", true);
window_menu
.append_items(&[
&PredefinedMenuItem::fullscreen(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::hide(None),
&PredefinedMenuItem::hide_others(None),
&PredefinedMenuItem::show_all(None),
&PredefinedMenuItem::maximize(None),
&PredefinedMenuItem::minimize(None),
&PredefinedMenuItem::close_window(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::quit(None),
])
.unwrap();
let edit_menu = Submenu::new("Window", true);
edit_menu
.append_items(&[
&PredefinedMenuItem::undo(None),
&PredefinedMenuItem::redo(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::cut(None),
&PredefinedMenuItem::copy(None),
&PredefinedMenuItem::paste(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::select_all(None),
])
.unwrap();
let help_menu = Submenu::new("Help", true);
help_menu
.append_items(&[&MenuItem::new("Toggle Developer Tools", true, None)])
.unwrap();
menu.append_items(&[&window_menu, &edit_menu, &help_menu])
.unwrap();
#[cfg(target_os = "macos")]
{
window_menu.set_as_windows_menu_for_nsapp();
help_menu.set_as_help_menu_for_nsapp();
}
}
menu
}
+21 -15
View File
@@ -11,7 +11,7 @@ use crate::{
use dioxus_core::VirtualDom;
use dioxus_html::prelude::EvalProvider;
use futures_util::{pin_mut, FutureExt};
use std::{rc::Rc, task::Waker};
use std::{any::Any, rc::Rc, task::Waker};
use wry::{RequestAsyncResponder, WebContext, WebViewBuilder};
pub struct WebviewInstance {
@@ -22,16 +22,19 @@ pub struct WebviewInstance {
// Wry assumes the webcontext is alive for the lifetime of the webview.
// We need to keep the webcontext alive, otherwise the webview will crash
_web_context: WebContext,
// Same with the menu.
// Currently it's a box<dyn any> because 1) we don't touch it and 2) we support a number of platforms
// like ios where muda does not give us a menu type. It sucks but alas.
//
// This would be a good thing for someone looking to contribute to fix.
_menu: Option<Box<dyn Any>>,
}
impl WebviewInstance {
pub fn new(mut cfg: Config, dom: VirtualDom, shared: Rc<SharedContext>) -> WebviewInstance {
let window = cfg.window.clone().build(&shared.target).unwrap();
// TODO: allow users to specify their own menubars, again :/
#[cfg(not(any(target_os = "android", target_os = "ios")))]
crate::menubar::build_menu(&window, cfg.enable_default_menu_bar);
// 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(
@@ -100,14 +103,6 @@ impl WebviewInstance {
webview = webview.with_file_drop_handler(move |evt| handler(window_id, evt))
}
// This was removed from wry, I'm not sure what replaced it
// #[cfg(windows)]
// {
// // Windows has a platform specific settings to disable the browser shortcut keys
// use wry::WebViewBuilderExtWindows;
// webview = webview.with_browser_accelerator_keys(false);
// }
if let Some(color) = cfg.background_color {
webview = webview.with_background_color(color);
}
@@ -136,8 +131,17 @@ impl WebviewInstance {
webview = webview.with_devtools(true);
}
let webview = webview.build().unwrap();
// TODO: allow users to specify their own menubars, again :/
let menu = if cfg!(not(any(target_os = "android", target_os = "ios"))) {
crate::menubar::build_menu(&window, cfg.enable_default_menu_bar)
} else {
None
};
let desktop_context = Rc::from(DesktopService::new(
webview.build().unwrap(),
webview,
window,
shared.clone(),
edit_queue,
@@ -149,15 +153,17 @@ impl WebviewInstance {
// Also set up its eval provider
// It's important that we provide as dyn EvalProvider - using the concrete type has
// a different TypeId.
// a different TypeId and can not be downcasted as dyn EvalProvider
let provider: Rc<dyn EvalProvider> =
Rc::new(DesktopEvalProvider::new(desktop_context.clone()));
dom.base_scope().provide_context(provider);
WebviewInstance {
waker: tao_waker(shared.proxy.clone(), desktop_context.window.id()),
desktop_context,
dom,
_menu: menu,
_web_context: web_context,
}
}