mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 14:51:30 +11:00
Merge pull request #568 from paulrouget/x11-crasher
Fix a rare crash in some X11 implementations
This commit is contained in:
commit
691bac6528
|
@ -38,6 +38,13 @@ fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) ->
|
||||||
f(c_str.as_ptr())
|
f(c_str.as_ptr())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WindowProxyData {
|
||||||
|
display: Arc<XConnection>,
|
||||||
|
window: ffi::Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for WindowProxyData {}
|
||||||
|
|
||||||
pub struct XWindow {
|
pub struct XWindow {
|
||||||
display: Arc<XConnection>,
|
display: Arc<XConnection>,
|
||||||
window: ffi::Window,
|
window: ffi::Window,
|
||||||
|
@ -48,6 +55,7 @@ pub struct XWindow {
|
||||||
ic: ffi::XIC,
|
ic: ffi::XIC,
|
||||||
im: ffi::XIM,
|
im: ffi::XIM,
|
||||||
colormap: ffi::Colormap,
|
colormap: ffi::Colormap,
|
||||||
|
window_proxy_data: Arc<Mutex<Option<WindowProxyData>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Context {
|
pub enum Context {
|
||||||
|
@ -65,6 +73,10 @@ unsafe impl Sync for Window {}
|
||||||
impl Drop for XWindow {
|
impl Drop for XWindow {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Clear out the window proxy data arc, so that any window proxy objects
|
||||||
|
// are no longer able to send messages to this window.
|
||||||
|
*self.window_proxy_data.lock().unwrap() = None;
|
||||||
|
|
||||||
// we don't call MakeCurrent(0, 0) because we are not sure that the context
|
// we don't call MakeCurrent(0, 0) because we are not sure that the context
|
||||||
// is still the current one
|
// is still the current one
|
||||||
self.context = Context::None;
|
self.context = Context::None;
|
||||||
|
@ -86,25 +98,29 @@ impl Drop for XWindow {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WindowProxy {
|
pub struct WindowProxy {
|
||||||
x: Arc<XWindow>,
|
data: Arc<Mutex<Option<WindowProxyData>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowProxy {
|
impl WindowProxy {
|
||||||
pub fn wakeup_event_loop(&self) {
|
pub fn wakeup_event_loop(&self) {
|
||||||
let mut xev = ffi::XClientMessageEvent {
|
let window_proxy_data = self.data.lock().unwrap();
|
||||||
type_: ffi::ClientMessage,
|
|
||||||
window: self.x.window,
|
|
||||||
format: 32,
|
|
||||||
message_type: 0,
|
|
||||||
serial: 0,
|
|
||||||
send_event: 0,
|
|
||||||
display: self.x.display.display,
|
|
||||||
data: unsafe { mem::zeroed() },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
if let Some(ref data) = *window_proxy_data {
|
||||||
(self.x.display.xlib.XSendEvent)(self.x.display.display, self.x.window, 0, 0, mem::transmute(&mut xev));
|
let mut xev = ffi::XClientMessageEvent {
|
||||||
(self.x.display.xlib.XFlush)(self.x.display.display);
|
type_: ffi::ClientMessage,
|
||||||
|
window: data.window,
|
||||||
|
format: 32,
|
||||||
|
message_type: 0,
|
||||||
|
serial: 0,
|
||||||
|
send_event: 0,
|
||||||
|
display: data.display.display,
|
||||||
|
data: unsafe { mem::zeroed() },
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(data.display.xlib.XSendEvent)(data.display.display, data.window, 0, 0, mem::transmute(&mut xev));
|
||||||
|
(data.display.xlib.XFlush)(data.display.display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,6 +529,12 @@ impl Window {
|
||||||
};
|
};
|
||||||
|
|
||||||
// creating the window object
|
// creating the window object
|
||||||
|
let window_proxy_data = WindowProxyData {
|
||||||
|
display: display.clone(),
|
||||||
|
window: window,
|
||||||
|
};
|
||||||
|
let window_proxy_data = Arc::new(Mutex::new(Some(window_proxy_data)));
|
||||||
|
|
||||||
let window = Window {
|
let window = Window {
|
||||||
x: Arc::new(XWindow {
|
x: Arc::new(XWindow {
|
||||||
display: display.clone(),
|
display: display.clone(),
|
||||||
|
@ -524,6 +546,7 @@ impl Window {
|
||||||
is_fullscreen: is_fullscreen,
|
is_fullscreen: is_fullscreen,
|
||||||
xf86_desk_mode: xf86_desk_mode,
|
xf86_desk_mode: xf86_desk_mode,
|
||||||
colormap: cmap,
|
colormap: cmap,
|
||||||
|
window_proxy_data: window_proxy_data,
|
||||||
}),
|
}),
|
||||||
is_closed: AtomicBool::new(false),
|
is_closed: AtomicBool::new(false),
|
||||||
wm_delete_window: wm_delete_window,
|
wm_delete_window: wm_delete_window,
|
||||||
|
@ -603,7 +626,7 @@ impl Window {
|
||||||
|
|
||||||
pub fn create_window_proxy(&self) -> WindowProxy {
|
pub fn create_window_proxy(&self) -> WindowProxy {
|
||||||
WindowProxy {
|
WindowProxy {
|
||||||
x: self.x.clone()
|
data: self.x.window_proxy_data.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue