Fix muda segfault
This commit is contained in:
4 files changed
+128
-103
No files matched your search
@@ -55,7 +55,6 @@ impl Config {
|
||||
);
|
||||
|
||||
Self {
|
||||
// event_handler: None,
|
||||
window,
|
||||
protocols: Vec::new(),
|
||||
file_drop_handler: None,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user