Wayland's eventloop 2.0 (#790)

* match unix common API to evl 2.0

* wayland: eventloop2.0

* make EventLoopProxy require T: 'static

* Fix linux build and tests

* wayland: update sctk & small fixes
This commit is contained in:
Victor Berger 2019-02-21 10:51:43 +01:00 committed by GitHub
parent 9602716ed2
commit 6513351e0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 532 additions and 592 deletions

View file

@ -9,23 +9,18 @@ use std::sync::Arc;
use parking_lot::Mutex;
use sctk::reexports::client::ConnectError;
use {
CreationError,
EventLoopClosed,
Icon,
MouseCursor,
ControlFlow,
WindowAttributes,
};
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use window::MonitorHandle as RootMonitorHandle;
use self::x11::{XConnection, XError};
use self::x11::ffi::XVisualInfo;
pub use self::x11::XNotSupported;
use icon::Icon;
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
use monitor::MonitorHandle as RootMonitorHandle;
use window::{WindowAttributes, CreationError, MouseCursor};
//use self::x11::{XConnection, XError};
//use self::x11::ffi::XVisualInfo;
//pub use self::x11::XNotSupported;
mod dlopen;
pub mod wayland;
pub mod x11;
//pub mod x11;
/// Environment variable specifying which backend should be used on unix platform.
///
@ -38,55 +33,55 @@ const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND";
#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes {
pub visual_infos: Option<XVisualInfo>,
//pub visual_infos: Option<XVisualInfo>,
pub screen_id: Option<i32>,
pub resize_increments: Option<(u32, u32)>,
pub base_size: Option<(u32, u32)>,
pub class: Option<(String, String)>,
pub override_redirect: bool,
pub x11_window_type: x11::util::WindowType,
//pub x11_window_type: x11::util::WindowType,
pub gtk_theme_variant: Option<String>,
pub app_id: Option<String>
}
lazy_static!(
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
};
);
//lazy_static!(
// pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
// Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
// };
//);
pub enum Window {
X(x11::Window),
//X(x11::Window),
Wayland(wayland::Window),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum WindowId {
X(x11::WindowId),
//X(x11::WindowId),
Wayland(wayland::WindowId),
}
impl WindowId {
pub unsafe fn dummy() -> Self {
WindowId::X(x11::WindowId::dummy())
WindowId::Wayland(wayland::WindowId::dummy())
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DeviceId {
X(x11::DeviceId),
//X(x11::DeviceId),
Wayland(wayland::DeviceId),
}
impl DeviceId {
pub unsafe fn dummy() -> Self {
DeviceId::X(x11::DeviceId::dummy())
DeviceId::Wayland(wayland::DeviceId::dummy())
}
}
#[derive(Debug, Clone)]
pub enum MonitorHandle {
X(x11::MonitorHandle),
//X(x11::MonitorHandle),
Wayland(wayland::MonitorHandle),
}
@ -94,7 +89,7 @@ impl MonitorHandle {
#[inline]
pub fn get_name(&self) -> Option<String> {
match self {
&MonitorHandle::X(ref m) => m.get_name(),
//&MonitorHandle::X(ref m) => m.get_name(),
&MonitorHandle::Wayland(ref m) => m.get_name(),
}
}
@ -102,7 +97,7 @@ impl MonitorHandle {
#[inline]
pub fn get_native_identifier(&self) -> u32 {
match self {
&MonitorHandle::X(ref m) => m.get_native_identifier(),
//&MonitorHandle::X(ref m) => m.get_native_identifier(),
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
}
}
@ -110,7 +105,7 @@ impl MonitorHandle {
#[inline]
pub fn get_dimensions(&self) -> PhysicalSize {
match self {
&MonitorHandle::X(ref m) => m.get_dimensions(),
//&MonitorHandle::X(ref m) => m.get_dimensions(),
&MonitorHandle::Wayland(ref m) => m.get_dimensions(),
}
}
@ -118,7 +113,7 @@ impl MonitorHandle {
#[inline]
pub fn get_position(&self) -> PhysicalPosition {
match self {
&MonitorHandle::X(ref m) => m.get_position(),
//&MonitorHandle::X(ref m) => m.get_position(),
&MonitorHandle::Wayland(ref m) => m.get_position(),
}
}
@ -126,7 +121,7 @@ impl MonitorHandle {
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
match self {
&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
//&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
}
}
@ -134,25 +129,25 @@ impl MonitorHandle {
impl Window {
#[inline]
pub fn new(
event_loop: &EventLoop,
pub fn new<T>(
window_target: &EventLoopWindowTarget<T>,
attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> {
match *event_loop {
EventsLoop::Wayland(ref event_loop) => {
wayland::Window::new(event_loop, attribs, pl_attribs).map(Window::Wayland)
},
EventLoop::X(ref event_loop) => {
x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X)
match *window_target {
EventLoopWindowTarget::Wayland(ref window_target) => {
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
},
//EventLoop::X(ref event_loop) => {
// x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X)
//},
}
}
#[inline]
pub fn id(&self) -> WindowId {
match self {
&Window::X(ref w) => WindowId::X(w.id()),
//&Window::X(ref w) => WindowId::X(w.id()),
&Window::Wayland(ref w) => WindowId::Wayland(w.id()),
}
}
@ -160,7 +155,7 @@ impl Window {
#[inline]
pub fn set_title(&self, title: &str) {
match self {
&Window::X(ref w) => w.set_title(title),
//&Window::X(ref w) => w.set_title(title),
&Window::Wayland(ref w) => w.set_title(title),
}
}
@ -168,7 +163,7 @@ impl Window {
#[inline]
pub fn show(&self) {
match self {
&Window::X(ref w) => w.show(),
//&Window::X(ref w) => w.show(),
&Window::Wayland(ref w) => w.show(),
}
}
@ -176,7 +171,7 @@ impl Window {
#[inline]
pub fn hide(&self) {
match self {
&Window::X(ref w) => w.hide(),
//&Window::X(ref w) => w.hide(),
&Window::Wayland(ref w) => w.hide(),
}
}
@ -184,7 +179,7 @@ impl Window {
#[inline]
pub fn get_position(&self) -> Option<LogicalPosition> {
match self {
&Window::X(ref w) => w.get_position(),
//&Window::X(ref w) => w.get_position(),
&Window::Wayland(ref w) => w.get_position(),
}
}
@ -192,7 +187,7 @@ impl Window {
#[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
match self {
&Window::X(ref m) => m.get_inner_position(),
//&Window::X(ref m) => m.get_inner_position(),
&Window::Wayland(ref m) => m.get_inner_position(),
}
}
@ -200,7 +195,7 @@ impl Window {
#[inline]
pub fn set_position(&self, position: LogicalPosition) {
match self {
&Window::X(ref w) => w.set_position(position),
//&Window::X(ref w) => w.set_position(position),
&Window::Wayland(ref w) => w.set_position(position),
}
}
@ -208,7 +203,7 @@ impl Window {
#[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> {
match self {
&Window::X(ref w) => w.get_inner_size(),
//&Window::X(ref w) => w.get_inner_size(),
&Window::Wayland(ref w) => w.get_inner_size(),
}
}
@ -216,7 +211,7 @@ impl Window {
#[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
match self {
&Window::X(ref w) => w.get_outer_size(),
//&Window::X(ref w) => w.get_outer_size(),
&Window::Wayland(ref w) => w.get_outer_size(),
}
}
@ -224,7 +219,7 @@ impl Window {
#[inline]
pub fn set_inner_size(&self, size: LogicalSize) {
match self {
&Window::X(ref w) => w.set_inner_size(size),
//&Window::X(ref w) => w.set_inner_size(size),
&Window::Wayland(ref w) => w.set_inner_size(size),
}
}
@ -232,7 +227,7 @@ impl Window {
#[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
match self {
&Window::X(ref w) => w.set_min_dimensions(dimensions),
//&Window::X(ref w) => w.set_min_dimensions(dimensions),
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
}
}
@ -240,7 +235,7 @@ impl Window {
#[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
match self {
&Window::X(ref w) => w.set_max_dimensions(dimensions),
//&Window::X(ref w) => w.set_max_dimensions(dimensions),
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
}
}
@ -248,7 +243,7 @@ impl Window {
#[inline]
pub fn set_resizable(&self, resizable: bool) {
match self {
&Window::X(ref w) => w.set_resizable(resizable),
//&Window::X(ref w) => w.set_resizable(resizable),
&Window::Wayland(ref w) => w.set_resizable(resizable),
}
}
@ -256,7 +251,7 @@ impl Window {
#[inline]
pub fn set_cursor(&self, cursor: MouseCursor) {
match self {
&Window::X(ref w) => w.set_cursor(cursor),
//&Window::X(ref w) => w.set_cursor(cursor),
&Window::Wayland(ref w) => w.set_cursor(cursor)
}
}
@ -264,7 +259,7 @@ impl Window {
#[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
match self {
&Window::X(ref window) => window.grab_cursor(grab),
//&Window::X(ref window) => window.grab_cursor(grab),
&Window::Wayland(ref window) => window.grab_cursor(grab),
}
}
@ -272,7 +267,7 @@ impl Window {
#[inline]
pub fn hide_cursor(&self, hide: bool) {
match self {
&Window::X(ref window) => window.hide_cursor(hide),
//&Window::X(ref window) => window.hide_cursor(hide),
&Window::Wayland(ref window) => window.hide_cursor(hide),
}
}
@ -280,7 +275,7 @@ impl Window {
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
match self {
&Window::X(ref w) => w.get_hidpi_factor(),
//&Window::X(ref w) => w.get_hidpi_factor(),
&Window::Wayland(ref w) => w.hidpi_factor() as f64,
}
}
@ -288,7 +283,7 @@ impl Window {
#[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
match self {
&Window::X(ref w) => w.set_cursor_position(position),
//&Window::X(ref w) => w.set_cursor_position(position),
&Window::Wayland(ref w) => w.set_cursor_position(position),
}
}
@ -296,7 +291,7 @@ impl Window {
#[inline]
pub fn set_maximized(&self, maximized: bool) {
match self {
&Window::X(ref w) => w.set_maximized(maximized),
//&Window::X(ref w) => w.set_maximized(maximized),
&Window::Wayland(ref w) => w.set_maximized(maximized),
}
}
@ -304,7 +299,7 @@ impl Window {
#[inline]
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
match self {
&Window::X(ref w) => w.set_fullscreen(monitor),
//&Window::X(ref w) => w.set_fullscreen(monitor),
&Window::Wayland(ref w) => w.set_fullscreen(monitor)
}
}
@ -312,7 +307,7 @@ impl Window {
#[inline]
pub fn set_decorations(&self, decorations: bool) {
match self {
&Window::X(ref w) => w.set_decorations(decorations),
//&Window::X(ref w) => w.set_decorations(decorations),
&Window::Wayland(ref w) => w.set_decorations(decorations)
}
}
@ -320,7 +315,7 @@ impl Window {
#[inline]
pub fn set_always_on_top(&self, always_on_top: bool) {
match self {
&Window::X(ref w) => w.set_always_on_top(always_on_top),
//&Window::X(ref w) => w.set_always_on_top(always_on_top),
&Window::Wayland(_) => (),
}
}
@ -328,7 +323,7 @@ impl Window {
#[inline]
pub fn set_window_icon(&self, window_icon: Option<Icon>) {
match self {
&Window::X(ref w) => w.set_window_icon(window_icon),
//&Window::X(ref w) => w.set_window_icon(window_icon),
&Window::Wayland(_) => (),
}
}
@ -336,15 +331,23 @@ impl Window {
#[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) {
match self {
&Window::X(ref w) => w.set_ime_spot(position),
//&Window::X(ref w) => w.set_ime_spot(position),
&Window::Wayland(_) => (),
}
}
#[inline]
pub fn request_redraw(&self) {
match self {
//&Window::X(ref w) => w.request_redraw(),
&Window::Wayland(ref w) => w.request_redraw(),
}
}
#[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle {
match self {
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
//&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
}
}
@ -352,10 +355,10 @@ impl Window {
#[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
match self {
&Window::X(ref window) => window.get_available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
//&Window::X(ref window) => window.get_available_monitors()
// .into_iter()
// .map(MonitorHandle::X)
// .collect(),
&Window::Wayland(ref window) => window.get_available_monitors()
.into_iter()
.map(MonitorHandle::Wayland)
@ -366,12 +369,13 @@ impl Window {
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
match self {
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
//&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
}
}
}
/*
unsafe extern "C" fn x_error_callback(
display: *mut x11::ffi::Display,
event: *mut x11::ffi::XErrorEvent,
@ -401,20 +405,21 @@ unsafe extern "C" fn x_error_callback(
// Fun fact: this return value is completely ignored.
0
}
*/
pub enum EventLoop {
Wayland(wayland::EventLoop),
X(x11::EventLoop)
pub enum EventLoop<T: 'static> {
Wayland(wayland::EventLoop<T>),
//X(x11::EventLoop)
}
#[derive(Clone)]
pub enum EventLoopProxy {
X(x11::EventLoopProxy),
Wayland(wayland::EventLoopProxy),
pub enum EventLoopProxy<T: 'static> {
//X(x11::EventLoopProxy),
Wayland(wayland::EventLoopProxy<T>),
}
impl EventLoop {
pub fn new() -> EventLoop {
impl<T:'static> EventLoop<T> {
pub fn new() -> EventLoop<T> {
if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) {
match env_var.as_str() {
"x11" => {
@ -450,19 +455,20 @@ impl EventLoop {
panic!(err_string);
}
pub fn new_wayland() -> Result<EventLoop, ConnectError> {
pub fn new_wayland() -> Result<EventLoop<T>, ConnectError> {
wayland::EventLoop::new()
.map(EventLoop::Wayland)
}
pub fn new_x11() -> Result<EventLoop, XNotSupported> {
X11_BACKEND
.lock()
.as_ref()
.map(Arc::clone)
.map(x11::EventLoop::new)
.map(EventLoop::X)
.map_err(|err| err.clone())
pub fn new_x11() -> Result<EventLoop<T>, () /*XNotSupported*/> {
//X11_BACKEND
// .lock()
// .as_ref()
// .map(Arc::clone)
// .map(x11::EventLoop::new)
// .map(EventLoop::X)
// .map_err(|err| err.clone())
unimplemented!()
}
#[inline]
@ -473,12 +479,12 @@ impl EventLoop {
.into_iter()
.map(MonitorHandle::Wayland)
.collect(),
EventLoop::X(ref evlp) => evlp
.x_connection()
.get_available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
//EventLoop::X(ref evlp) => evlp
// .x_connection()
// .get_available_monitors()
// .into_iter()
// .map(MonitorHandle::X)
// .collect(),
}
}
@ -486,32 +492,32 @@ impl EventLoop {
pub fn get_primary_monitor(&self) -> MonitorHandle {
match *self {
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()),
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
//EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
}
}
pub fn create_proxy(&self) -> EventLoopProxy {
pub fn create_proxy(&self) -> EventLoopProxy<T> {
match *self {
EventLoop::Wayland(ref evlp) => EventLoopProxy::Wayland(evlp.create_proxy()),
EventLoop::X(ref evlp) => EventLoopProxy::X(evlp.create_proxy()),
//EventLoop::X(ref evlp) => EventLoopProxy::X(evlp.create_proxy()),
}
}
pub fn poll_events<F>(&mut self, callback: F)
where F: FnMut(::Event)
pub fn run_return<F>(&mut self, callback: F)
where F: FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{
match *self {
EventLoop::Wayland(ref mut evlp) => evlp.poll_events(callback),
EventLoop::X(ref mut evlp) => evlp.poll_events(callback)
EventLoop::Wayland(ref mut evlp) => evlp.run_return(callback),
//EventLoop::X(ref mut evlp) => evlp.run_return(callback)
}
}
pub fn run_forever<F>(&mut self, callback: F)
where F: FnMut(::Event) -> ControlFlow
pub fn run<F>(self, callback: F) -> !
where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{
match *self {
EventLoop::Wayland(ref mut evlp) => evlp.run_forever(callback),
EventLoop::X(ref mut evlp) => evlp.run_forever(callback)
match self {
EventLoop::Wayland(evlp) => evlp.run(callback),
//EventLoop::X(ref mut evlp) => evlp.run(callback)
}
}
@ -519,24 +525,36 @@ impl EventLoop {
pub fn is_wayland(&self) -> bool {
match *self {
EventLoop::Wayland(_) => true,
EventLoop::X(_) => false,
//EventLoop::X(_) => false,
}
}
#[inline]
pub fn x_connection(&self) -> Option<&Arc<XConnection>> {
pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> {
match *self {
EventLoop::Wayland(_) => None,
EventLoop::X(ref ev) => Some(ev.x_connection()),
EventLoop::Wayland(ref evl) => evl.window_target(),
//EventLoop::X(ref evl) => evl.window_target()
}
}
//#[inline]
//pub fn x_connection(&self) -> Option<&Arc<XConnection>> {
// match *self {
// EventLoop::Wayland(_) => None,
// EventLoop::X(ref ev) => Some(ev.x_connection()),
// }
//}
}
impl<T: 'static> EventLoopProxy<T> {
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
match *self {
EventLoopProxy::Wayland(ref proxy) => proxy.send_event(event),
//EventLoopProxy::X(ref proxy) => proxy.wakeup(),
}
}
}
impl EventLoopProxy {
pub fn wakeup(&self) -> Result<(), EventLoopClosed> {
match *self {
EventLoopProxy::Wayland(ref proxy) => proxy.wakeup(),
EventLoopProxy::X(ref proxy) => proxy.wakeup(),
}
}
pub enum EventLoopWindowTarget<T> {
Wayland(wayland::EventLoopWindowTarget<T>),
//X(x11::EventLoopWIndowTarget<T>)
}