mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-02 06:40:06 -04:00
Avoid leaking Windows by storing Weak pointers in EventsLoop
This commit is contained in:
@@ -6,7 +6,7 @@ use std;
|
|||||||
|
|
||||||
|
|
||||||
pub struct EventsLoop {
|
pub struct EventsLoop {
|
||||||
pub windows: std::sync::Mutex<Vec<std::sync::Arc<Window>>>,
|
pub windows: std::sync::Mutex<Vec<std::sync::Weak<Window>>>,
|
||||||
pub pending_events: std::sync::Mutex<std::collections::VecDeque<Event>>,
|
pub pending_events: std::sync::Mutex<std::collections::VecDeque<Event>>,
|
||||||
modifiers: std::sync::Mutex<Modifiers>,
|
modifiers: std::sync::Mutex<Modifiers>,
|
||||||
interrupted: std::sync::atomic::AtomicBool,
|
interrupted: std::sync::atomic::AtomicBool,
|
||||||
@@ -236,8 +236,6 @@ impl EventsLoop {
|
|||||||
let event_type = ns_event.eventType();
|
let event_type = ns_event.eventType();
|
||||||
let ns_window = ns_event.window();
|
let ns_window = ns_event.window();
|
||||||
let window_id = super::window::get_window_id(ns_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.
|
// 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.
|
// 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),
|
_ => 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 {
|
let into_event = |window_event| Event::WindowEvent {
|
||||||
window_id: ::WindowId(window_id),
|
window_id: ::WindowId(window_id),
|
||||||
event: window_event,
|
event: window_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns `Some` window if one of our windows is the key window.
|
// Returns `Some` window if one of our windows is the key window.
|
||||||
let maybe_key_window = || windows.iter().find(|window| {
|
let maybe_key_window = || windows.iter()
|
||||||
let is_key_window: cocoa::base::BOOL = msg_send![*window.window, isKeyWindow];
|
.filter_map(std::sync::Weak::upgrade)
|
||||||
is_key_window == cocoa::base::YES
|
.find(|window| {
|
||||||
});
|
let is_key_window: cocoa::base::BOOL = msg_send![*window.window, isKeyWindow];
|
||||||
|
is_key_window == cocoa::base::YES
|
||||||
|
});
|
||||||
|
|
||||||
match event_type {
|
match event_type {
|
||||||
|
|
||||||
@@ -586,4 +591,4 @@ fn event_mods(event: cocoa::base::id) -> ModifiersState {
|
|||||||
alt: flags.contains(appkit::NSAlternateKeyMask),
|
alt: flags.contains(appkit::NSAlternateKeyMask),
|
||||||
logo: flags.contains(appkit::NSCommandKeyMask),
|
logo: flags.contains(appkit::NSCommandKeyMask),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ impl Window2 {
|
|||||||
{
|
{
|
||||||
let weak_events_loop = ::std::sync::Arc::downgrade(&events_loop);
|
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)));
|
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 })
|
Ok(Window2 { window: window })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,10 @@ impl Drop for Window {
|
|||||||
let id = self.id();
|
let id = self.id();
|
||||||
if let Some(ev) = self.delegate.state.events_loop.upgrade() {
|
if let Some(ev) = self.delegate.state.events_loop.upgrade() {
|
||||||
let mut windows = ev.windows.lock().unwrap();
|
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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user