diff --git a/src/platform/macos/events_loop.rs b/src/platform/macos/events_loop.rs index f656468e..f283a763 100644 --- a/src/platform/macos/events_loop.rs +++ b/src/platform/macos/events_loop.rs @@ -6,7 +6,7 @@ use std; pub struct EventsLoop { - pub windows: std::sync::Mutex>>, + pub windows: std::sync::Mutex>>, pub pending_events: std::sync::Mutex>, modifiers: std::sync::Mutex, interrupted: std::sync::atomic::AtomicBool, @@ -236,8 +236,6 @@ impl EventsLoop { let event_type = ns_event.eventType(); let ns_window = ns_event.window(); let window_id = super::window::get_window_id(ns_window); - let windows = self.windows.lock().unwrap(); - let maybe_window = windows.iter().find(|window| window_id == window.id()); // FIXME: Document this. Why do we do this? Seems like it passes on events to window/app. // If we don't do this, window does not become main for some reason. @@ -246,16 +244,23 @@ impl EventsLoop { _ => appkit::NSApp().sendEvent_(ns_event), } + let windows = self.windows.lock().unwrap(); + let maybe_window = windows.iter() + .filter_map(std::sync::Weak::upgrade) + .find(|window| window_id == window.id()); + let into_event = |window_event| Event::WindowEvent { window_id: ::WindowId(window_id), event: window_event, }; // Returns `Some` window if one of our windows is the key window. - let maybe_key_window = || windows.iter().find(|window| { - let is_key_window: cocoa::base::BOOL = msg_send![*window.window, isKeyWindow]; - is_key_window == cocoa::base::YES - }); + let maybe_key_window = || windows.iter() + .filter_map(std::sync::Weak::upgrade) + .find(|window| { + let is_key_window: cocoa::base::BOOL = msg_send![*window.window, isKeyWindow]; + is_key_window == cocoa::base::YES + }); match event_type { @@ -586,4 +591,4 @@ fn event_mods(event: cocoa::base::id) -> ModifiersState { alt: flags.contains(appkit::NSAlternateKeyMask), logo: flags.contains(appkit::NSCommandKeyMask), } -} \ No newline at end of file +} diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index da43cb5f..086bcf0f 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -26,7 +26,8 @@ impl Window2 { { let weak_events_loop = ::std::sync::Arc::downgrade(&events_loop); let window = ::std::sync::Arc::new(try!(Window::new(weak_events_loop, attributes, pl_attribs))); - events_loop.windows.lock().unwrap().push(window.clone()); + let weak_window = ::std::sync::Arc::downgrade(&window); + events_loop.windows.lock().unwrap().push(weak_window); Ok(Window2 { window: window }) } diff --git a/src/platform/macos/window.rs b/src/platform/macos/window.rs index 09ec570d..04e17f9c 100644 --- a/src/platform/macos/window.rs +++ b/src/platform/macos/window.rs @@ -174,7 +174,10 @@ impl Drop for Window { let id = self.id(); if let Some(ev) = self.delegate.state.events_loop.upgrade() { let mut windows = ev.windows.lock().unwrap(); - windows.retain(|w| w.id() != id) + windows.retain(|w| match w.upgrade() { + Some(w) => w.id() != id, + None => true, + }) } } }