Skip to content

Commit 572a69b

Browse files
committed
x11: WindowHandle::close sync via JoinHandle
1 parent a9bb4fc commit 572a69b

File tree

2 files changed

+15
-17
lines changed

2 files changed

+15
-17
lines changed

src/x11/event_loop.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ impl EventLoop {
108108

109109
// Check if the parents's handle was dropped (such as when the host
110110
// requested the window to close)
111-
//
112-
// FIXME: This will need to be changed from just setting an atomic to somehow
113-
// synchronizing with the window being closed (using a synchronous channel, or
114-
// by joining on the event loop thread).
115111
if let Some(parent_handle) = &self.parent_handle {
116112
if parent_handle.parent_did_drop() {
117113
self.handle_must_close();

src/x11/window.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ffi::c_void;
44
use std::sync::atomic::{AtomicBool, Ordering};
55
use std::sync::mpsc;
66
use std::sync::Arc;
7-
use std::thread;
7+
use std::thread::{self, JoinHandle};
88

99
use raw_window_handle::{
1010
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, XlibDisplayHandle,
@@ -31,13 +31,17 @@ use crate::x11::visual_info::WindowVisualConfig;
3131

3232
pub struct WindowHandle {
3333
raw_window_handle: Option<RawWindowHandle>,
34-
close_requested: mpsc::SyncSender<()>,
34+
event_loop_handle: Option<JoinHandle<()>>,
35+
close_requested: Arc<AtomicBool>,
3536
is_open: Arc<AtomicBool>,
3637
}
3738

3839
impl WindowHandle {
3940
pub fn close(&mut self) {
40-
self.close_requested.send(()).ok();
41+
self.close_requested.store(true, Ordering::Relaxed);
42+
if let Some(event_loop) = self.event_loop_handle.take() {
43+
let _ = event_loop.join();
44+
}
4145
}
4246

4347
pub fn is_open(&self) -> bool {
@@ -58,26 +62,26 @@ unsafe impl HasRawWindowHandle for WindowHandle {
5862
}
5963

6064
pub(crate) struct ParentHandle {
61-
close_requested: mpsc::Receiver<()>,
65+
close_requested: Arc<AtomicBool>,
6266
is_open: Arc<AtomicBool>,
6367
}
6468

6569
impl ParentHandle {
6670
pub fn new() -> (Self, WindowHandle) {
67-
let (close_sender, close_receiver) = mpsc::sync_channel(0);
71+
let close_requested = Arc::new(AtomicBool::new(false));
6872
let is_open = Arc::new(AtomicBool::new(true));
69-
7073
let handle = WindowHandle {
7174
raw_window_handle: None,
72-
close_requested: close_sender,
75+
event_loop_handle: None,
76+
close_requested: Arc::clone(&close_requested),
7377
is_open: Arc::clone(&is_open),
7478
};
7579

76-
(Self { close_requested: close_receiver, is_open }, handle)
80+
(Self { close_requested, is_open }, handle)
7781
}
7882

7983
pub fn parent_did_drop(&self) -> bool {
80-
self.close_requested.try_recv().is_ok()
84+
self.close_requested.load(Ordering::Relaxed)
8185
}
8286
}
8387

@@ -127,17 +131,15 @@ impl<'a> Window<'a> {
127131
};
128132

129133
let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1);
130-
131134
let (parent_handle, mut window_handle) = ParentHandle::new();
132-
133-
thread::spawn(move || {
135+
let join_handle = thread::spawn(move || {
134136
Self::window_thread(Some(parent_id), options, build, tx.clone(), Some(parent_handle))
135137
.unwrap();
136138
});
137139

138140
let raw_window_handle = rx.recv().unwrap().unwrap();
139141
window_handle.raw_window_handle = Some(raw_window_handle.0);
140-
142+
window_handle.event_loop_handle = Some(join_handle);
141143
window_handle
142144
}
143145

0 commit comments

Comments
 (0)