Merge pull request #945 from ProfXwing/return-context
make new_window return desktop context instead of webview
This commit is contained in:
4 files changed
+41
-32
No files matched your search
@@ -51,10 +51,9 @@ pub(crate) type WebviewQueue = Rc<RefCell<Vec<WebviewHandler>>>;
|
|||||||
/// ```rust, ignore
|
/// ```rust, ignore
|
||||||
/// let desktop = cx.consume_context::<DesktopContext>().unwrap();
|
/// let desktop = cx.consume_context::<DesktopContext>().unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone)]
|
pub struct DesktopService {
|
||||||
pub struct DesktopContext {
|
|
||||||
/// The wry/tao proxy to the current window
|
/// The wry/tao proxy to the current window
|
||||||
pub webview: Rc<WebView>,
|
pub webview: WebView,
|
||||||
|
|
||||||
/// The proxy to the event loop
|
/// The proxy to the event loop
|
||||||
pub proxy: ProxyType,
|
pub proxy: ProxyType,
|
||||||
@@ -74,8 +73,10 @@ pub struct DesktopContext {
|
|||||||
pub(crate) views: Rc<RefCell<Vec<*mut objc::runtime::Object>>>,
|
pub(crate) views: Rc<RefCell<Vec<*mut objc::runtime::Object>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type DesktopContext = Rc<DesktopService>;
|
||||||
|
|
||||||
/// A smart pointer to the current window.
|
/// A smart pointer to the current window.
|
||||||
impl std::ops::Deref for DesktopContext {
|
impl std::ops::Deref for DesktopService {
|
||||||
type Target = Window;
|
type Target = Window;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@@ -83,9 +84,9 @@ impl std::ops::Deref for DesktopContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DesktopContext {
|
impl DesktopService {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
webview: Rc<WebView>,
|
webview: WebView,
|
||||||
proxy: ProxyType,
|
proxy: ProxyType,
|
||||||
event_loop: EventLoopWindowTarget<UserWindowEvent>,
|
event_loop: EventLoopWindowTarget<UserWindowEvent>,
|
||||||
webviews: WebviewQueue,
|
webviews: WebviewQueue,
|
||||||
@@ -112,7 +113,7 @@ impl DesktopContext {
|
|||||||
/// You can use this to control other windows from the current window.
|
/// You can use this to control other windows from the current window.
|
||||||
///
|
///
|
||||||
/// Be careful to not create a cycle of windows, or you might leak memory.
|
/// Be careful to not create a cycle of windows, or you might leak memory.
|
||||||
pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak<WebView> {
|
pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak<DesktopService> {
|
||||||
let window = create_new_window(
|
let window = create_new_window(
|
||||||
cfg,
|
cfg,
|
||||||
&self.event_loop,
|
&self.event_loop,
|
||||||
@@ -123,7 +124,13 @@ impl DesktopContext {
|
|||||||
self.shortcut_manager.clone(),
|
self.shortcut_manager.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let id = window.webview.window().id();
|
let desktop_context = window
|
||||||
|
.dom
|
||||||
|
.base_scope()
|
||||||
|
.consume_context::<Rc<DesktopService>>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id = window.desktop_context.webview.window().id();
|
||||||
|
|
||||||
self.proxy
|
self.proxy
|
||||||
.send_event(UserWindowEvent(EventData::NewWindow, id))
|
.send_event(UserWindowEvent(EventData::NewWindow, id))
|
||||||
@@ -133,11 +140,9 @@ impl DesktopContext {
|
|||||||
.send_event(UserWindowEvent(EventData::Poll, id))
|
.send_event(UserWindowEvent(EventData::Poll, id))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let webview = window.webview.clone();
|
|
||||||
|
|
||||||
self.pending_windows.borrow_mut().push(window);
|
self.pending_windows.borrow_mut().push(window);
|
||||||
|
|
||||||
Rc::downgrade(&webview)
|
Rc::downgrade(&desktop_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// trigger the drag-window event
|
/// trigger the drag-window event
|
||||||
@@ -405,7 +410,7 @@ pub fn use_wry_event_handler(
|
|||||||
let id = desktop.create_wry_event_handler(handler);
|
let id = desktop.create_wry_event_handler(handler);
|
||||||
|
|
||||||
WryEventHandler {
|
WryEventHandler {
|
||||||
handlers: desktop.event_handlers,
|
handlers: desktop.event_handlers.clone(),
|
||||||
id,
|
id,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+21
-15
@@ -19,9 +19,11 @@ mod webview;
|
|||||||
use crate::query::QueryResult;
|
use crate::query::QueryResult;
|
||||||
pub use cfg::Config;
|
pub use cfg::Config;
|
||||||
pub use desktop_context::{
|
pub use desktop_context::{
|
||||||
use_window, use_wry_event_handler, DesktopContext, WryEventHandler, WryEventHandlerId,
|
use_window, use_wry_event_handler, DesktopService, WryEventHandler, WryEventHandlerId,
|
||||||
|
};
|
||||||
|
use desktop_context::{
|
||||||
|
DesktopContext, EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers,
|
||||||
};
|
};
|
||||||
use desktop_context::{EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers};
|
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use dioxus_html::MountedData;
|
use dioxus_html::MountedData;
|
||||||
use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent};
|
use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent};
|
||||||
@@ -150,8 +152,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
|
|
||||||
let shortcut_manager = ShortcutRegistry::new(&event_loop);
|
let shortcut_manager = ShortcutRegistry::new(&event_loop);
|
||||||
|
|
||||||
// By default, we'll create a new window when the app starts
|
let web_view = create_new_window(
|
||||||
queue.borrow_mut().push(create_new_window(
|
|
||||||
cfg,
|
cfg,
|
||||||
&event_loop,
|
&event_loop,
|
||||||
&proxy,
|
&proxy,
|
||||||
@@ -159,7 +160,10 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
&queue,
|
&queue,
|
||||||
&event_handlers,
|
&event_handlers,
|
||||||
shortcut_manager.clone(),
|
shortcut_manager.clone(),
|
||||||
));
|
);
|
||||||
|
|
||||||
|
// By default, we'll create a new window when the app starts
|
||||||
|
queue.borrow_mut().push(web_view);
|
||||||
|
|
||||||
event_loop.run(move |window_event, event_loop, control_flow| {
|
event_loop.run(move |window_event, event_loop, control_flow| {
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
@@ -190,7 +194,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
Event::NewEvents(StartCause::Init)
|
Event::NewEvents(StartCause::Init)
|
||||||
| Event::UserEvent(UserWindowEvent(EventData::NewWindow, _)) => {
|
| Event::UserEvent(UserWindowEvent(EventData::NewWindow, _)) => {
|
||||||
for handler in queue.borrow_mut().drain(..) {
|
for handler in queue.borrow_mut().drain(..) {
|
||||||
let id = handler.webview.window().id();
|
let id = handler.desktop_context.webview.window().id();
|
||||||
webviews.insert(id, handler);
|
webviews.insert(id, handler);
|
||||||
_ = proxy.send_event(UserWindowEvent(EventData::Poll, id));
|
_ = proxy.send_event(UserWindowEvent(EventData::Poll, id));
|
||||||
}
|
}
|
||||||
@@ -260,7 +264,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
|
|
||||||
view.dom.handle_event(&name, as_any, element, bubbles);
|
view.dom.handle_event(&name, as_any, element, bubbles);
|
||||||
|
|
||||||
send_edits(view.dom.render_immediate(), &view.webview);
|
send_edits(view.dom.render_immediate(), &view.desktop_context.webview);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the webview sends a query, we need to send it to the query manager which handles dispatching the data to the correct pending query
|
// When the webview sends a query, we need to send it to the query manager which handles dispatching the data to the correct pending query
|
||||||
@@ -282,7 +286,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
|
|
||||||
EventData::Ipc(msg) if msg.method() == "initialize" => {
|
EventData::Ipc(msg) if msg.method() == "initialize" => {
|
||||||
let view = webviews.get_mut(&event.1).unwrap();
|
let view = webviews.get_mut(&event.1).unwrap();
|
||||||
send_edits(view.dom.rebuild(), &view.webview);
|
send_edits(view.dom.rebuild(), &view.desktop_context.webview);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData::Ipc(msg) if msg.method() == "browser_open" => {
|
EventData::Ipc(msg) if msg.method() == "browser_open" => {
|
||||||
@@ -342,9 +346,8 @@ fn create_new_window(
|
|||||||
shortcut_manager: ShortcutRegistry,
|
shortcut_manager: ShortcutRegistry,
|
||||||
) -> WebviewHandler {
|
) -> WebviewHandler {
|
||||||
let (webview, web_context) = webview::build(&mut cfg, event_loop, proxy.clone());
|
let (webview, web_context) = webview::build(&mut cfg, event_loop, proxy.clone());
|
||||||
|
let desktop_context = Rc::from(DesktopService::new(
|
||||||
dom.base_scope().provide_context(DesktopContext::new(
|
webview,
|
||||||
webview.clone(),
|
|
||||||
proxy.clone(),
|
proxy.clone(),
|
||||||
event_loop.clone(),
|
event_loop.clone(),
|
||||||
queue.clone(),
|
queue.clone(),
|
||||||
@@ -352,11 +355,14 @@ fn create_new_window(
|
|||||||
shortcut_manager,
|
shortcut_manager,
|
||||||
));
|
));
|
||||||
|
|
||||||
let id = webview.window().id();
|
dom.base_scope().provide_context(desktop_context.clone());
|
||||||
|
|
||||||
|
let id = desktop_context.webview.window().id();
|
||||||
|
|
||||||
// We want to poll the virtualdom and the event loop at the same time, so the waker will be connected to both
|
// We want to poll the virtualdom and the event loop at the same time, so the waker will be connected to both
|
||||||
|
|
||||||
WebviewHandler {
|
WebviewHandler {
|
||||||
webview,
|
desktop_context,
|
||||||
dom,
|
dom,
|
||||||
waker: waker::tao_waker(proxy, id),
|
waker: waker::tao_waker(proxy, id),
|
||||||
web_context,
|
web_context,
|
||||||
@@ -365,7 +371,7 @@ fn create_new_window(
|
|||||||
|
|
||||||
struct WebviewHandler {
|
struct WebviewHandler {
|
||||||
dom: VirtualDom,
|
dom: VirtualDom,
|
||||||
webview: Rc<wry::webview::WebView>,
|
desktop_context: DesktopContext,
|
||||||
waker: Waker,
|
waker: Waker,
|
||||||
// This is nessisary because of a bug in wry. Wry assumes the webcontext is alive for the lifetime of the webview. We need to keep the webcontext alive, otherwise the webview will crash
|
// This is nessisary because of a bug in wry. Wry assumes the webcontext is alive for the lifetime of the webview. We need to keep the webcontext alive, otherwise the webview will crash
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -391,7 +397,7 @@ fn poll_vdom(view: &mut WebviewHandler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_edits(view.dom.render_immediate(), &view.webview);
|
send_edits(view.dom.render_immediate(), &view.desktop_context.webview);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use wry::application::{
|
|||||||
keyboard::{KeyCode, ModifiersState},
|
keyboard::{KeyCode, ModifiersState},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{use_window, DesktopContext};
|
use crate::{desktop_context::DesktopContext, use_window};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct ShortcutRegistry {
|
pub(crate) struct ShortcutRegistry {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use crate::desktop_context::EventData;
|
use crate::desktop_context::EventData;
|
||||||
use crate::protocol;
|
use crate::protocol;
|
||||||
use crate::{desktop_context::UserWindowEvent, Config};
|
use crate::{desktop_context::UserWindowEvent, Config};
|
||||||
@@ -13,7 +11,7 @@ pub fn build(
|
|||||||
cfg: &mut Config,
|
cfg: &mut Config,
|
||||||
event_loop: &EventLoopWindowTarget<UserWindowEvent>,
|
event_loop: &EventLoopWindowTarget<UserWindowEvent>,
|
||||||
proxy: EventLoopProxy<UserWindowEvent>,
|
proxy: EventLoopProxy<UserWindowEvent>,
|
||||||
) -> (Rc<WebView>, WebContext) {
|
) -> (WebView, WebContext) {
|
||||||
let builder = cfg.window.clone();
|
let builder = cfg.window.clone();
|
||||||
let window = builder.build(event_loop).unwrap();
|
let window = builder.build(event_loop).unwrap();
|
||||||
let file_handler = cfg.file_drop_handler.take();
|
let file_handler = cfg.file_drop_handler.take();
|
||||||
@@ -96,5 +94,5 @@ pub fn build(
|
|||||||
webview = webview.with_devtools(true);
|
webview = webview.with_devtools(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
(Rc::new(webview.build().unwrap()), web_context)
|
(webview.build().unwrap(), web_context)
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user