mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 23:01:30 +11:00
Merge pull request #199 from alexheretic/xwayland-env-var
Add a `WINIT_UNIX_BACKEND` environment variable to all the user to control the choice of x11/wayland backend.
This commit is contained in:
commit
05cd9f2114
|
@ -181,6 +181,14 @@ pub struct ButtonId(u32);
|
||||||
/// Provides a way to retreive events from the windows that were registered to it.
|
/// Provides a way to retreive events from the windows that were registered to it.
|
||||||
///
|
///
|
||||||
/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs.
|
/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs.
|
||||||
|
///
|
||||||
|
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||||
|
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||||
|
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||||
|
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||||
|
/// > and if it fails will fallback on x11.
|
||||||
|
/// >
|
||||||
|
/// > If this variable is set with any other value, winit will panic.
|
||||||
pub struct EventsLoop {
|
pub struct EventsLoop {
|
||||||
events_loop: platform::EventsLoop,
|
events_loop: platform::EventsLoop,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
use {CreationError, CursorState, EventsLoopClosed, MouseCursor, ControlFlow};
|
use {CreationError, CursorState, EventsLoopClosed, MouseCursor, ControlFlow};
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -15,6 +16,15 @@ mod dlopen;
|
||||||
pub mod wayland;
|
pub mod wayland;
|
||||||
pub mod x11;
|
pub mod x11;
|
||||||
|
|
||||||
|
/// Environment variable specifying which backend should be used on unix platform.
|
||||||
|
///
|
||||||
|
/// Legal values are x11 and wayland. If this variable is set only the named backend
|
||||||
|
/// will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||||
|
/// and if it fails will fallback on x11.
|
||||||
|
///
|
||||||
|
/// If this variable is set with any other value, winit will panic.
|
||||||
|
const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND";
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub visual_infos: Option<XVisualInfo>,
|
pub visual_infos: Option<XVisualInfo>,
|
||||||
|
@ -24,19 +34,42 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub enum UnixBackend {
|
pub enum UnixBackend {
|
||||||
X(Arc<XConnection>),
|
X(Arc<XConnection>),
|
||||||
Wayland(Arc<wayland::WaylandContext>),
|
Wayland(Arc<wayland::WaylandContext>),
|
||||||
Error(XNotSupported),
|
Error(Option<XNotSupported>, Option<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static!(
|
lazy_static!(
|
||||||
pub static ref UNIX_BACKEND: UnixBackend = {
|
pub static ref UNIX_BACKEND: UnixBackend = {
|
||||||
if let Some(ctxt) = wayland::WaylandContext::init() {
|
#[inline]
|
||||||
UnixBackend::Wayland(Arc::new(ctxt))
|
fn x_backend() -> Result<UnixBackend, XNotSupported> {
|
||||||
} else {
|
|
||||||
match XConnection::new(Some(x_error_callback)) {
|
match XConnection::new(Some(x_error_callback)) {
|
||||||
Ok(x) => UnixBackend::X(Arc::new(x)),
|
Ok(x) => Ok(UnixBackend::X(Arc::new(x))),
|
||||||
Err(e) => UnixBackend::Error(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn wayland_backend() -> Result<UnixBackend, ()> {
|
||||||
|
wayland::WaylandContext::init()
|
||||||
|
.map(|ctx| UnixBackend::Wayland(Arc::new(ctx)))
|
||||||
|
.ok_or(())
|
||||||
|
}
|
||||||
|
match env::var(BACKEND_PREFERENCE_ENV_VAR) {
|
||||||
|
Ok(s) => match s.as_str() {
|
||||||
|
"x11" => x_backend().unwrap_or_else(|e| UnixBackend::Error(Some(e), None)),
|
||||||
|
"wayland" => wayland_backend().unwrap_or_else(|_| {
|
||||||
|
UnixBackend::Error(None, Some("Wayland not available".into()))
|
||||||
|
}),
|
||||||
|
_ => panic!("Unknown environment variable value for {}, try one of `x11`,`wayland`",
|
||||||
|
BACKEND_PREFERENCE_ENV_VAR),
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
// Try wayland, fallback to X11
|
||||||
|
wayland_backend().unwrap_or_else(|_| {
|
||||||
|
x_backend().unwrap_or_else(|x_err| {
|
||||||
|
UnixBackend::Error(Some(x_err), Some("Wayland not available".into()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -85,7 +118,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(MonitorId::X)
|
.map(MonitorId::X)
|
||||||
.collect(),
|
.collect(),
|
||||||
UnixBackend::Error(_) => { let mut d = VecDeque::new(); d.push_back(MonitorId::None); d},
|
UnixBackend::Error(..) => { let mut d = VecDeque::new(); d.push_back(MonitorId::None); d},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +127,7 @@ pub fn get_primary_monitor() -> MonitorId {
|
||||||
match *UNIX_BACKEND {
|
match *UNIX_BACKEND {
|
||||||
UnixBackend::Wayland(ref ctxt) => MonitorId::Wayland(wayland::get_primary_monitor(ctxt)),
|
UnixBackend::Wayland(ref ctxt) => MonitorId::Wayland(wayland::get_primary_monitor(ctxt)),
|
||||||
UnixBackend::X(ref connec) => MonitorId::X(x11::get_primary_monitor(connec)),
|
UnixBackend::X(ref connec) => MonitorId::X(x11::get_primary_monitor(connec)),
|
||||||
UnixBackend::Error(_) => MonitorId::None,
|
UnixBackend::Error(..) => MonitorId::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +180,7 @@ impl Window2 {
|
||||||
UnixBackend::X(_) => {
|
UnixBackend::X(_) => {
|
||||||
x11::Window2::new(events_loop, window, pl_attribs).map(Window2::X)
|
x11::Window2::new(events_loop, window, pl_attribs).map(Window2::X)
|
||||||
},
|
},
|
||||||
UnixBackend::Error(_) => {
|
UnixBackend::Error(..) => {
|
||||||
// If the Backend is Error(), it is not possible to instanciate an EventsLoop at all,
|
// If the Backend is Error(), it is not possible to instanciate an EventsLoop at all,
|
||||||
// thus this function cannot be called!
|
// thus this function cannot be called!
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
@ -324,7 +357,7 @@ impl EventsLoop {
|
||||||
EventsLoop::X(x11::EventsLoop::new(ctxt.clone()))
|
EventsLoop::X(x11::EventsLoop::new(ctxt.clone()))
|
||||||
},
|
},
|
||||||
|
|
||||||
UnixBackend::Error(_) => {
|
UnixBackend::Error(..) => {
|
||||||
panic!("Attempted to create an EventsLoop while no backend was available.")
|
panic!("Attempted to create an EventsLoop while no backend was available.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,6 +320,14 @@ impl Iterator for AvailableMonitorsIter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of all available monitors.
|
/// Returns the list of all available monitors.
|
||||||
|
///
|
||||||
|
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||||
|
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||||
|
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||||
|
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||||
|
/// > and if it fails will fallback on x11.
|
||||||
|
/// >
|
||||||
|
/// > If this variable is set with any other value, winit will panic.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors() -> AvailableMonitorsIter {
|
pub fn get_available_monitors() -> AvailableMonitorsIter {
|
||||||
let data = platform::get_available_monitors();
|
let data = platform::get_available_monitors();
|
||||||
|
@ -327,6 +335,14 @@ pub fn get_available_monitors() -> AvailableMonitorsIter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the primary monitor of the system.
|
/// Returns the primary monitor of the system.
|
||||||
|
///
|
||||||
|
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||||
|
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||||
|
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||||
|
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||||
|
/// > and if it fails will fallback on x11.
|
||||||
|
/// >
|
||||||
|
/// > If this variable is set with any other value, winit will panic.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor() -> MonitorId {
|
pub fn get_primary_monitor() -> MonitorId {
|
||||||
MonitorId(platform::get_primary_monitor())
|
MonitorId(platform::get_primary_monitor())
|
||||||
|
|
Loading…
Reference in a new issue