diff --git a/src/x11/event_loop.rs b/src/x11/event_loop.rs index 6b6ecd3..53375d6 100644 --- a/src/x11/event_loop.rs +++ b/src/x11/event_loop.rs @@ -108,10 +108,6 @@ impl EventLoop { // Check if the parents's handle was dropped (such as when the host // requested the window to close) - // - // FIXME: This will need to be changed from just setting an atomic to somehow - // synchronizing with the window being closed (using a synchronous channel, or - // by joining on the event loop thread). if let Some(parent_handle) = &self.parent_handle { if parent_handle.parent_did_drop() { self.handle_must_close(); diff --git a/src/x11/window.rs b/src/x11/window.rs index ca4db3c..e556fe2 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -4,7 +4,7 @@ use std::ffi::c_void; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc; use std::sync::Arc; -use std::thread; +use std::thread::{self, JoinHandle}; use raw_window_handle::{ HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, XlibDisplayHandle, @@ -31,18 +31,16 @@ use crate::x11::visual_info::WindowVisualConfig; pub struct WindowHandle { raw_window_handle: Option, + event_loop_handle: Option>, close_requested: Arc, is_open: Arc, } impl WindowHandle { pub fn close(&mut self) { - if self.raw_window_handle.take().is_some() { - // FIXME: This will need to be changed from just setting an atomic to somehow - // synchronizing with the window being closed (using a synchronous channel, or - // by joining on the event loop thread). - - self.close_requested.store(true, Ordering::Relaxed); + self.close_requested.store(true, Ordering::Relaxed); + if let Some(event_loop) = self.event_loop_handle.take() { + let _ = event_loop.join(); } } @@ -72,9 +70,9 @@ impl ParentHandle { pub fn new() -> (Self, WindowHandle) { let close_requested = Arc::new(AtomicBool::new(false)); let is_open = Arc::new(AtomicBool::new(true)); - let handle = WindowHandle { raw_window_handle: None, + event_loop_handle: None, close_requested: Arc::clone(&close_requested), is_open: Arc::clone(&is_open), }; @@ -134,17 +132,15 @@ impl<'a> Window<'a> { }; let (tx, rx) = mpsc::sync_channel::(1); - let (parent_handle, mut window_handle) = ParentHandle::new(); - - thread::spawn(move || { + let join_handle = thread::spawn(move || { Self::window_thread(Some(parent_id), options, build, tx.clone(), Some(parent_handle)) .unwrap(); }); let raw_window_handle = rx.recv().unwrap().unwrap(); window_handle.raw_window_handle = Some(raw_window_handle.0); - + window_handle.event_loop_handle = Some(join_handle); window_handle }