Add new EventLoopWindowTargetExtUnix trait. (#1026)

* Add new `EventLoopWindowTargetExtUnix` trait.

Signed-off-by: Hal Gentz <zegentzy@protonmail.com>

* Slide.

Signed-off-by: Hal Gentz <zegentzy@protonmail.com>

* Travis, damn you.

Signed-off-by: Hal Gentz <zegentzy@protonmail.com>

* Update CHANGELOG.md
This commit is contained in:
Hal Gentz 2019-08-08 14:50:22 -07:00 committed by GitHub
parent c0c22c8ff1
commit cf0b8babbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 72 deletions

View file

@ -18,6 +18,7 @@
- Removed the `T: Clone` requirement from the `Clone` impl of `EventLoopProxy<T>`.
- 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)

View file

@ -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<Arc<XConnection>>;
/// 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<T> EventLoopWindowTargetExtUnix for EventLoopWindowTarget<T> {
#[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<Arc<XConnection>> {
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<Arc<XConnection>>;
/// 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<T> EventLoopExtUnix for EventLoop<T> {
@ -138,33 +174,6 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
_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<Arc<XConnection>> {
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.

View file

@ -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<T: 'static> EventLoop<T> {
.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<T: 'static> EventLoop<T> {
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<T: 'static> EventLoop<T> {
}
}
#[inline]
pub fn is_wayland(&self) -> bool {
match *self {
EventLoop::Wayland(_) => true,
EventLoop::X(_) => false,
}
}
pub fn window_target(&self) -> &crate::event_loop::EventLoopWindowTarget<T> {
match *self {
EventLoop::Wayland(ref evl) => evl.window_target(),
@ -624,6 +618,16 @@ pub enum EventLoopWindowTarget<T> {
X(x11::EventLoopWindowTarget<T>),
}
impl<T> EventLoopWindowTarget<T> {
#[inline]
pub fn is_wayland(&self) -> bool {
match *self {
EventLoopWindowTarget::Wayland(_) => true,
EventLoopWindowTarget::X(_) => false,
}
}
}
fn sticky_exit_callback<T, F>(
evt: Event<T>,
target: &RootELW<T>,

View file

@ -390,15 +390,17 @@ impl<T: 'static> EventLoop<T> {
available_monitors(&self.outputs)
}
pub fn display(&self) -> &Display {
&*self.display
}
pub fn window_target(&self) -> &RootELW<T> {
&self.window_target
}
}
impl<T> EventLoopWindowTarget<T> {
pub fn display(&self) -> &Display {
&*self.display
}
}
/*
* Private EventLoop Internals
*/

View file

@ -63,7 +63,7 @@ pub struct EventLoop<T: 'static> {
event_processor: Rc<RefCell<EventProcessor<T>>>,
user_sender: ::calloop::channel::Sender<T>,
pending_events: Rc<RefCell<VecDeque<Event<T>>>>,
target: Rc<RootELW<T>>,
pub(crate) target: Rc<RootELW<T>>,
}
pub struct EventLoopProxy<T: 'static> {
@ -232,12 +232,6 @@ impl<T: 'static> EventLoop<T> {
result
}
/// Returns the `XConnection` of this events loop.
#[inline]
pub fn x_connection(&self) -> &Arc<XConnection> {
&get_xtarget(&self.target).xconn
}
pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy {
user_sender: self.user_sender.clone(),
@ -413,11 +407,18 @@ fn drain_events<T: 'static>(
}
}
fn get_xtarget<T>(rt: &RootELW<T>) -> &EventLoopWindowTarget<T> {
if let super::EventLoopWindowTarget::X(ref target) = rt.p {
target
} else {
unreachable!();
pub(crate) fn get_xtarget<T>(target: &RootELW<T>) -> &EventLoopWindowTarget<T> {
match target.p {
super::EventLoopWindowTarget::X(ref target) => target,
_ => unreachable!(),
}
}
impl<T> EventLoopWindowTarget<T> {
/// Returns the `XConnection` of this events loop.
#[inline]
pub fn x_connection(&self) -> &Arc<XConnection> {
&self.xconn
}
}