From cf0b8babbdb39abc443c94c8a94281201e6e9b0c Mon Sep 17 00:00:00 2001 From: Hal Gentz Date: Thu, 8 Aug 2019 14:50:22 -0700 Subject: [PATCH] Add new `EventLoopWindowTargetExtUnix` trait. (#1026) * Add new `EventLoopWindowTargetExtUnix` trait. Signed-off-by: Hal Gentz * Slide. Signed-off-by: Hal Gentz * Travis, damn you. Signed-off-by: Hal Gentz * Update CHANGELOG.md --- CHANGELOG.md | 1 + src/platform/unix.rs | 99 ++++++++++--------- src/platform_impl/linux/mod.rs | 26 ++--- src/platform_impl/linux/wayland/event_loop.rs | 10 +- src/platform_impl/linux/x11/mod.rs | 25 ++--- 5 files changed, 89 insertions(+), 72 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f35ef9..8c73544e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Removed the `T: Clone` requirement from the `Clone` impl of `EventLoopProxy`. - On iOS, disable overscan compensation for external displays (removes black bars surrounding the image). +- On Linux, the functions `is_wayland`, `is_x11`, `xlib_xconnection` and `wayland_display` have been moved to a new `EventLoopWindowTargetExtUnix` trait. # 0.20.0 Alpha 2 (2019-07-09) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 494ed398..eb9675e4 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -6,14 +6,15 @@ use smithay_client_toolkit::window::{ButtonState, Theme}; use crate::{ dpi::LogicalSize, - event_loop::EventLoop, + event_loop::{EventLoop, EventLoopWindowTarget}, monitor::MonitorHandle, window::{Window, WindowBuilder}, }; use crate::platform_impl::{ x11::{ffi::XVisualInfo, XConnection}, - EventLoop as LinuxEventLoop, Window as LinuxWindow, + EventLoop as LinuxEventLoop, EventLoopWindowTarget as LinuxEventLoopWindowTarget, + Window as LinuxWindow, }; // TODO: stupid hack so that glutin can do its work @@ -90,6 +91,57 @@ impl Theme for WaylandThemeObject { } } +/// Additional methods on `EventLoopWindowTarget` that are specific to Unix. +pub trait EventLoopWindowTargetExtUnix { + /// True if the `EventLoopWindowTarget` uses Wayland. + fn is_wayland(&self) -> bool; + /// + /// True if the `EventLoopWindowTarget` uses X11. + fn is_x11(&self) -> bool; + + #[doc(hidden)] + fn xlib_xconnection(&self) -> Option>; + + /// Returns a pointer to the `wl_display` object of wayland that is used by this + /// `EventLoopWindowTarget`. + /// + /// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example). + /// + /// The pointer will become invalid when the winit `EventLoop` is destroyed. + fn wayland_display(&self) -> Option<*mut raw::c_void>; +} + +impl EventLoopWindowTargetExtUnix for EventLoopWindowTarget { + #[inline] + fn is_wayland(&self) -> bool { + self.p.is_wayland() + } + + #[inline] + fn is_x11(&self) -> bool { + !self.p.is_wayland() + } + + #[inline] + #[doc(hidden)] + fn xlib_xconnection(&self) -> Option> { + match self.p { + LinuxEventLoopWindowTarget::X(ref e) => Some(e.x_connection().clone()), + _ => None, + } + } + + #[inline] + fn wayland_display(&self) -> Option<*mut raw::c_void> { + match self.p { + LinuxEventLoopWindowTarget::Wayland(ref p) => { + Some(p.display().get_display_ptr() as *mut _) + } + _ => None, + } + } +} + /// Additional methods on `EventLoop` that are specific to Unix. pub trait EventLoopExtUnix { /// Builds a new `EventLoops` that is forced to use X11. @@ -101,22 +153,6 @@ pub trait EventLoopExtUnix { fn new_wayland() -> Self where Self: Sized; - - /// True if the `EventLoop` uses Wayland. - fn is_wayland(&self) -> bool; - - /// True if the `EventLoop` uses X11. - fn is_x11(&self) -> bool; - - #[doc(hidden)] - fn xlib_xconnection(&self) -> Option>; - - /// Returns a pointer to the `wl_display` object of wayland that is used by this `EventLoop`. - /// - /// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example). - /// - /// The pointer will become invalid when the glutin `EventLoop` is destroyed. - fn wayland_display(&self) -> Option<*mut raw::c_void>; } impl EventLoopExtUnix for EventLoop { @@ -138,33 +174,6 @@ impl EventLoopExtUnix for EventLoop { _marker: ::std::marker::PhantomData, } } - - #[inline] - fn is_wayland(&self) -> bool { - self.event_loop.is_wayland() - } - - #[inline] - fn is_x11(&self) -> bool { - !self.event_loop.is_wayland() - } - - #[inline] - #[doc(hidden)] - fn xlib_xconnection(&self) -> Option> { - match self.event_loop { - LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()), - _ => None, - } - } - - #[inline] - fn wayland_display(&self) -> Option<*mut raw::c_void> { - match self.event_loop { - LinuxEventLoop::Wayland(ref e) => Some(e.display().get_display_ptr() as *mut _), - _ => None, - } - } } /// Additional methods on `Window` that are specific to Unix. diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 93238d60..f036f9f0 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -6,7 +6,7 @@ use parking_lot::Mutex; use smithay_client_toolkit::reexports::client::ConnectError; pub use self::x11::XNotSupported; -use self::x11::{ffi::XVisualInfo, XConnection, XError}; +use self::x11::{ffi::XVisualInfo, get_xtarget, XConnection, XError}; use crate::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}, error::{ExternalError, NotSupportedError, OsError as RootOsError}, @@ -550,7 +550,7 @@ impl EventLoop { .into_iter() .map(MonitorHandle::Wayland) .collect(), - EventLoop::X(ref evlp) => evlp + EventLoop::X(ref evlp) => get_xtarget(&evlp.target) .x_connection() .available_monitors() .into_iter() @@ -563,7 +563,9 @@ impl EventLoop { pub fn primary_monitor(&self) -> MonitorHandle { match *self { EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.primary_monitor()), - EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().primary_monitor()), + EventLoop::X(ref evlp) => { + MonitorHandle::X(get_xtarget(&evlp.target).x_connection().primary_monitor()) + } } } @@ -594,14 +596,6 @@ impl EventLoop { } } - #[inline] - pub fn is_wayland(&self) -> bool { - match *self { - EventLoop::Wayland(_) => true, - EventLoop::X(_) => false, - } - } - pub fn window_target(&self) -> &crate::event_loop::EventLoopWindowTarget { match *self { EventLoop::Wayland(ref evl) => evl.window_target(), @@ -624,6 +618,16 @@ pub enum EventLoopWindowTarget { X(x11::EventLoopWindowTarget), } +impl EventLoopWindowTarget { + #[inline] + pub fn is_wayland(&self) -> bool { + match *self { + EventLoopWindowTarget::Wayland(_) => true, + EventLoopWindowTarget::X(_) => false, + } + } +} + fn sticky_exit_callback( evt: Event, target: &RootELW, diff --git a/src/platform_impl/linux/wayland/event_loop.rs b/src/platform_impl/linux/wayland/event_loop.rs index 8c4cfa65..fa1ef347 100644 --- a/src/platform_impl/linux/wayland/event_loop.rs +++ b/src/platform_impl/linux/wayland/event_loop.rs @@ -390,15 +390,17 @@ impl EventLoop { available_monitors(&self.outputs) } - pub fn display(&self) -> &Display { - &*self.display - } - pub fn window_target(&self) -> &RootELW { &self.window_target } } +impl EventLoopWindowTarget { + pub fn display(&self) -> &Display { + &*self.display + } +} + /* * Private EventLoop Internals */ diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index b239c571..420dfb2d 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -63,7 +63,7 @@ pub struct EventLoop { event_processor: Rc>>, user_sender: ::calloop::channel::Sender, pending_events: Rc>>>, - target: Rc>, + pub(crate) target: Rc>, } pub struct EventLoopProxy { @@ -232,12 +232,6 @@ impl EventLoop { result } - /// Returns the `XConnection` of this events loop. - #[inline] - pub fn x_connection(&self) -> &Arc { - &get_xtarget(&self.target).xconn - } - pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { user_sender: self.user_sender.clone(), @@ -413,11 +407,18 @@ fn drain_events( } } -fn get_xtarget(rt: &RootELW) -> &EventLoopWindowTarget { - if let super::EventLoopWindowTarget::X(ref target) = rt.p { - target - } else { - unreachable!(); +pub(crate) fn get_xtarget(target: &RootELW) -> &EventLoopWindowTarget { + match target.p { + super::EventLoopWindowTarget::X(ref target) => target, + _ => unreachable!(), + } +} + +impl EventLoopWindowTarget { + /// Returns the `XConnection` of this events loop. + #[inline] + pub fn x_connection(&self) -> &Arc { + &self.xconn } }