mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-24 02:46:33 +11:00
On some X11 driver implementations, calling XCloseDisplay from a different thread
causes memory corruption, resulting in a crash. Change window proxy to be a weak reference so that the XCloseDisplay is always called from the main window.
This commit is contained in:
parent
5611a32513
commit
1b73aeaa24
1 changed files with 25 additions and 17 deletions
|
@ -7,7 +7,7 @@ use std::cell::Cell;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::collections::RingBuf;
|
use std::collections::RingBuf;
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use std::sync::{Arc, Once, ONCE_INIT};
|
use std::sync::{Arc, Once, ONCE_INIT, Weak};
|
||||||
use std::sync::{StaticMutex, MUTEX_INIT};
|
use std::sync::{StaticMutex, MUTEX_INIT};
|
||||||
|
|
||||||
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
|
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
|
||||||
|
@ -36,7 +36,7 @@ fn ensure_thread_init() {
|
||||||
fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) -> T {
|
fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) -> T {
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
let c_str = CString::from_slice(s.as_bytes());
|
let c_str = CString::from_slice(s.as_bytes());
|
||||||
f(c_str.as_slice_with_nul().as_ptr())
|
f(c_str.as_slice_with_nul().as_ptr())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XWindow {
|
struct XWindow {
|
||||||
|
@ -50,6 +50,9 @@ struct XWindow {
|
||||||
im: ffi::XIM,
|
im: ffi::XIM,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for XWindow {}
|
||||||
|
unsafe impl Sync for XWindow {}
|
||||||
|
|
||||||
unsafe impl Send for Window {}
|
unsafe impl Send for Window {}
|
||||||
unsafe impl Sync for Window {}
|
unsafe impl Sync for Window {}
|
||||||
|
|
||||||
|
@ -74,25 +77,30 @@ impl Drop for XWindow {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WindowProxy {
|
pub struct WindowProxy {
|
||||||
x: Arc<XWindow>,
|
x: Weak<XWindow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowProxy {
|
impl WindowProxy {
|
||||||
pub fn wakeup_event_loop(&self) {
|
pub fn wakeup_event_loop(&self) {
|
||||||
let mut xev = ffi::XClientMessageEvent {
|
match self.x.upgrade() {
|
||||||
type_: ffi::ClientMessage,
|
Some(x) => {
|
||||||
window: self.x.window,
|
let mut xev = ffi::XClientMessageEvent {
|
||||||
format: 32,
|
type_: ffi::ClientMessage,
|
||||||
message_type: 0,
|
window: x.window,
|
||||||
serial: 0,
|
format: 32,
|
||||||
send_event: 0,
|
message_type: 0,
|
||||||
display: self.x.display,
|
serial: 0,
|
||||||
l: [0, 0, 0, 0, 0],
|
send_event: 0,
|
||||||
};
|
display: x.display,
|
||||||
|
l: [0, 0, 0, 0, 0],
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::XSendEvent(self.x.display, self.x.window, 0, 0, mem::transmute(&mut xev));
|
ffi::XSendEvent(x.display, x.window, 0, 0, mem::transmute(&mut xev));
|
||||||
ffi::XFlush(self.x.display);
|
ffi::XFlush(x.display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,7 +496,7 @@ impl Window {
|
||||||
|
|
||||||
pub fn create_window_proxy(&self) -> WindowProxy {
|
pub fn create_window_proxy(&self) -> WindowProxy {
|
||||||
WindowProxy {
|
WindowProxy {
|
||||||
x: self.x.clone()
|
x: self.x.downgrade()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue