Port X11 backend to the EVL2.0 API (#842)

* Fix compilation on Linux.

* x11: port to evl2 with stubs

* x11: Implement run_return using calloop

* wayland/x11: Make ControlFlow::Exit sticky

* x11: Send LoopDestroyed on exit

* x11: Fix RedrawRequested semandics

* wayland: Fix RedrawRequested semandics

* x11/wayland: reduce code duplication for sticky callback
This commit is contained in:
Victor Berger 2019-04-27 18:06:51 +02:00 committed by GitHub
parent 2253565db5
commit 94f998af0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 2411 additions and 2301 deletions

View file

@ -15,15 +15,15 @@ use platform_impl::{
EventLoop as LinuxEventLoop, EventLoop as LinuxEventLoop,
Window as LinuxWindow, Window as LinuxWindow,
}; };
//use platform_impl::x11::XConnection; use platform_impl::x11::XConnection;
//use platform_impl::x11::ffi::XVisualInfo; use platform_impl::x11::ffi::XVisualInfo;
//
// TODO: stupid hack so that glutin can do its work // TODO: stupid hack so that glutin can do its work
//#[doc(hidden)] #[doc(hidden)]
//pub use platform_impl::x11; pub use platform_impl::x11;
//
//pub use platform_impl::XNotSupported; pub use platform_impl::XNotSupported;
//pub use platform_impl::x11::util::WindowType as XWindowType; pub use platform_impl::x11::util::WindowType as XWindowType;
/// Theme for wayland client side decorations /// Theme for wayland client side decorations
/// ///
@ -96,8 +96,8 @@ impl Theme for WaylandThemeObject {
/// Additional methods on `EventLoop` that are specific to Unix. /// Additional methods on `EventLoop` that are specific to Unix.
pub trait EventLoopExtUnix { pub trait EventLoopExtUnix {
/// Builds a new `EventLoops` that is forced to use X11. /// Builds a new `EventLoops` that is forced to use X11.
//fn new_x11() -> Result<Self, XNotSupported> fn new_x11() -> Result<Self, XNotSupported>
// where Self: Sized; where Self: Sized;
/// Builds a new `EventLoop` that is forced to use Wayland. /// Builds a new `EventLoop` that is forced to use Wayland.
fn new_wayland() -> Self fn new_wayland() -> Self
@ -109,8 +109,8 @@ pub trait EventLoopExtUnix {
/// True if the `EventLoop` uses X11. /// True if the `EventLoop` uses X11.
fn is_x11(&self) -> bool; fn is_x11(&self) -> bool;
//#[doc(hidden)] #[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Returns a pointer to the `wl_display` object of wayland that is used by this `EventsLoop`. /// Returns a pointer to the `wl_display` object of wayland that is used by this `EventsLoop`.
/// ///
@ -121,15 +121,15 @@ pub trait EventLoopExtUnix {
} }
impl<T> EventLoopExtUnix for EventLoop<T> { impl<T> EventLoopExtUnix for EventLoop<T> {
//#[inline] #[inline]
//fn new_x11() -> Result<Self, XNotSupported> { fn new_x11() -> Result<Self, XNotSupported> {
// LinuxEventLoop::new_x11().map(|ev| LinuxEventLoop::new_x11().map(|ev|
// EventLoop { EventLoop {
// event_loop: ev, event_loop: ev,
// _marker: ::std::marker::PhantomData, _marker: ::std::marker::PhantomData,
// } }
// ) )
//} }
#[inline] #[inline]
fn new_wayland() -> Self { fn new_wayland() -> Self {
@ -152,16 +152,19 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
!self.event_loop.is_wayland() !self.event_loop.is_wayland()
} }
//#[inline] #[inline]
//#[doc(hidden)] #[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
// self.event_loop.x_connection().cloned() match self.event_loop {
//} LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
_ => None
}
}
#[inline] #[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> { fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
match self.events_loop { match self.event_loop {
LinuxEventsLoop::Wayland(ref e) => Some(e.get_display().c_ptr() as *mut _), LinuxEventLoop::Wayland(ref e) => Some(e.get_display().get_display_ptr() as *mut _),
_ => None _ => None
} }
} }
@ -183,8 +186,8 @@ pub trait WindowExtUnix {
fn get_xlib_screen_id(&self) -> Option<raw::c_int>; fn get_xlib_screen_id(&self) -> Option<raw::c_int>;
//#[doc(hidden)] #[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X. /// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
fn set_urgent(&self, is_urgent: bool); fn set_urgent(&self, is_urgent: bool);
@ -227,7 +230,7 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_window(&self) -> Option<raw::c_ulong> { fn get_xlib_window(&self) -> Option<raw::c_ulong> {
match self.window { match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_window()), LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
_ => None _ => None
} }
} }
@ -235,7 +238,7 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_display(&self) -> Option<*mut raw::c_void> { fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_display()), LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
_ => None _ => None
} }
} }
@ -243,33 +246,33 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_screen_id(&self) -> Option<raw::c_int> { fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window { match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()), LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
_ => None _ => None
} }
} }
//#[inline] #[inline]
//#[doc(hidden)] #[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
// match self.window { match self.window {
// //LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()), LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
// _ => None _ => None
// } }
//} }
#[inline] #[inline]
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> { fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xcb_connection()), LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn set_urgent(&self, is_urgent: bool) { fn set_urgent(&self, is_urgent: bool) {
//if let LinuxWindow::X(ref w) = self.window { if let LinuxWindow::X(ref w) = self.window {
// w.set_urgent(is_urgent); w.set_urgent(is_urgent);
//} }
} }
#[inline] #[inline]
@ -312,7 +315,7 @@ pub trait WindowBuilderExtUnix {
/// Build window with override-redirect flag; defaults to false. Only relevant on X11. /// Build window with override-redirect flag; defaults to false. Only relevant on X11.
fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder; fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder;
/// Build window with `_NET_WM_WINDOW_TYPE` hint; defaults to `Normal`. Only relevant on X11. /// Build window with `_NET_WM_WINDOW_TYPE` hint; defaults to `Normal`. Only relevant on X11.
//fn with_x11_window_type(self, x11_window_type: XWindowType) -> WindowBuilder; fn with_x11_window_type(self, x11_window_type: XWindowType) -> WindowBuilder;
/// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11. /// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11.
fn with_gtk_theme_variant(self, variant: String) -> WindowBuilder; fn with_gtk_theme_variant(self, variant: String) -> WindowBuilder;
/// Build window with resize increment hint. Only implemented on X11. /// Build window with resize increment hint. Only implemented on X11.
@ -331,9 +334,9 @@ pub trait WindowBuilderExtUnix {
impl WindowBuilderExtUnix for WindowBuilder { impl WindowBuilderExtUnix for WindowBuilder {
#[inline] #[inline]
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder { fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder {
//self.platform_specific.visual_infos = Some( self.platform_specific.visual_infos = Some(
// unsafe { ptr::read(visual_infos as *const XVisualInfo) } unsafe { ptr::read(visual_infos as *const XVisualInfo) }
//); );
self self
} }
@ -355,11 +358,11 @@ impl WindowBuilderExtUnix for WindowBuilder {
self self
} }
//#[inline] #[inline]
//fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder { fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
// self.platform_specific.x11_window_type = x11_window_type; self.platform_specific.x11_window_type = x11_window_type;
// self self
//} }
#[inline] #[inline]
fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder { fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder {

View file

@ -11,16 +11,17 @@ use sctk::reexports::client::ConnectError;
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use icon::Icon; use icon::Icon;
use event::Event;
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW}; use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use window::{WindowAttributes, CreationError, MouseCursor}; use window::{WindowAttributes, CreationError, MouseCursor};
//use self::x11::{XConnection, XError}; use self::x11::{XConnection, XError};
//use self::x11::ffi::XVisualInfo; use self::x11::ffi::XVisualInfo;
//pub use self::x11::XNotSupported; pub use self::x11::XNotSupported;
mod dlopen; 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. /// Environment variable specifying which backend should be used on unix platform.
/// ///
@ -33,31 +34,31 @@ 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>,
pub screen_id: Option<i32>, pub screen_id: Option<i32>,
pub resize_increments: Option<(u32, u32)>, pub resize_increments: Option<(u32, u32)>,
pub base_size: Option<(u32, u32)>, pub base_size: Option<(u32, u32)>,
pub class: Option<(String, String)>, pub class: Option<(String, String)>,
pub override_redirect: bool, 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 gtk_theme_variant: Option<String>,
pub app_id: Option<String> pub app_id: Option<String>
} }
//lazy_static!( lazy_static!(
// pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = { pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
// Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)) Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
// }; };
//); );
pub enum Window { pub enum Window {
//X(x11::Window), X(x11::Window),
Wayland(wayland::Window), Wayland(wayland::Window),
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum WindowId { pub enum WindowId {
//X(x11::WindowId), X(x11::WindowId),
Wayland(wayland::WindowId), Wayland(wayland::WindowId),
} }
@ -69,7 +70,7 @@ impl WindowId {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DeviceId { pub enum DeviceId {
//X(x11::DeviceId), X(x11::DeviceId),
Wayland(wayland::DeviceId), Wayland(wayland::DeviceId),
} }
@ -81,7 +82,7 @@ impl DeviceId {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum MonitorHandle { pub enum MonitorHandle {
//X(x11::MonitorHandle), X(x11::MonitorHandle),
Wayland(wayland::MonitorHandle), Wayland(wayland::MonitorHandle),
} }
@ -89,7 +90,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn get_name(&self) -> Option<String> {
match self { match self {
//&MonitorHandle::X(ref m) => m.get_name(), &MonitorHandle::X(ref m) => m.get_name(),
&MonitorHandle::Wayland(ref m) => m.get_name(), &MonitorHandle::Wayland(ref m) => m.get_name(),
} }
} }
@ -97,7 +98,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn get_native_identifier(&self) -> u32 {
match self { 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(), &MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
} }
} }
@ -105,7 +106,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn get_dimensions(&self) -> PhysicalSize {
match self { match self {
//&MonitorHandle::X(ref m) => m.get_dimensions(), &MonitorHandle::X(ref m) => m.get_dimensions(),
&MonitorHandle::Wayland(ref m) => m.get_dimensions(), &MonitorHandle::Wayland(ref m) => m.get_dimensions(),
} }
} }
@ -113,7 +114,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn get_position(&self) -> PhysicalPosition {
match self { match self {
//&MonitorHandle::X(ref m) => m.get_position(), &MonitorHandle::X(ref m) => m.get_position(),
&MonitorHandle::Wayland(ref m) => m.get_position(), &MonitorHandle::Wayland(ref m) => m.get_position(),
} }
} }
@ -121,7 +122,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn get_hidpi_factor(&self) -> f64 {
match self { 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, &MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
} }
} }
@ -138,16 +139,16 @@ impl Window {
EventLoopWindowTarget::Wayland(ref window_target) => { EventLoopWindowTarget::Wayland(ref window_target) => {
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland) wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
}, },
//EventLoop::X(ref event_loop) => { EventLoopWindowTarget::X(ref window_target) => {
// x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X) x11::Window::new(window_target, attribs, pl_attribs).map(Window::X)
//}, },
} }
} }
#[inline] #[inline]
pub fn id(&self) -> WindowId { pub fn id(&self) -> WindowId {
match self { 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()), &Window::Wayland(ref w) => WindowId::Wayland(w.id()),
} }
} }
@ -155,7 +156,7 @@ impl Window {
#[inline] #[inline]
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
match self { 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), &Window::Wayland(ref w) => w.set_title(title),
} }
} }
@ -163,7 +164,7 @@ impl Window {
#[inline] #[inline]
pub fn show(&self) { pub fn show(&self) {
match self { match self {
//&Window::X(ref w) => w.show(), &Window::X(ref w) => w.show(),
&Window::Wayland(ref w) => w.show(), &Window::Wayland(ref w) => w.show(),
} }
} }
@ -171,7 +172,7 @@ impl Window {
#[inline] #[inline]
pub fn hide(&self) { pub fn hide(&self) {
match self { match self {
//&Window::X(ref w) => w.hide(), &Window::X(ref w) => w.hide(),
&Window::Wayland(ref w) => w.hide(), &Window::Wayland(ref w) => w.hide(),
} }
} }
@ -179,7 +180,7 @@ impl Window {
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn get_position(&self) -> Option<LogicalPosition> {
match self { match self {
//&Window::X(ref w) => w.get_position(), &Window::X(ref w) => w.get_position(),
&Window::Wayland(ref w) => w.get_position(), &Window::Wayland(ref w) => w.get_position(),
} }
} }
@ -187,7 +188,7 @@ impl Window {
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn get_inner_position(&self) -> Option<LogicalPosition> {
match self { 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(), &Window::Wayland(ref m) => m.get_inner_position(),
} }
} }
@ -195,7 +196,7 @@ impl Window {
#[inline] #[inline]
pub fn set_position(&self, position: LogicalPosition) { pub fn set_position(&self, position: LogicalPosition) {
match self { 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), &Window::Wayland(ref w) => w.set_position(position),
} }
} }
@ -203,7 +204,7 @@ impl Window {
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn get_inner_size(&self) -> Option<LogicalSize> {
match self { 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(), &Window::Wayland(ref w) => w.get_inner_size(),
} }
} }
@ -211,7 +212,7 @@ impl Window {
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn get_outer_size(&self) -> Option<LogicalSize> {
match self { 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(), &Window::Wayland(ref w) => w.get_outer_size(),
} }
} }
@ -219,7 +220,7 @@ impl Window {
#[inline] #[inline]
pub fn set_inner_size(&self, size: LogicalSize) { pub fn set_inner_size(&self, size: LogicalSize) {
match self { 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), &Window::Wayland(ref w) => w.set_inner_size(size),
} }
} }
@ -227,7 +228,7 @@ impl Window {
#[inline] #[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
match self { 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), &Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
} }
} }
@ -235,7 +236,7 @@ impl Window {
#[inline] #[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
match self { 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), &Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
} }
} }
@ -243,7 +244,7 @@ impl Window {
#[inline] #[inline]
pub fn set_resizable(&self, resizable: bool) { pub fn set_resizable(&self, resizable: bool) {
match self { 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), &Window::Wayland(ref w) => w.set_resizable(resizable),
} }
} }
@ -251,7 +252,7 @@ impl Window {
#[inline] #[inline]
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor(&self, cursor: MouseCursor) {
match self { 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) &Window::Wayland(ref w) => w.set_cursor(cursor)
} }
} }
@ -259,7 +260,7 @@ impl Window {
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
match self { 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), &Window::Wayland(ref window) => window.grab_cursor(grab),
} }
} }
@ -267,7 +268,7 @@ impl Window {
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn hide_cursor(&self, hide: bool) {
match self { 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), &Window::Wayland(ref window) => window.hide_cursor(hide),
} }
} }
@ -275,7 +276,7 @@ impl Window {
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn get_hidpi_factor(&self) -> f64 {
match self { 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, &Window::Wayland(ref w) => w.hidpi_factor() as f64,
} }
} }
@ -283,7 +284,7 @@ impl Window {
#[inline] #[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
match self { 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), &Window::Wayland(ref w) => w.set_cursor_position(position),
} }
} }
@ -291,7 +292,7 @@ impl Window {
#[inline] #[inline]
pub fn set_maximized(&self, maximized: bool) { pub fn set_maximized(&self, maximized: bool) {
match self { 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), &Window::Wayland(ref w) => w.set_maximized(maximized),
} }
} }
@ -299,7 +300,7 @@ impl Window {
#[inline] #[inline]
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) { pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
match self { 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) &Window::Wayland(ref w) => w.set_fullscreen(monitor)
} }
} }
@ -307,7 +308,7 @@ impl Window {
#[inline] #[inline]
pub fn set_decorations(&self, decorations: bool) { pub fn set_decorations(&self, decorations: bool) {
match self { 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) &Window::Wayland(ref w) => w.set_decorations(decorations)
} }
} }
@ -315,7 +316,7 @@ impl Window {
#[inline] #[inline]
pub fn set_always_on_top(&self, always_on_top: bool) { pub fn set_always_on_top(&self, always_on_top: bool) {
match self { 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(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -323,7 +324,7 @@ impl Window {
#[inline] #[inline]
pub fn set_window_icon(&self, window_icon: Option<Icon>) { pub fn set_window_icon(&self, window_icon: Option<Icon>) {
match self { match self {
//&Window::X(ref w) => w.set_window_icon(window_icon), &Window::X(ref w) => w.set_window_icon(window_icon),
&Window::Wayland(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -331,7 +332,7 @@ impl Window {
#[inline] #[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) { pub fn set_ime_spot(&self, position: LogicalPosition) {
match self { match self {
//&Window::X(ref w) => w.set_ime_spot(position), &Window::X(ref w) => w.set_ime_spot(position),
&Window::Wayland(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -339,7 +340,7 @@ impl Window {
#[inline] #[inline]
pub fn request_redraw(&self) { pub fn request_redraw(&self) {
match self { match self {
//&Window::X(ref w) => w.request_redraw(), &Window::X(ref w) => w.request_redraw(),
&Window::Wayland(ref w) => w.request_redraw(), &Window::Wayland(ref w) => w.request_redraw(),
} }
} }
@ -347,7 +348,7 @@ impl Window {
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn get_current_monitor(&self) -> RootMonitorHandle {
match self { 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()) }, &Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
} }
} }
@ -355,10 +356,10 @@ impl Window {
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
match self { match self {
//&Window::X(ref window) => window.get_available_monitors() &Window::X(ref window) => window.get_available_monitors()
// .into_iter() .into_iter()
// .map(MonitorHandle::X) .map(MonitorHandle::X)
// .collect(), .collect(),
&Window::Wayland(ref window) => window.get_available_monitors() &Window::Wayland(ref window) => window.get_available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
@ -369,13 +370,13 @@ impl Window {
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn get_primary_monitor(&self) -> MonitorHandle {
match self { 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()), &Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
} }
} }
} }
/*
unsafe extern "C" fn x_error_callback( 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,
@ -405,16 +406,16 @@ unsafe extern "C" fn x_error_callback(
// Fun fact: this return value is completely ignored. // Fun fact: this return value is completely ignored.
0 0
} }
*/
pub enum EventLoop<T: 'static> { pub enum EventLoop<T: 'static> {
Wayland(wayland::EventLoop<T>), Wayland(wayland::EventLoop<T>),
//X(x11::EventLoop) X(x11::EventLoop<T>)
} }
#[derive(Clone)] #[derive(Clone)]
pub enum EventLoopProxy<T: 'static> { pub enum EventLoopProxy<T: 'static> {
//X(x11::EventLoopProxy), X(x11::EventLoopProxy<T>),
Wayland(wayland::EventLoopProxy<T>), Wayland(wayland::EventLoopProxy<T>),
} }
@ -460,15 +461,14 @@ impl<T:'static> EventLoop<T> {
.map(EventLoop::Wayland) .map(EventLoop::Wayland)
} }
pub fn new_x11() -> Result<EventLoop<T>, () /*XNotSupported*/> { pub fn new_x11() -> Result<EventLoop<T>, XNotSupported> {
//X11_BACKEND X11_BACKEND
// .lock() .lock()
// .as_ref() .as_ref()
// .map(Arc::clone) .map(Arc::clone)
// .map(x11::EventLoop::new) .map(x11::EventLoop::new)
// .map(EventLoop::X) .map(EventLoop::X)
// .map_err(|err| err.clone()) .map_err(|err| err.clone())
unimplemented!()
} }
#[inline] #[inline]
@ -479,12 +479,12 @@ impl<T:'static> EventLoop<T> {
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
.collect(), .collect(),
//EventLoop::X(ref evlp) => evlp EventLoop::X(ref evlp) => evlp
// .x_connection() .x_connection()
// .get_available_monitors() .get_available_monitors()
// .into_iter() .into_iter()
// .map(MonitorHandle::X) .map(MonitorHandle::X)
// .collect(), .collect(),
} }
} }
@ -492,14 +492,14 @@ impl<T:'static> EventLoop<T> {
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn get_primary_monitor(&self) -> MonitorHandle {
match *self { match *self {
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()), 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<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {
match *self { match *self {
EventLoop::Wayland(ref evlp) => EventLoopProxy::Wayland(evlp.create_proxy()), 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()),
} }
} }
@ -508,7 +508,7 @@ impl<T:'static> EventLoop<T> {
{ {
match *self { match *self {
EventLoop::Wayland(ref mut evlp) => evlp.run_return(callback), EventLoop::Wayland(ref mut evlp) => evlp.run_return(callback),
//EventLoop::X(ref mut evlp) => evlp.run_return(callback) EventLoop::X(ref mut evlp) => evlp.run_return(callback)
} }
} }
@ -517,7 +517,7 @@ impl<T:'static> EventLoop<T> {
{ {
match self { match self {
EventLoop::Wayland(evlp) => evlp.run(callback), EventLoop::Wayland(evlp) => evlp.run(callback),
//EventLoop::X(ref mut evlp) => evlp.run(callback) EventLoop::X(evlp) => evlp.run(callback)
} }
} }
@ -525,36 +525,44 @@ impl<T:'static> EventLoop<T> {
pub fn is_wayland(&self) -> bool { pub fn is_wayland(&self) -> bool {
match *self { match *self {
EventLoop::Wayland(_) => true, EventLoop::Wayland(_) => true,
//EventLoop::X(_) => false, EventLoop::X(_) => false,
} }
} }
pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> { pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> {
match *self { match *self {
EventLoop::Wayland(ref evl) => evl.window_target(), EventLoop::Wayland(ref evl) => evl.window_target(),
//EventLoop::X(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> { impl<T: 'static> EventLoopProxy<T> {
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
match *self { match *self {
EventLoopProxy::Wayland(ref proxy) => proxy.send_event(event), EventLoopProxy::Wayland(ref proxy) => proxy.send_event(event),
//EventLoopProxy::X(ref proxy) => proxy.wakeup(), EventLoopProxy::X(ref proxy) => proxy.send_event(event),
} }
} }
} }
pub enum EventLoopWindowTarget<T> { pub enum EventLoopWindowTarget<T> {
Wayland(wayland::EventLoopWindowTarget<T>), Wayland(wayland::EventLoopWindowTarget<T>),
//X(x11::EventLoopWIndowTarget<T>) X(x11::EventLoopWindowTarget<T>)
}
fn sticky_exit_callback<T, F>(
evt: Event<T>, target: &RootELW<T>, control_flow: &mut ControlFlow, callback: &mut F
) where F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
{
// make ControlFlow::Exit sticky by providing a dummy
// control flow reference if it is already Exit.
let mut dummy = ControlFlow::Exit;
let cf = if *control_flow == ControlFlow::Exit {
&mut dummy
} else {
control_flow
};
// user callback
callback(evt, target, cf)
} }

View file

@ -8,6 +8,7 @@ use std::time::Instant;
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}; use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
use event::ModifiersState; use event::ModifiersState;
use dpi::{PhysicalPosition, PhysicalSize}; use dpi::{PhysicalPosition, PhysicalSize};
use platform_impl::platform::sticky_exit_callback;
use super::window::WindowStore; use super::window::WindowStore;
use super::WindowId; use super::WindowId;
@ -204,23 +205,39 @@ impl<T: 'static> EventLoop<T> {
// empty buffer of events // empty buffer of events
{ {
let mut guard = sink.lock().unwrap(); let mut guard = sink.lock().unwrap();
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow)); guard.empty_with(|evt| {
sticky_exit_callback(evt, &self.window_target, &mut control_flow, &mut callback);
});
} }
// empty user events // empty user events
{ {
let mut guard = user_events.borrow_mut(); let mut guard = user_events.borrow_mut();
for evt in guard.drain(..) { for evt in guard.drain(..) {
callback(::event::Event::UserEvent(evt), &self.window_target, &mut control_flow); sticky_exit_callback(
::event::Event::UserEvent(evt),
&self.window_target,
&mut control_flow,
&mut callback
);
} }
} }
// do a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
callback(::event::Event::EventsCleared, &self.window_target, &mut control_flow); // in response of resize & friends
// fo a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
self.post_dispatch_triggers(); self.post_dispatch_triggers();
{ {
let mut guard = sink.lock().unwrap(); let mut guard = sink.lock().unwrap();
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow)); guard.empty_with(|evt| {
sticky_exit_callback(evt, &self.window_target, &mut control_flow, &mut callback);
});
}
// send Events cleared
{
sticky_exit_callback(
::event::Event::EventsCleared,
&self.window_target,
&mut control_flow,
&mut callback
);
} }
// send pending events to the server // send pending events to the server

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@ use std::os::raw::*;
use parking_lot::Mutex; use parking_lot::Mutex;
use {PhysicalPosition, PhysicalSize}; use dpi::{PhysicalPosition, PhysicalSize};
use super::{util, XConnection, XError}; use super::{util, XConnection, XError};
use super::ffi::{ use super::ffi::{
RRCrtcChangeNotifyMask, RRCrtcChangeNotifyMask,

View file

@ -1,7 +1,7 @@
use std::cmp; use std::cmp;
use super::*; use super::*;
use {LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
// Friendly neighborhood axis-aligned rectangle // Friendly neighborhood axis-aligned rectangle
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View file

@ -1,4 +1,4 @@
use {Icon, Pixel, PIXEL_SIZE}; use window::{Icon, Pixel, PIXEL_SIZE};
use super::*; use super::*;
impl Pixel { impl Pixel {

View file

@ -1,7 +1,7 @@
use std::str; use std::str;
use super::*; use super::*;
use events::ModifiersState; use event::ModifiersState;
pub const VIRTUAL_CORE_POINTER: c_int = 2; pub const VIRTUAL_CORE_POINTER: c_int = 2;
pub const VIRTUAL_CORE_KEYBOARD: c_int = 3; pub const VIRTUAL_CORE_KEYBOARD: c_int = 3;

View file

@ -1,7 +1,7 @@
use std::{env, slice}; use std::{env, slice};
use std::str::FromStr; use std::str::FromStr;
use validate_hidpi_factor; use dpi::validate_hidpi_factor;
use super::*; use super::*;
pub fn calc_dpi_factor( pub fn calc_dpi_factor(

View file

@ -1,4 +1,5 @@
use std::{cmp, env, mem}; use std::{cmp, env, mem};
use std::collections::HashSet;
use std::ffi::CString; use std::ffi::CString;
use std::os::raw::*; use std::os::raw::*;
use std::path::Path; use std::path::Path;
@ -7,15 +8,15 @@ use std::sync::Arc;
use libc; use libc;
use parking_lot::Mutex; use parking_lot::Mutex;
use {Icon, MouseCursor, WindowAttributes}; use window::{Icon, MouseCursor, WindowAttributes};
use CreationError::{self, OsError}; use window::CreationError::{self, OsError};
use dpi::{LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
use platform_impl::MonitorHandle as PlatformMonitorHandle; use platform_impl::MonitorHandle as PlatformMonitorHandle;
use platform_impl::PlatformSpecificWindowBuilderAttributes; use platform_impl::PlatformSpecificWindowBuilderAttributes;
use platform_impl::x11::MonitorHandle as X11MonitorHandle; use platform_impl::x11::MonitorHandle as X11MonitorHandle;
use window::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use super::{ffi, util, ImeSender, XConnection, XError, WindowId, EventLoop}; use super::{ffi, util, ImeSender, XConnection, XError, WindowId, EventLoopWindowTarget};
unsafe extern "C" fn visibility_predicate( unsafe extern "C" fn visibility_predicate(
_display: *mut ffi::Display, _display: *mut ffi::Display,
@ -66,11 +67,12 @@ pub struct UnownedWindow {
ime_sender: Mutex<ImeSender>, ime_sender: Mutex<ImeSender>,
pub multitouch: bool, // never changes pub multitouch: bool, // never changes
pub shared_state: Mutex<SharedState>, pub shared_state: Mutex<SharedState>,
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
} }
impl UnownedWindow { impl UnownedWindow {
pub fn new( pub fn new<T>(
event_loop: &EventLoop, event_loop: &EventLoopWindowTarget<T>,
window_attrs: WindowAttributes, window_attrs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<UnownedWindow, CreationError> { ) -> Result<UnownedWindow, CreationError> {
@ -203,6 +205,7 @@ impl UnownedWindow {
ime_sender: Mutex::new(event_loop.ime_sender.clone()), ime_sender: Mutex::new(event_loop.ime_sender.clone()),
multitouch: window_attrs.multitouch, multitouch: window_attrs.multitouch,
shared_state: SharedState::new(dpi_factor), shared_state: SharedState::new(dpi_factor),
pending_redraws: event_loop.pending_redraws.clone(),
}; };
// Title must be set before mapping. Some tiling window managers (i.e. i3) use the window // Title must be set before mapping. Some tiling window managers (i.e. i3) use the window
@ -1210,4 +1213,9 @@ impl UnownedWindow {
#[inline] #[inline]
pub fn id(&self) -> WindowId { WindowId(self.xwindow) } pub fn id(&self) -> WindowId { WindowId(self.xwindow) }
#[inline]
pub fn request_redraw(&self) {
self.pending_redraws.lock().unwrap().insert(WindowId(self.xwindow));
}
} }