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,
Window as LinuxWindow,
};
//use platform_impl::x11::XConnection;
//use platform_impl::x11::ffi::XVisualInfo;
//
use platform_impl::x11::XConnection;
use platform_impl::x11::ffi::XVisualInfo;
// TODO: stupid hack so that glutin can do its work
//#[doc(hidden)]
//pub use platform_impl::x11;
//
//pub use platform_impl::XNotSupported;
//pub use platform_impl::x11::util::WindowType as XWindowType;
#[doc(hidden)]
pub use platform_impl::x11;
pub use platform_impl::XNotSupported;
pub use platform_impl::x11::util::WindowType as XWindowType;
/// Theme for wayland client side decorations
///
@ -96,8 +96,8 @@ impl Theme for WaylandThemeObject {
/// Additional methods on `EventLoop` that are specific to Unix.
pub trait EventLoopExtUnix {
/// Builds a new `EventLoops` that is forced to use X11.
//fn new_x11() -> Result<Self, XNotSupported>
// where Self: Sized;
fn new_x11() -> Result<Self, XNotSupported>
where Self: Sized;
/// Builds a new `EventLoop` that is forced to use Wayland.
fn new_wayland() -> Self
@ -109,8 +109,8 @@ pub trait EventLoopExtUnix {
/// True if the `EventLoop` uses X11.
fn is_x11(&self) -> bool;
//#[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// 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> {
//#[inline]
//fn new_x11() -> Result<Self, XNotSupported> {
// LinuxEventLoop::new_x11().map(|ev|
// EventLoop {
// event_loop: ev,
// _marker: ::std::marker::PhantomData,
// }
// )
//}
#[inline]
fn new_x11() -> Result<Self, XNotSupported> {
LinuxEventLoop::new_x11().map(|ev|
EventLoop {
event_loop: ev,
_marker: ::std::marker::PhantomData,
}
)
}
#[inline]
fn new_wayland() -> Self {
@ -152,16 +152,19 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
!self.event_loop.is_wayland()
}
//#[inline]
//#[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
// self.event_loop.x_connection().cloned()
//}
#[inline]
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.event_loop {
LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
_ => None
}
}
#[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
match self.events_loop {
LinuxEventsLoop::Wayland(ref e) => Some(e.get_display().c_ptr() as *mut _),
match self.event_loop {
LinuxEventLoop::Wayland(ref e) => Some(e.get_display().get_display_ptr() as *mut _),
_ => None
}
}
@ -183,8 +186,8 @@ pub trait WindowExtUnix {
fn get_xlib_screen_id(&self) -> Option<raw::c_int>;
//#[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
fn set_urgent(&self, is_urgent: bool);
@ -227,7 +230,7 @@ impl WindowExtUnix for Window {
#[inline]
fn get_xlib_window(&self) -> Option<raw::c_ulong> {
match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
_ => None
}
}
@ -235,7 +238,7 @@ impl WindowExtUnix for Window {
#[inline]
fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
_ => None
}
}
@ -243,33 +246,33 @@ impl WindowExtUnix for Window {
#[inline]
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
_ => None
}
}
//#[inline]
//#[doc(hidden)]
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
// match self.window {
// //LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
// _ => None
// }
//}
#[inline]
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
_ => None
}
}
#[inline]
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window {
//LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
_ => None
}
}
#[inline]
fn set_urgent(&self, is_urgent: bool) {
//if let LinuxWindow::X(ref w) = self.window {
// w.set_urgent(is_urgent);
//}
if let LinuxWindow::X(ref w) = self.window {
w.set_urgent(is_urgent);
}
}
#[inline]
@ -312,7 +315,7 @@ pub trait WindowBuilderExtUnix {
/// Build window with override-redirect flag; defaults to false. Only relevant on X11.
fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder;
/// 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.
fn with_gtk_theme_variant(self, variant: String) -> WindowBuilder;
/// Build window with resize increment hint. Only implemented on X11.
@ -331,9 +334,9 @@ pub trait WindowBuilderExtUnix {
impl WindowBuilderExtUnix for WindowBuilder {
#[inline]
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder {
//self.platform_specific.visual_infos = Some(
// unsafe { ptr::read(visual_infos as *const XVisualInfo) }
//);
self.platform_specific.visual_infos = Some(
unsafe { ptr::read(visual_infos as *const XVisualInfo) }
);
self
}
@ -355,11 +358,11 @@ impl WindowBuilderExtUnix for WindowBuilder {
self
}
//#[inline]
//fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
// self.platform_specific.x11_window_type = x11_window_type;
// self
//}
#[inline]
fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
self.platform_specific.x11_window_type = x11_window_type;
self
}
#[inline]
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 icon::Icon;
use event::Event;
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;
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.
///
@ -33,31 +34,31 @@ 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),
}
@ -69,7 +70,7 @@ impl WindowId {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DeviceId {
//X(x11::DeviceId),
X(x11::DeviceId),
Wayland(wayland::DeviceId),
}
@ -81,7 +82,7 @@ impl DeviceId {
#[derive(Debug, Clone)]
pub enum MonitorHandle {
//X(x11::MonitorHandle),
X(x11::MonitorHandle),
Wayland(wayland::MonitorHandle),
}
@ -89,7 +90,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(),
}
}
@ -97,7 +98,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(),
}
}
@ -105,7 +106,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(),
}
}
@ -113,7 +114,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(),
}
}
@ -121,7 +122,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,
}
}
@ -138,16 +139,16 @@ impl Window {
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)
//},
EventLoopWindowTarget::X(ref window_target) => {
x11::Window::new(window_target, 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()),
}
}
@ -155,7 +156,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),
}
}
@ -163,7 +164,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(),
}
}
@ -171,7 +172,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(),
}
}
@ -179,7 +180,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(),
}
}
@ -187,7 +188,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(),
}
}
@ -195,7 +196,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),
}
}
@ -203,7 +204,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(),
}
}
@ -211,7 +212,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(),
}
}
@ -219,7 +220,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),
}
}
@ -227,7 +228,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),
}
}
@ -235,7 +236,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),
}
}
@ -243,7 +244,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),
}
}
@ -251,7 +252,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)
}
}
@ -259,7 +260,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),
}
}
@ -267,7 +268,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),
}
}
@ -275,7 +276,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,
}
}
@ -283,7 +284,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),
}
}
@ -291,7 +292,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),
}
}
@ -299,7 +300,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)
}
}
@ -307,7 +308,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)
}
}
@ -315,7 +316,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(_) => (),
}
}
@ -323,7 +324,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(_) => (),
}
}
@ -331,7 +332,7 @@ 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(_) => (),
}
}
@ -339,7 +340,7 @@ impl Window {
#[inline]
pub fn request_redraw(&self) {
match self {
//&Window::X(ref w) => w.request_redraw(),
&Window::X(ref w) => w.request_redraw(),
&Window::Wayland(ref w) => w.request_redraw(),
}
}
@ -347,7 +348,7 @@ impl Window {
#[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()) },
}
}
@ -355,10 +356,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)
@ -369,13 +370,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,
@ -405,16 +406,16 @@ unsafe extern "C" fn x_error_callback(
// Fun fact: this return value is completely ignored.
0
}
*/
pub enum EventLoop<T: 'static> {
Wayland(wayland::EventLoop<T>),
//X(x11::EventLoop)
X(x11::EventLoop<T>)
}
#[derive(Clone)]
pub enum EventLoopProxy<T: 'static> {
//X(x11::EventLoopProxy),
X(x11::EventLoopProxy<T>),
Wayland(wayland::EventLoopProxy<T>),
}
@ -460,15 +461,14 @@ impl<T:'static> EventLoop<T> {
.map(EventLoop::Wayland)
}
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!()
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())
}
#[inline]
@ -479,12 +479,12 @@ impl<T:'static> EventLoop<T> {
.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(),
}
}
@ -492,14 +492,14 @@ impl<T:'static> EventLoop<T> {
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<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()),
}
}
@ -508,7 +508,7 @@ impl<T:'static> EventLoop<T> {
{
match *self {
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 {
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 {
match *self {
EventLoop::Wayland(_) => true,
//EventLoop::X(_) => false,
EventLoop::X(_) => false,
}
}
pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> {
match *self {
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> {
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(),
EventLoopProxy::X(ref proxy) => proxy.send_event(event),
}
}
}
pub enum 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::ModifiersState;
use dpi::{PhysicalPosition, PhysicalSize};
use platform_impl::platform::sticky_exit_callback;
use super::window::WindowStore;
use super::WindowId;
@ -204,23 +205,39 @@ impl<T: 'static> EventLoop<T> {
// empty buffer of events
{
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
{
let mut guard = user_events.borrow_mut();
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
);
}
}
callback(::event::Event::EventsCleared, &self.window_target, &mut control_flow);
// fo a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
// do a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
// in response of resize & friends
self.post_dispatch_triggers();
{
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

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 {PhysicalPosition, PhysicalSize};
use dpi::{PhysicalPosition, PhysicalSize};
use super::{util, XConnection, XError};
use super::ffi::{
RRCrtcChangeNotifyMask,

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
use std::{cmp, env, mem};
use std::collections::HashSet;
use std::ffi::CString;
use std::os::raw::*;
use std::path::Path;
@ -7,15 +8,15 @@ use std::sync::Arc;
use libc;
use parking_lot::Mutex;
use {Icon, MouseCursor, WindowAttributes};
use CreationError::{self, OsError};
use window::{Icon, MouseCursor, WindowAttributes};
use window::CreationError::{self, OsError};
use dpi::{LogicalPosition, LogicalSize};
use platform_impl::MonitorHandle as PlatformMonitorHandle;
use platform_impl::PlatformSpecificWindowBuilderAttributes;
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(
_display: *mut ffi::Display,
@ -66,11 +67,12 @@ pub struct UnownedWindow {
ime_sender: Mutex<ImeSender>,
pub multitouch: bool, // never changes
pub shared_state: Mutex<SharedState>,
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
}
impl UnownedWindow {
pub fn new(
event_loop: &EventLoop,
pub fn new<T>(
event_loop: &EventLoopWindowTarget<T>,
window_attrs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<UnownedWindow, CreationError> {
@ -203,6 +205,7 @@ impl UnownedWindow {
ime_sender: Mutex::new(event_loop.ime_sender.clone()),
multitouch: window_attrs.multitouch,
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
@ -1210,4 +1213,9 @@ impl UnownedWindow {
#[inline]
pub fn id(&self) -> WindowId { WindowId(self.xwindow) }
#[inline]
pub fn request_redraw(&self) {
self.pending_redraws.lock().unwrap().insert(WindowId(self.xwindow));
}
}