Shares the XConnection between all event loops instead of just all event (#572)

loops on the same thread.

This is needed for adding shared context support to glutin, as contexts
must be made with the same native display (and therefore the same
connection.)

Signed-off-by: Hal Gentz <zegentzy@protonmail.com>
This commit is contained in:
Hal Gentz 2018-06-18 00:44:38 +00:00 committed by Francesca Frangipane
parent 289fb47a34
commit 042f5fe4b3
2 changed files with 31 additions and 31 deletions

View file

@ -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. - `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`. - `AvailableMonitorsIter` now implements `Debug`.
- Fixed quirk on macOS where certain keys would generate characters at twice the normal rate when held down. - 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) # Version 0.15.1 (2018-06-13)

View file

@ -6,6 +6,7 @@ use std::ffi::CStr;
use std::os::raw::*; use std::os::raw::*;
use std::sync::Arc; use std::sync::Arc;
use parking_lot::Mutex;
use sctk::reexports::client::ConnectError; use sctk::reexports::client::ConnectError;
use { use {
@ -50,9 +51,9 @@ pub struct PlatformSpecificWindowBuilderAttributes {
pub x11_window_type: x11::util::WindowType, pub x11_window_type: x11::util::WindowType,
} }
thread_local!( lazy_static!(
pub static X11_BACKEND: Result<Arc<XConnection>, XNotSupported> = { pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
XConnection::new(Some(x_error_callback)).map(Arc::new) 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, display: *mut x11::ffi::Display,
event: *mut x11::ffi::XErrorEvent, event: *mut x11::ffi::XErrorEvent,
) -> c_int { ) -> c_int {
X11_BACKEND.with(|result| { let xconn_lock = X11_BACKEND.lock();
if let &Ok(ref xconn) = result { if let Ok(ref xconn) = *xconn_lock {
let mut buf: [c_char; 1024] = mem::uninitialized(); let mut buf: [c_char; 1024] = mem::uninitialized();
(xconn.xlib.XGetErrorText)( (xconn.xlib.XGetErrorText)(
display, display,
(*event).error_code as c_int, (*event).error_code as c_int,
buf.as_mut_ptr(), buf.as_mut_ptr(),
buf.len() as c_int, buf.len() as c_int,
); );
let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy(); let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy();
let error = XError { let error = XError {
description: description.into_owned(), description: description.into_owned(),
error_code: (*event).error_code, error_code: (*event).error_code,
request_code: (*event).request_code, request_code: (*event).request_code,
minor_code: (*event).minor_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. // Fun fact: this return value is completely ignored.
0 0
} }
@ -441,14 +441,13 @@ r#"Failed to initialize any backend!
} }
pub fn new_x11() -> Result<EventsLoop, XNotSupported> { pub fn new_x11() -> Result<EventsLoop, XNotSupported> {
X11_BACKEND.with(|result| { X11_BACKEND
result .lock()
.as_ref() .as_ref()
.map(Arc::clone) .map(Arc::clone)
.map(x11::EventsLoop::new) .map(x11::EventsLoop::new)
.map(EventsLoop::X) .map(EventsLoop::X)
.map_err(|err| err.clone()) .map_err(|err| err.clone())
})
} }
#[inline] #[inline]