diff --git a/CHANGELOG.md b/CHANGELOG.md index 54e44e4c..bd8812a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - `EventsLoop::get_available_monitors` and `EventsLoop::get_primary_monitor` now have identical counterparts on `Window`, so this information can be acquired without an `EventsLoop` borrow. - `AvailableMonitorsIter` now implements `Debug`. - Fixed quirk on macOS where certain keys would generate characters at twice the normal rate when held down. +- On X11, all event loops now share the same `XConnection`. # Version 0.15.1 (2018-06-13) diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 83f0869d..9e209521 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -6,6 +6,7 @@ use std::ffi::CStr; use std::os::raw::*; use std::sync::Arc; +use parking_lot::Mutex; use sctk::reexports::client::ConnectError; use { @@ -50,9 +51,9 @@ pub struct PlatformSpecificWindowBuilderAttributes { pub x11_window_type: x11::util::WindowType, } -thread_local!( - pub static X11_BACKEND: Result, XNotSupported> = { - XConnection::new(Some(x_error_callback)).map(Arc::new) +lazy_static!( + pub static ref X11_BACKEND: Mutex, XNotSupported>> = { + Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)) }; ); @@ -357,29 +358,28 @@ unsafe extern "C" fn x_error_callback( display: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent, ) -> c_int { - X11_BACKEND.with(|result| { - if let &Ok(ref xconn) = result { - let mut buf: [c_char; 1024] = mem::uninitialized(); - (xconn.xlib.XGetErrorText)( - display, - (*event).error_code as c_int, - buf.as_mut_ptr(), - buf.len() as c_int, - ); - let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy(); + let xconn_lock = X11_BACKEND.lock(); + if let Ok(ref xconn) = *xconn_lock { + let mut buf: [c_char; 1024] = mem::uninitialized(); + (xconn.xlib.XGetErrorText)( + display, + (*event).error_code as c_int, + buf.as_mut_ptr(), + buf.len() as c_int, + ); + let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy(); - let error = XError { - description: description.into_owned(), - error_code: (*event).error_code, - request_code: (*event).request_code, - minor_code: (*event).minor_code, - }; + let error = XError { + description: description.into_owned(), + error_code: (*event).error_code, + request_code: (*event).request_code, + minor_code: (*event).minor_code, + }; - eprintln!("[winit X11 error] {:#?}", error); + eprintln!("[winit X11 error] {:#?}", error); - *xconn.latest_error.lock() = Some(error); - } - }); + *xconn.latest_error.lock() = Some(error); + } // Fun fact: this return value is completely ignored. 0 } @@ -441,14 +441,13 @@ r#"Failed to initialize any backend! } pub fn new_x11() -> Result { - X11_BACKEND.with(|result| { - result - .as_ref() - .map(Arc::clone) - .map(x11::EventsLoop::new) - .map(EventsLoop::X) - .map_err(|err| err.clone()) - }) + X11_BACKEND + .lock() + .as_ref() + .map(Arc::clone) + .map(x11::EventsLoop::new) + .map(EventsLoop::X) + .map_err(|err| err.clone()) } #[inline]