Add support for user-provided event loops & event handlers (#3180)
* added support for custom event loop * added support for custom event callbacks
This commit is contained in:
1 parent
e7e624f05e
commit
1370bce182
3 files changed
+42
-4
No files matched your search
@@ -53,8 +53,11 @@ pub(crate) struct SharedContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(cfg: Config, virtual_dom: VirtualDom) -> (EventLoop<UserWindowEvent>, Self) {
|
pub fn new(mut cfg: Config, virtual_dom: VirtualDom) -> (EventLoop<UserWindowEvent>, Self) {
|
||||||
let event_loop = EventLoopBuilder::<UserWindowEvent>::with_user_event().build();
|
let event_loop = cfg
|
||||||
|
.event_loop
|
||||||
|
.take()
|
||||||
|
.unwrap_or_else(|| EventLoopBuilder::<UserWindowEvent>::with_user_event().build());
|
||||||
|
|
||||||
let app = Self {
|
let app = Self {
|
||||||
window_behavior: cfg.last_window_close_behavior,
|
window_behavior: cfg.last_window_close_behavior,
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
use dioxus_core::LaunchConfig;
|
use dioxus_core::LaunchConfig;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use tao::event_loop::{EventLoop, EventLoopWindowTarget};
|
||||||
use tao::window::{Icon, WindowBuilder};
|
use tao::window::{Icon, WindowBuilder};
|
||||||
use wry::http::{Request as HttpRequest, Response as HttpResponse};
|
use wry::http::{Request as HttpRequest, Response as HttpResponse};
|
||||||
use wry::RequestAsyncResponder;
|
use wry::RequestAsyncResponder;
|
||||||
|
|
||||||
|
use crate::ipc::UserWindowEvent;
|
||||||
use crate::menubar::{default_menu_bar, DioxusMenu};
|
use crate::menubar::{default_menu_bar, DioxusMenu};
|
||||||
|
|
||||||
|
type CustomEventHandler = Box<
|
||||||
|
dyn 'static
|
||||||
|
+ for<'a> FnMut(
|
||||||
|
&tao::event::Event<'a, UserWindowEvent>,
|
||||||
|
&EventLoopWindowTarget<UserWindowEvent>,
|
||||||
|
),
|
||||||
|
>;
|
||||||
|
|
||||||
/// The behaviour of the application when the last window is closed.
|
/// The behaviour of the application when the last window is closed.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
@@ -37,6 +47,7 @@ impl From<MenuBuilderState> for Option<DioxusMenu> {
|
|||||||
|
|
||||||
/// The configuration for the desktop application.
|
/// The configuration for the desktop application.
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
pub(crate) event_loop: Option<EventLoop<UserWindowEvent>>,
|
||||||
pub(crate) window: WindowBuilder,
|
pub(crate) window: WindowBuilder,
|
||||||
pub(crate) menu: MenuBuilderState,
|
pub(crate) menu: MenuBuilderState,
|
||||||
pub(crate) protocols: Vec<WryProtocol>,
|
pub(crate) protocols: Vec<WryProtocol>,
|
||||||
@@ -50,6 +61,7 @@ pub struct Config {
|
|||||||
pub(crate) root_name: String,
|
pub(crate) root_name: String,
|
||||||
pub(crate) background_color: Option<(u8, u8, u8, u8)>,
|
pub(crate) background_color: Option<(u8, u8, u8, u8)>,
|
||||||
pub(crate) last_window_close_behavior: WindowCloseBehaviour,
|
pub(crate) last_window_close_behavior: WindowCloseBehaviour,
|
||||||
|
pub(crate) custom_event_handler: Option<CustomEventHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LaunchConfig for Config {}
|
impl LaunchConfig for Config {}
|
||||||
@@ -80,6 +92,7 @@ impl Config {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
window,
|
window,
|
||||||
|
event_loop: None,
|
||||||
menu: MenuBuilderState::Unset,
|
menu: MenuBuilderState::Unset,
|
||||||
protocols: Vec::new(),
|
protocols: Vec::new(),
|
||||||
asynchronous_protocols: Vec::new(),
|
asynchronous_protocols: Vec::new(),
|
||||||
@@ -92,6 +105,7 @@ impl Config {
|
|||||||
root_name: "main".to_string(),
|
root_name: "main".to_string(),
|
||||||
background_color: None,
|
background_color: None,
|
||||||
last_window_close_behavior: WindowCloseBehaviour::LastWindowExitsApp,
|
last_window_close_behavior: WindowCloseBehaviour::LastWindowExitsApp,
|
||||||
|
custom_event_handler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +135,12 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the event loop to be used
|
||||||
|
pub fn with_event_loop(mut self, event_loop: EventLoop<UserWindowEvent>) -> Self {
|
||||||
|
self.event_loop = Some(event_loop);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the configuration for the window.
|
/// Set the configuration for the window.
|
||||||
pub fn with_window(mut self, window: WindowBuilder) -> Self {
|
pub fn with_window(mut self, window: WindowBuilder) -> Self {
|
||||||
// We need to do a swap because the window builder only takes itself as muy self
|
// We need to do a swap because the window builder only takes itself as muy self
|
||||||
@@ -138,6 +158,16 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets a custom callback to run whenever the event pool receives an event.
|
||||||
|
pub fn with_custom_event_handler(
|
||||||
|
mut self,
|
||||||
|
f: impl FnMut(&tao::event::Event<'_, UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>)
|
||||||
|
+ 'static,
|
||||||
|
) -> Self {
|
||||||
|
self.custom_event_handler = Some(Box::new(f));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a custom protocol
|
/// Set a custom protocol
|
||||||
pub fn with_custom_protocol<F>(mut self, name: impl ToString, handler: F) -> Self
|
pub fn with_custom_protocol<F>(mut self, name: impl ToString, handler: F) -> Self
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -12,13 +12,18 @@ use tao::event::{Event, StartCause, WindowEvent};
|
|||||||
///
|
///
|
||||||
/// This will block the main thread, and *must* be spawned on the main thread. This function does not assume any runtime
|
/// This will block the main thread, and *must* be spawned on the main thread. This function does not assume any runtime
|
||||||
/// and is equivalent to calling launch_with_props with the tokio feature disabled.
|
/// and is equivalent to calling launch_with_props with the tokio feature disabled.
|
||||||
pub fn launch_virtual_dom_blocking(virtual_dom: VirtualDom, desktop_config: Config) -> ! {
|
pub fn launch_virtual_dom_blocking(virtual_dom: VirtualDom, mut desktop_config: Config) -> ! {
|
||||||
|
let mut custom_event_handler = desktop_config.custom_event_handler.take();
|
||||||
let (event_loop, mut app) = App::new(desktop_config, virtual_dom);
|
let (event_loop, mut app) = App::new(desktop_config, virtual_dom);
|
||||||
|
|
||||||
event_loop.run(move |window_event, _, control_flow| {
|
event_loop.run(move |window_event, event_loop, control_flow| {
|
||||||
// Set the control flow and check if any events need to be handled in the app itself
|
// Set the control flow and check if any events need to be handled in the app itself
|
||||||
app.tick(&window_event);
|
app.tick(&window_event);
|
||||||
|
|
||||||
|
if let Some(ref mut f) = custom_event_handler {
|
||||||
|
f(&window_event, event_loop)
|
||||||
|
}
|
||||||
|
|
||||||
match window_event {
|
match window_event {
|
||||||
Event::NewEvents(StartCause::Init) => app.handle_start_cause_init(),
|
Event::NewEvents(StartCause::Init) => app.handle_start_cause_init(),
|
||||||
Event::LoopDestroyed => app.handle_loop_destroyed(),
|
Event::LoopDestroyed => app.handle_loop_destroyed(),
|
||||||
|
|||||||
Reference in new issue
Block a user