diff --git a/src/app.rs b/src/app.rs index e5617337..32fc1b23 100644 --- a/src/app.rs +++ b/src/app.rs @@ -30,6 +30,7 @@ pub enum AppEvent { pub(crate) enum UserEvent { AppUpdate, Idle, + QuitApp, } pub(crate) enum AppUpdateEvent { @@ -145,3 +146,9 @@ impl Application { } } } + +pub fn quit_app() { + Application::with_event_loop_proxy(|proxy| { + let _ = proxy.send_event(UserEvent::QuitApp); + }); +} diff --git a/src/app_handle.rs b/src/app_handle.rs index ffe4b660..5ba5f321 100644 --- a/src/app_handle.rs +++ b/src/app_handle.rs @@ -43,6 +43,9 @@ impl ApplicationHandle { UserEvent::Idle => { self.idle(); } + UserEvent::QuitApp => { + control_flow.set_exit(); + } } } @@ -61,7 +64,7 @@ impl ApplicationHandle { self.new_window(event_loop, view_fn, config) } AppUpdateEvent::CloseWindow { window_id } => { - self.close_window(window_id); + self.close_window(window_id, control_flow); } AppUpdateEvent::RequestTimer { timer } => { self.request_timer(timer, control_flow); @@ -85,8 +88,7 @@ impl ApplicationHandle { &mut self, window_id: winit::window::WindowId, event: WindowEvent, - #[cfg(target_os = "macos")] _control_flow: &mut ControlFlow, - #[cfg(not(target_os = "macos"))] control_flow: &mut ControlFlow, + control_flow: &mut ControlFlow, ) { let window_handle = match self.window_handles.get_mut(&window_id) { Some(window_handle) => window_handle, @@ -106,15 +108,10 @@ impl ApplicationHandle { window_handle.position(point); } WindowEvent::CloseRequested => { - window_handle.window = None; + self.close_window(window_id, control_flow); } WindowEvent::Destroyed => { - window_handle.destroy(); - self.window_handles.remove(&window_id); - #[cfg(not(target_os = "macos"))] - if self.window_handles.is_empty() { - control_flow.set_exit(); - } + self.close_window(window_id, control_flow); } WindowEvent::DroppedFile(_) => {} WindowEvent::HoveredFile(_) => {} @@ -208,9 +205,20 @@ impl ApplicationHandle { self.window_handles.insert(window_id, window_handle); } - fn close_window(&mut self, window_id: WindowId) { + fn close_window( + &mut self, + window_id: WindowId, + #[cfg(target_os = "macos")] _control_flow: &mut ControlFlow, + #[cfg(not(target_os = "macos"))] control_flow: &mut ControlFlow, + ) { if let Some(handle) = self.window_handles.get_mut(&window_id) { handle.window = None; + handle.destroy(); + } + self.window_handles.remove(&window_id); + #[cfg(not(target_os = "macos"))] + if self.window_handles.is_empty() { + control_flow.set_exit(); } } diff --git a/src/lib.rs b/src/lib.rs index 27699a3e..1b5412c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,7 +111,7 @@ pub mod views; pub mod window; mod window_handle; -pub use app::{launch, AppEvent, Application}; +pub use app::{launch, quit_app, AppEvent, Application}; pub use context::ViewContext; pub use floem_reactive as reactive; pub use floem_renderer::cosmic_text; diff --git a/src/window_handle.rs b/src/window_handle.rs index f865a979..a57ff2d4 100644 --- a/src/window_handle.rs +++ b/src/window_handle.rs @@ -1,7 +1,4 @@ -use std::{ - sync::Arc, - time::{Duration, Instant}, -}; +use std::time::{Duration, Instant}; use floem_reactive::{with_scope, RwSignal, Scope}; use floem_renderer::Renderer; @@ -45,7 +42,7 @@ use crate::{ /// - processing all requests to update the animation state from the reactive system /// - requesting a new animation frame from the backend pub(crate) struct WindowHandle { - pub(crate) window: Option>, + pub(crate) window: Option, /// Reactive Scope for this WindowHandle scope: Scope, pub(crate) view: Box, @@ -66,7 +63,6 @@ impl WindowHandle { window: winit::window::Window, view_fn: impl FnOnce(winit::window::WindowId) -> Box + 'static, ) -> Self { - let window = Arc::new(window); let window_id = window.id(); let id = Id::next(); set_current_view(id); @@ -892,8 +888,9 @@ impl WindowHandle { #[cfg(target_os = "linux")] fn show_context_menu(&self, menu: Menu, _platform_menu: winit::menu::Menu, pos: Option) { - self.context_menu - .set(Some((menu, pos.unwrap_or(self.cursor_position)))); + let pos = pos.unwrap_or(self.cursor_position); + let pos = Point::new(pos.x / self.app_state.scale, pos.y / self.app_state.scale); + self.context_menu.set(Some((menu, pos))); } pub(crate) fn menu_action(&mut self, id: usize) {