diff --git a/CHANGELOG.md b/CHANGELOG.md index 3604673613..275f204ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- On macOS, fix `WindowEvent::Destroyed` isn't emitted when the window is dropped. - On Windows and macOS, add `Window::title` to query the current window title. - On Windows, fix focusing menubar when pressing `Alt`. - On MacOS, made `accepts_first_mouse` configurable. diff --git a/src/event.rs b/src/event.rs index da237672c7..326c097a99 100644 --- a/src/event.rs +++ b/src/event.rs @@ -331,6 +331,9 @@ pub enum WindowEvent<'a> { CloseRequested, /// The window has been destroyed. + /// + /// However, it won't get emitted if the window is closed by the event loop set to exit. + /// Use [`Event::LoopDestroyed`] to check such behaviour instead. Destroyed, /// A file has been dropped into the window. diff --git a/src/platform_impl/macos/mod.rs b/src/platform_impl/macos/mod.rs index f4b585db9b..404aba2f4c 100644 --- a/src/platform_impl/macos/mod.rs +++ b/src/platform_impl/macos/mod.rs @@ -51,13 +51,13 @@ pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId); pub(crate) struct Window { pub(crate) window: Id, // We keep this around so that it doesn't get dropped until the window does. - _delegate: Id, + pub(crate) delegate: Id, } impl Drop for Window { fn drop(&mut self) { // Ensure the window is closed - util::close_async(Id::into_super(self.window.clone())); + util::close_async(self.delegate.clone()); } } @@ -84,8 +84,8 @@ impl Window { attributes: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { - let (window, _delegate) = autoreleasepool(|_| WinitWindow::new(attributes, pl_attribs))?; - Ok(Window { window, _delegate }) + let (window, delegate) = autoreleasepool(|_| WinitWindow::new(attributes, pl_attribs))?; + Ok(Window { window, delegate }) } } diff --git a/src/platform_impl/macos/util/async.rs b/src/platform_impl/macos/util/async.rs index 59f8e2ed54..50212720b4 100644 --- a/src/platform_impl/macos/util/async.rs +++ b/src/platform_impl/macos/util/async.rs @@ -6,6 +6,7 @@ use dispatch::Queue; use objc2::foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString}; use objc2::rc::{autoreleasepool, Id, Shared}; +use crate::platform_impl::platform::window_delegate::WinitWindowDelegate; use crate::{ dpi::LogicalSize, platform_impl::platform::{ @@ -218,11 +219,11 @@ pub(crate) fn set_title_async(window: &NSWindow, title: String) { // // ArturKovacs: It's important that this operation keeps the underlying window alive // through the `Id` because otherwise it would dereference free'd memory -pub(crate) fn close_async(window: Id) { - let window = MainThreadSafe(window); +pub(crate) fn close_async(delegate: Id) { + let delegate = MainThreadSafe(delegate); Queue::main().exec_async(move || { autoreleasepool(move |_| { - window.close(); + delegate.window.close(); }); }); } diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index e328e59c0a..ef46d5c65d 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -25,7 +25,7 @@ use crate::{ declare_class!( #[derive(Debug)] pub(crate) struct WinitWindowDelegate { - window: IvarDrop>, + pub(crate) window: IvarDrop>, // TODO: It's possible for delegate methods to be called asynchronously, // causing data races / `RefCell` panics.