diff --git a/src/app.rs b/src/app.rs index dba0095ed..a420ae407 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,6 +2,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc}; use floem_reactive::WriteSignal; use floem_winit::{ + event::WindowEvent, event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy}, monitor::MonitorHandle, window::WindowId, @@ -80,12 +81,13 @@ pub(crate) fn add_app_update_event(event: AppUpdateEvent) { }); } -/// Floem top level application +/// Floem top level application. /// This is the entry point of the application. pub struct Application { handle: Option, event_listener: Option>, event_loop: EventLoop, + custom_window_event_listener: Option bool>> } impl Default for Application { @@ -110,6 +112,7 @@ impl Application { handle: Some(handle), event_listener: None, event_loop, + custom_window_event_listener: None, } } @@ -118,8 +121,16 @@ impl Application { self } - /// create a new window for the application, if you want multiple windows, - /// just chain more window method to the builder + /// Can be used to hook window events before they are handled by floem. Must return `true` if + /// the event was handled and the native floem event handling is not desired, or `false` to let + /// floem handle the event normally. + pub fn on_window_event(mut self, handle_event: impl Fn(&WindowEvent) -> bool + 'static) -> Self { + self.custom_window_event_listener = Some(Box::new(handle_event)); + self + } + + /// Create a new window for the application. If you want multiple windows, just chain more + /// `window()` methods to the builder. pub fn window( mut self, app_view: impl FnOnce(WindowId) -> V + 'static, @@ -143,7 +154,13 @@ impl Application { match event { floem_winit::event::Event::NewEvents(_) => {} floem_winit::event::Event::WindowEvent { window_id, event } => { - handle.handle_window_event(window_id, event, event_loop); + let custom_handled = self.custom_window_event_listener + .as_ref() + .map(|handle_event| handle_event(&event)) + .unwrap_or(false); + if !custom_handled { + handle.handle_window_event(window_id, event, event_loop); + } } floem_winit::event::Event::DeviceEvent { .. } => {} floem_winit::event::Event::UserEvent(event) => {