mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
wayland: cleanup signal to prune dead windows
This commit is contained in:
parent
17fde48ed7
commit
3ff9eb08e8
|
@ -1,7 +1,5 @@
|
||||||
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase, ModifiersState};
|
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase, ModifiersState};
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
|
@ -54,9 +52,10 @@ impl EventsLoopSink {
|
||||||
pub struct EventsLoop {
|
pub struct EventsLoop {
|
||||||
ctxt: Arc<WaylandContext>,
|
ctxt: Arc<WaylandContext>,
|
||||||
evq: Arc<Mutex<EventQueue>>,
|
evq: Arc<Mutex<EventQueue>>,
|
||||||
decorated_ids: Mutex<Vec<(usize, WindowId)>>,
|
decorated_ids: Mutex<Vec<(usize, Arc<wl_surface::WlSurface>)>>,
|
||||||
sink: Arc<Mutex<EventsLoopSink>>,
|
sink: Arc<Mutex<EventsLoopSink>>,
|
||||||
interrupted: AtomicBool,
|
interrupted: AtomicBool,
|
||||||
|
cleanup_needed: Arc<AtomicBool>,
|
||||||
hid: usize
|
hid: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,31 +70,32 @@ impl EventsLoop {
|
||||||
decorated_ids: Mutex::new(Vec::new()),
|
decorated_ids: Mutex::new(Vec::new()),
|
||||||
sink: sink,
|
sink: sink,
|
||||||
interrupted: AtomicBool::new(false),
|
interrupted: AtomicBool::new(false),
|
||||||
|
cleanup_needed: Arc::new(AtomicBool::new(false)),
|
||||||
hid: hid
|
hid: hid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_event_queue(&self) -> Arc<Mutex<EventQueue>> {
|
pub fn get_window_init(&self) -> (Arc<Mutex<EventQueue>>, Arc<AtomicBool>) {
|
||||||
self.evq.clone()
|
(self.evq.clone(), self.cleanup_needed.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_window(&self, decorated_id: usize, surface: Arc<wl_surface::WlSurface>) {
|
pub fn register_window(&self, decorated_id: usize, surface: Arc<wl_surface::WlSurface>) {
|
||||||
self.decorated_ids.lock().unwrap().push((decorated_id, make_wid(&surface)));
|
self.decorated_ids.lock().unwrap().push((decorated_id, surface.clone()));
|
||||||
let mut guard = self.evq.lock().unwrap();
|
let mut guard = self.evq.lock().unwrap();
|
||||||
let mut state = guard.state();
|
let mut state = guard.state();
|
||||||
state.get_mut_handler::<InputHandler>(self.hid).windows.push(surface);
|
state.get_mut_handler::<InputHandler>(self.hid).windows.push(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_resize(evq: &mut EventQueue, ids: &[(usize, WindowId)], callback: &mut FnMut(::Event))
|
fn process_resize(evq: &mut EventQueue, ids: &[(usize, Arc<wl_surface::WlSurface>)], callback: &mut FnMut(::Event))
|
||||||
{
|
{
|
||||||
let mut state = evq.state();
|
let mut state = evq.state();
|
||||||
for &(decorated_id, window_id) in ids {
|
for &(decorated_id, ref window) in ids {
|
||||||
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(decorated_id);
|
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(decorated_id);
|
||||||
if let Some((w, h)) = decorated.handler().as_mut().and_then(|h| h.take_newsize()) {
|
if let Some((w, h)) = decorated.handler().as_mut().and_then(|h| h.take_newsize()) {
|
||||||
decorated.resize(w as i32, h as i32);
|
decorated.resize(w as i32, h as i32);
|
||||||
callback(
|
callback(
|
||||||
::Event::WindowEvent {
|
::Event::WindowEvent {
|
||||||
window_id: ::WindowId(::platform::WindowId::Wayland(window_id)),
|
window_id: ::WindowId(::platform::WindowId::Wayland(make_wid(&window))),
|
||||||
event: ::WindowEvent::Resized(w,h)
|
event: ::WindowEvent::Resized(w,h)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -107,7 +107,20 @@ impl EventsLoop {
|
||||||
self.interrupted.store(true, ::std::sync::atomic::Ordering::Relaxed);
|
self.interrupted.store(true, ::std::sync::atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F>(&self, mut callback: F)
|
fn prune_dead_windows(&self) {
|
||||||
|
self.decorated_ids.lock().unwrap().retain(|&(_, ref w)| w.is_alive());
|
||||||
|
let mut evq_guard = self.evq.lock().unwrap();
|
||||||
|
let mut state = evq_guard.state();
|
||||||
|
let handler = state.get_mut_handler::<InputHandler>(self.hid);
|
||||||
|
handler.windows.retain(|w| w.is_alive());
|
||||||
|
if let Some(w) = handler.mouse_focus.take() {
|
||||||
|
if w.is_alive() {
|
||||||
|
handler.mouse_focus = Some(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_events<F>(&self, callback: F)
|
||||||
where F: FnMut(::Event)
|
where F: FnMut(::Event)
|
||||||
{
|
{
|
||||||
// send pending requests to the server...
|
// send pending requests to the server...
|
||||||
|
@ -142,9 +155,12 @@ impl EventsLoop {
|
||||||
// replace the old noop callback
|
// replace the old noop callback
|
||||||
unsafe { self.sink.lock().unwrap().set_callback(old_cb) };
|
unsafe { self.sink.lock().unwrap().set_callback(old_cb) };
|
||||||
|
|
||||||
|
if self.cleanup_needed.swap(false, ::std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
self.prune_dead_windows()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_forever<F>(&self, mut callback: F)
|
pub fn run_forever<F>(&self, callback: F)
|
||||||
where F: FnMut(::Event)
|
where F: FnMut(::Event)
|
||||||
{
|
{
|
||||||
// send pending requests to the server...
|
// send pending requests to the server...
|
||||||
|
@ -171,6 +187,10 @@ impl EventsLoop {
|
||||||
|
|
||||||
// replace the old noop callback
|
// replace the old noop callback
|
||||||
unsafe { self.sink.lock().unwrap().set_callback(old_cb) };
|
unsafe { self.sink.lock().unwrap().set_callback(old_cb) };
|
||||||
|
|
||||||
|
if self.cleanup_needed.swap(false, ::std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
self.prune_dead_windows()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
use wayland_client::{EventQueue, EventQueueHandle, Proxy};
|
use wayland_client::{EventQueue, EventQueueHandle, Proxy};
|
||||||
use wayland_client::protocol::{wl_display,wl_surface,wl_shell_surface};
|
use wayland_client::protocol::{wl_display,wl_surface,wl_shell_surface};
|
||||||
|
@ -13,6 +14,7 @@ use super::wayland_window::DecoratedSurface;
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
ctxt: Arc<WaylandContext>,
|
ctxt: Arc<WaylandContext>,
|
||||||
evq: Arc<Mutex<EventQueue>>,
|
evq: Arc<Mutex<EventQueue>>,
|
||||||
|
cleanup_signal: Arc<AtomicBool>,
|
||||||
surface: Arc<wl_surface::WlSurface>,
|
surface: Arc<wl_surface::WlSurface>,
|
||||||
size: Mutex<(u32, u32)>,
|
size: Mutex<(u32, u32)>,
|
||||||
decorated_id: usize
|
decorated_id: usize
|
||||||
|
@ -34,7 +36,7 @@ impl Window {
|
||||||
let (surface, decorated) = ctxt.create_window::<DecoratedHandler>();
|
let (surface, decorated) = ctxt.create_window::<DecoratedHandler>();
|
||||||
|
|
||||||
// init DecoratedSurface
|
// init DecoratedSurface
|
||||||
let evq = evlp.get_event_queue();
|
let (evq, cleanup_signal) = evlp.get_window_init();
|
||||||
let decorated_id = {
|
let decorated_id = {
|
||||||
let mut evq_guard = evq.lock().unwrap();
|
let mut evq_guard = evq.lock().unwrap();
|
||||||
let decorated_id = evq_guard.add_handler_with_init(decorated);
|
let decorated_id = evq_guard.add_handler_with_init(decorated);
|
||||||
|
@ -62,6 +64,7 @@ impl Window {
|
||||||
let me = Window {
|
let me = Window {
|
||||||
ctxt: ctxt,
|
ctxt: ctxt,
|
||||||
evq: evq,
|
evq: evq,
|
||||||
|
cleanup_signal: cleanup_signal,
|
||||||
surface: surface,
|
surface: surface,
|
||||||
size: Mutex::new((width, height)),
|
size: Mutex::new((width, height)),
|
||||||
decorated_id: decorated_id
|
decorated_id: decorated_id
|
||||||
|
@ -165,6 +168,7 @@ impl Window {
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.surface.destroy();
|
self.surface.destroy();
|
||||||
|
self.cleanup_signal.store(true, ::std::sync::atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue