From 1a65dd680afe2ebd8b121f259fbec3eb80d3cbc7 Mon Sep 17 00:00:00 2001 From: Raphael Amorim Date: Tue, 24 Sep 2024 09:56:41 +0200 Subject: [PATCH] confirm before quit on macos --- frontends/rioterm/src/application.rs | 4 +++- rio-window/src/event_loop.rs | 10 ++++++++++ rio-window/src/platform_impl/macos/app_delegate.rs | 13 ++++++++++++- rio-window/src/platform_impl/macos/event_loop.rs | 4 ++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/frontends/rioterm/src/application.rs b/frontends/rioterm/src/application.rs index 108a09f58d..38052076b9 100644 --- a/frontends/rioterm/src/application.rs +++ b/frontends/rioterm/src/application.rs @@ -55,9 +55,11 @@ impl Application<'_> { event_proxy.clone(), ); let scheduler = Scheduler::new(proxy); - event_loop.listen_device_events(DeviceEvents::Never); + #[cfg(target_os = "macos")] + event_loop.set_confirm_before_quit(config.confirm_before_quit); + Application { config, event_proxy, diff --git a/rio-window/src/event_loop.rs b/rio-window/src/event_loop.rs index 610b2a88fd..ea4eeba6d6 100644 --- a/rio-window/src/event_loop.rs +++ b/rio-window/src/event_loop.rs @@ -308,6 +308,16 @@ impl EventLoop { .listen_device_events(allowed); } + #[inline] + #[cfg(target_os = "macos")] + pub fn set_confirm_before_quit(&self, confirmation: bool) { + let _span = + tracing::debug_span!("rio_window::EventLoop::set_confirm_before_quit") + .entered(); + + self.event_loop.set_confirm_before_quit(confirmation) + } + /// Sets the [`ControlFlow`]. pub fn set_control_flow(&self, control_flow: ControlFlow) { self.event_loop diff --git a/rio-window/src/platform_impl/macos/app_delegate.rs b/rio-window/src/platform_impl/macos/app_delegate.rs index 97ec9b69d8..23f9485b0a 100644 --- a/rio-window/src/platform_impl/macos/app_delegate.rs +++ b/rio-window/src/platform_impl/macos/app_delegate.rs @@ -51,6 +51,7 @@ impl Default for Policy { pub(super) struct State { activation_policy: Policy, default_menu: bool, + set_confirm_before_quit: Cell, activate_ignoring_other_apps: bool, event_handler: EventHandler, stop_on_launch: Cell, @@ -92,6 +93,10 @@ declare_class!( unsafe impl NSApplicationDelegate for ApplicationDelegate { #[method(applicationShouldTerminate:)] fn should_terminate(&self, _sender: Option<&AnyObject>) -> u64 { + if !self.ivars().set_confirm_before_quit.get() { + return NSApplicationTerminateReply::Now as u64; + } + use objc::runtime::Object; use objc::msg_send; use objc::sel; @@ -349,6 +354,12 @@ impl ApplicationDelegate { self.ivars().event_handler.set(handler, closure) } + /// Place the event handler in the application delegate for the duration + /// of the given closure. + pub fn set_confirm_before_quit(&self, confirmation: bool) { + self.ivars().set_confirm_before_quit.set(confirmation) + } + /// If `pump_events` is called to progress the event loop then we /// bootstrap the event loop via `-[NSApplication run]` but will use /// `CFRunLoopRunInMode` for subsequent calls to `pump_events`. @@ -677,4 +688,4 @@ fn min_timeout(a: Option, b: Option) -> Option { a.map_or(b, |a_timeout| { b.map_or(Some(a_timeout), |b_timeout| Some(a_timeout.min(b_timeout))) }) -} \ No newline at end of file +} diff --git a/rio-window/src/platform_impl/macos/event_loop.rs b/rio-window/src/platform_impl/macos/event_loop.rs index 767f01e970..0cfeff6276 100644 --- a/rio-window/src/platform_impl/macos/event_loop.rs +++ b/rio-window/src/platform_impl/macos/event_loop.rs @@ -274,6 +274,10 @@ impl EventLoop { &self.window_target } + pub fn set_confirm_before_quit(&self, confirmation: bool) { + self.delegate.set_confirm_before_quit(confirmation); + } + pub fn run(mut self, handler: F) -> Result<(), EventLoopError> where F: FnMut(Event, &RootWindowTarget),