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

@ -64,8 +64,9 @@ features = [
]
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] }
smithay-client-toolkit = "0.4.3"
wayland-client = { version = "0.23.0", features = [ "dlopen", "egl", "cursor", "eventloop"] }
calloop = "0.4.2"
smithay-client-toolkit = "0.6"
x11-dl = "2.18.3"
parking_lot = "0.7"
percent-encoding = "1.0"

View file

@ -163,11 +163,11 @@ impl<T> Deref for EventLoop<T> {
/// Used to send custom events to `EventLoop`.
#[derive(Clone)]
pub struct EventLoopProxy<T> {
pub struct EventLoopProxy<T: 'static> {
event_loop_proxy: platform_impl::EventLoopProxy<T>,
}
impl<T> EventLoopProxy<T> {
impl<T: 'static> EventLoopProxy<T> {
/// Send an event to the `EventLoop` from which this proxy was created. This emits a
/// `UserEvent(event)` event in the event loop, where `event` is the value passed to this
/// function.
@ -178,7 +178,7 @@ impl<T> EventLoopProxy<T> {
}
}
impl<T> fmt::Debug for EventLoopProxy<T> {
impl<T: 'static> fmt::Debug for EventLoopProxy<T> {
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
fmtr.pad("EventLoopProxy { .. }")
}

View file

@ -111,6 +111,8 @@ extern crate parking_lot;
extern crate percent_encoding;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
extern crate smithay_client_toolkit as sctk;
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
extern crate calloop;
pub mod dpi;
pub mod event;

View file

@ -6,26 +6,24 @@ use std::sync::Arc;
use sctk::window::{ButtonState, Theme};
use {
EventLoop,
LogicalSize,
MonitorHandle,
Window,
WindowBuilder,
};
use dpi::LogicalSize;
use event_loop::EventLoop;
use monitor::MonitorHandle;
use window::{Window, WindowBuilder};
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
///
@ -97,9 +95,9 @@ impl Theme for WaylandThemeObject {
/// Additional methods on `EventLoop` that are specific to Unix.
pub trait EventLoopExtUnix {
/// Builds a new `EventsLoop` that is forced to use X11.
fn new_x11() -> Result<Self, XNotSupported>
where Self: Sized;
/// Builds a new `EventLoops` that is forced to use X11.
//fn new_x11() -> Result<Self, XNotSupported>
// where Self: Sized;
/// Builds a new `EventLoop` that is forced to use Wayland.
fn new_wayland() -> Self
@ -111,20 +109,20 @@ 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>>;
}
impl EventLoopExtUnix for EventLoop {
#[inline]
fn new_x11() -> Result<Self, XNotSupported> {
LinuxEventLoop::new_x11().map(|ev|
EventLoop {
event_loop: ev,
_marker: ::std::marker::PhantomData,
}
)
}
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_wayland() -> Self {
@ -147,11 +145,11 @@ impl EventLoopExtUnix for EventLoop {
!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>> {
// self.event_loop.x_connection().cloned()
//}
}
/// Additional methods on `Window` that are specific to Unix.
@ -170,8 +168,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);
@ -214,7 +212,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
}
}
@ -222,7 +220,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
}
}
@ -230,39 +228,39 @@ 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]
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_surface().c_ptr() as *mut _),
LinuxWindow::Wayland(ref w) => Some(w.get_surface().as_ref().c_ptr() as *mut _),
_ => None
}
}
@ -270,7 +268,7 @@ impl WindowExtUnix for Window {
#[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_display().c_ptr() as *mut _),
LinuxWindow::Wayland(ref w) => Some(w.get_display().as_ref().c_ptr() as *mut _),
_ => None
}
}
@ -299,7 +297,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.
@ -318,9 +316,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
}
@ -342,11 +340,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

@ -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>)
}

View file

@ -1,10 +1,13 @@
use std::cell::RefCell;
use std::collections::VecDeque;
use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, Weak};
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use {ControlFlow, EventLoopClosed, PhysicalPosition, PhysicalSize};
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
use event::ModifiersState;
use dpi::{PhysicalPosition, PhysicalSize};
use super::window::WindowStore;
use super::WindowId;
@ -13,54 +16,61 @@ use sctk::output::OutputMgr;
use sctk::reexports::client::protocol::{
wl_keyboard, wl_output, wl_pointer, wl_registry, wl_seat, wl_touch,
};
use sctk::reexports::client::{ConnectError, Display, EventQueue, GlobalEvent, Proxy};
use sctk::reexports::client::{ConnectError, Display, EventQueue, GlobalEvent};
use sctk::Environment;
use sctk::reexports::client::protocol::wl_display::RequestsTrait as DisplayRequests;
use sctk::reexports::client::protocol::wl_surface::RequestsTrait;
use ModifiersState;
pub struct EventLoopSink {
buffer: VecDeque<::Event>,
pub struct WindowEventsSink {
buffer: VecDeque<(::event::WindowEvent, ::window::WindowId)>,
}
impl EventLoopSink {
pub fn new() -> EventLoopSink {
EventLoopSink {
impl WindowEventsSink {
pub fn new() -> WindowEventsSink {
WindowEventsSink {
buffer: VecDeque::new(),
}
}
pub fn send_event(&mut self, evt: ::WindowEvent, wid: WindowId) {
let evt = ::Event::WindowEvent {
event: evt,
window_id: ::WindowId(::platform::WindowId::Wayland(wid)),
};
self.buffer.push_back(evt);
pub fn send_event(&mut self, evt: ::event::WindowEvent, wid: WindowId) {
self.buffer.push_back((evt, ::window::WindowId(::platform_impl::WindowId::Wayland(wid))));
}
pub fn send_raw_event(&mut self, evt: ::Event) {
self.buffer.push_back(evt);
}
fn empty_with<F>(&mut self, callback: &mut F)
fn empty_with<F, T>(&mut self, mut callback: F)
where
F: FnMut(::Event),
F: FnMut(::event::Event<T>),
{
for evt in self.buffer.drain(..) {
callback(evt)
for (evt, wid) in self.buffer.drain(..) {
callback(::event::Event::WindowEvent { event: evt, window_id: wid})
}
}
}
pub struct EventLoop {
// The Event Queue
pub evq: RefCell<EventQueue>,
pub struct EventLoop<T: 'static> {
// The loop
inner_loop: ::calloop::EventLoop<()>,
// The wayland display
pub display: Arc<Display>,
// the output manager
pub outputs: OutputMgr,
// our sink, shared with some handlers, buffering the events
sink: Arc<Mutex<EventLoopSink>>,
// Whether or not there is a pending `Awakened` event to be emitted.
pending_wakeup: Arc<AtomicBool>,
sink: Arc<Mutex<WindowEventsSink>>,
pending_user_events: Rc<RefCell<VecDeque<T>>>,
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
user_sender: ::calloop::channel::Sender<T>,
_kbd_source: ::calloop::Source<::calloop::channel::Channel<(::event::WindowEvent, super::WindowId)>>,
window_target: RootELW<T>
}
// A handle that can be sent across threads and used to wake up the `EventLoop`.
//
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
#[derive(Clone)]
pub struct EventLoopProxy<T: 'static> {
user_sender: ::calloop::channel::Sender<T>
}
pub struct EventLoopWindowTarget<T> {
// the event queue
pub evq: RefCell<::calloop::Source<EventQueue>>,
// The window store
pub store: Arc<Mutex<WindowStore>>,
// the env
@ -70,57 +80,40 @@ pub struct EventLoop {
// The wayland display
pub display: Arc<Display>,
// The list of seats
pub seats: Arc<Mutex<Vec<(u32, Proxy<wl_seat::WlSeat>)>>>,
pub seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
_marker: ::std::marker::PhantomData<T>
}
// A handle that can be sent across threads and used to wake up the `EventLoop`.
//
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
#[derive(Clone)]
pub struct EventLoopProxy {
display: Weak<Display>,
pending_wakeup: Weak<AtomicBool>,
}
impl EventLoopProxy {
// Causes the `EventLoop` to stop blocking on `run_forever` and emit an `Awakened` event.
//
// Returns `Err` if the associated `EventLoop` no longer exists.
pub fn wakeup(&self) -> Result<(), EventLoopClosed> {
let display = self.display.upgrade();
let wakeup = self.pending_wakeup.upgrade();
match (display, wakeup) {
(Some(display), Some(wakeup)) => {
// Update the `EventLoop`'s `pending_wakeup` flag.
wakeup.store(true, Ordering::Relaxed);
// Cause the `EventLoop` to break from `dispatch` if it is currently blocked.
let _ = display.sync(|callback| callback.implement(|_, _| {}, ()));
display.flush().map_err(|_| EventLoopClosed)?;
Ok(())
}
_ => Err(EventLoopClosed),
}
impl<T: 'static> EventLoopProxy<T> {
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
self.user_sender.send(event).map_err(|_| EventLoopClosed)
}
}
impl EventLoop {
pub fn new() -> Result<EventLoop, ConnectError> {
impl<T: 'static> EventLoop<T> {
pub fn new() -> Result<EventLoop<T>, ConnectError> {
let (display, mut event_queue) = Display::connect_to_env()?;
let display = Arc::new(display);
let pending_wakeup = Arc::new(AtomicBool::new(false));
let sink = Arc::new(Mutex::new(EventLoopSink::new()));
let sink = Arc::new(Mutex::new(WindowEventsSink::new()));
let store = Arc::new(Mutex::new(WindowStore::new()));
let seats = Arc::new(Mutex::new(Vec::new()));
let inner_loop = ::calloop::EventLoop::new().unwrap();
let (kbd_sender, kbd_channel) = ::calloop::channel::channel();
let kbd_sink = sink.clone();
let kbd_source = inner_loop.handle().insert_source(kbd_channel, move |evt, &mut()| {
if let ::calloop::channel::Event::Msg((evt, wid)) = evt {
kbd_sink.lock().unwrap().send_event(evt, wid);
}
}).unwrap();
let mut seat_manager = SeatManager {
sink: sink.clone(),
store: store.clone(),
seats: seats.clone(),
events_loop_proxy: EventsLoopProxy {
display: Arc::downgrade(&display),
pending_wakeup: Arc::downgrade(&pending_wakeup),
},
kbd_sender,
};
let env = Environment::from_display_with_cb(
@ -142,92 +135,160 @@ impl EventLoop {
},
).unwrap();
let source = inner_loop.handle().insert_source(event_queue, |(), &mut ()| {}).unwrap();
let pending_user_events = Rc::new(RefCell::new(VecDeque::new()));
let pending_user_events2 = pending_user_events.clone();
let (user_sender, user_channel) = ::calloop::channel::channel();
let user_source = inner_loop.handle().insert_source(user_channel, move |evt, &mut()| {
if let ::calloop::channel::Event::Msg(msg) = evt {
pending_user_events2.borrow_mut().push_back(msg);
}
}).unwrap();
Ok(EventLoop {
display,
evq: RefCell::new(event_queue),
inner_loop,
sink,
pending_wakeup,
store,
env,
cleanup_needed: Arc::new(Mutex::new(false)),
seats,
pending_user_events,
display: display.clone(),
outputs: env.outputs.clone(),
_user_source: user_source,
user_sender,
_kbd_source: kbd_source,
window_target: RootELW {
p: ::platform_impl::EventLoopWindowTarget::Wayland(EventLoopWindowTarget {
evq: RefCell::new(source),
store,
env,
cleanup_needed: Arc::new(Mutex::new(false)),
seats,
display,
_marker: ::std::marker::PhantomData
}),
_marker: ::std::marker::PhantomData
}
})
}
pub fn create_proxy(&self) -> EventLoopProxy {
pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy {
display: Arc::downgrade(&self.display),
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
user_sender: self.user_sender.clone()
}
}
pub fn poll_events<F>(&mut self, mut callback: F)
where
F: FnMut(::Event),
pub fn run<F>(mut self, callback: F) -> !
where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{
self.run_return(callback);
::std::process::exit(0);
}
pub fn run_return<F>(&mut self, mut callback: F)
where F: FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{
// send pending events to the server
self.display.flush().expect("Wayland connection lost.");
// dispatch any pre-buffered events
self.sink.lock().unwrap().empty_with(&mut callback);
let mut control_flow = ControlFlow::default();
// try to read pending events
if let Some(h) = self.evq.get_mut().prepare_read() {
h.read_events().expect("Wayland connection lost.");
}
// dispatch wayland events
self.evq
.get_mut()
.dispatch_pending()
.expect("Wayland connection lost.");
self.post_dispatch_triggers();
let sink = self.sink.clone();
let user_events = self.pending_user_events.clone();
// dispatch buffered events to client
self.sink.lock().unwrap().empty_with(&mut callback);
}
pub fn run_forever<F>(&mut self, mut callback: F)
where
F: FnMut(::Event) -> ControlFlow,
{
// send pending events to the server
self.display.flush().expect("Wayland connection lost.");
// Check for control flow by wrapping the callback.
let control_flow = ::std::cell::Cell::new(ControlFlow::Continue);
let mut callback = |event| {
if let ControlFlow::Break = callback(event) {
control_flow.set(ControlFlow::Break);
}
};
// dispatch any pre-buffered events
self.post_dispatch_triggers();
self.sink.lock().unwrap().empty_with(&mut callback);
callback(::event::Event::NewEvents(::event::StartCause::Init), &self.window_target, &mut control_flow);
loop {
// dispatch events blocking if needed
self.evq
.get_mut()
.dispatch()
.expect("Wayland connection lost.");
self.post_dispatch_triggers();
// empty buffer of events
self.sink.lock().unwrap().empty_with(&mut callback);
{
let mut guard = sink.lock().unwrap();
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow));
}
// 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);
}
}
if let ControlFlow::Break = control_flow.get() {
break;
callback(::event::Event::EventsCleared, &self.window_target, &mut control_flow);
// fo a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
self.post_dispatch_triggers();
{
let mut guard = sink.lock().unwrap();
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow));
}
// send pending events to the server
self.display.flush().expect("Wayland connection lost.");
match control_flow {
ControlFlow::Exit => break,
ControlFlow::Poll => {
// non-blocking dispatch
self.inner_loop.dispatch(Some(::std::time::Duration::from_millis(0)), &mut ()).unwrap();
control_flow = ControlFlow::default();
callback(::event::Event::NewEvents(::event::StartCause::Poll), &self.window_target, &mut control_flow);
},
ControlFlow::Wait => {
self.inner_loop.dispatch(None, &mut ()).unwrap();
control_flow = ControlFlow::default();
callback(
::event::Event::NewEvents(::event::StartCause::WaitCancelled {
start: Instant::now(),
requested_resume: None
}),
&self.window_target,
&mut control_flow
);
},
ControlFlow::WaitUntil(deadline) => {
let start = Instant::now();
// compute the blocking duration
let duration = deadline.duration_since(::std::cmp::max(deadline, start));
self.inner_loop.dispatch(Some(duration), &mut ()).unwrap();
control_flow = ControlFlow::default();
let now = Instant::now();
if now < deadline {
callback(
::event::Event::NewEvents(::event::StartCause::WaitCancelled {
start,
requested_resume: Some(deadline)
}),
&self.window_target,
&mut control_flow
);
} else {
callback(
::event::Event::NewEvents(::event::StartCause::ResumeTimeReached {
start,
requested_resume: deadline
}),
&self.window_target,
&mut control_flow
);
}
},
}
}
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
}
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.env.outputs)
get_primary_monitor(&self.outputs)
}
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.env.outputs)
get_available_monitors(&self.outputs)
}
pub fn window_target(&self) -> &RootELW<T> {
&self.window_target
}
}
@ -235,34 +296,33 @@ impl EventLoop {
* Private EventLoop Internals
*/
impl EventLoop {
impl<T> EventLoop<T> {
fn post_dispatch_triggers(&mut self) {
let mut sink = self.sink.lock().unwrap();
// process a possible pending wakeup call
if self.pending_wakeup.load(Ordering::Relaxed) {
sink.send_raw_event(::Event::Awakened);
self.pending_wakeup.store(false, Ordering::Relaxed);
}
let window_target = match self.window_target.p {
::platform_impl::EventLoopWindowTarget::Wayland(ref wt) => wt,
_ => unreachable!()
};
// prune possible dead windows
{
let mut cleanup_needed = self.cleanup_needed.lock().unwrap();
let mut cleanup_needed = window_target.cleanup_needed.lock().unwrap();
if *cleanup_needed {
let pruned = self.store.lock().unwrap().cleanup();
let pruned = window_target.store.lock().unwrap().cleanup();
*cleanup_needed = false;
for wid in pruned {
sink.send_event(::WindowEvent::Destroyed, wid);
sink.send_event(::event::WindowEvent::Destroyed, wid);
}
}
}
// process pending resize/refresh
self.store.lock().unwrap().for_each(
window_target.store.lock().unwrap().for_each(
|newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
if let Some(frame) = frame {
if let Some((w, h)) = newsize {
frame.resize(w, h);
frame.refresh();
let logical_size = ::LogicalSize::new(w as f64, h as f64);
sink.send_event(::WindowEvent::Resized(logical_size), wid);
let logical_size = ::dpi::LogicalSize::new(w as f64, h as f64);
sink.send_event(::event::WindowEvent::Resized(logical_size), wid);
*size = (w, h);
} else if frame_refresh {
frame.refresh();
@ -272,13 +332,13 @@ impl EventLoop {
}
}
if let Some(dpi) = new_dpi {
sink.send_event(::WindowEvent::HiDpiFactorChanged(dpi as f64), wid);
sink.send_event(::event::WindowEvent::HiDpiFactorChanged(dpi as f64), wid);
}
if refresh {
sink.send_event(::WindowEvent::Redraw, wid);
sink.send_event(::event::WindowEvent::RedrawRequested, wid);
}
if closed {
sink.send_event(::WindowEvent::CloseRequested, wid);
sink.send_event(::event::WindowEvent::CloseRequested, wid);
}
},
)
@ -290,15 +350,14 @@ impl EventLoop {
*/
struct SeatManager {
sink: Arc<Mutex<EventLoopSink>>,
sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>,
seats: Arc<Mutex<Vec<(u32, Proxy<wl_seat::WlSeat>)>>>,
event_loop_proxy: EventLoopProxy,
seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>
}
impl SeatManager {
fn add_seat(&mut self, id: u32, version: u32, registry: Proxy<wl_registry::WlRegistry>) {
use self::wl_registry::RequestsTrait as RegistryRequests;
fn add_seat(&mut self, id: u32, version: u32, registry: wl_registry::WlRegistry) {
use std::cmp::min;
let mut seat_data = SeatData {
@ -307,12 +366,12 @@ impl SeatManager {
pointer: None,
keyboard: None,
touch: None,
events_loop_proxy: self.events_loop_proxy.clone(),
kbd_sender: self.kbd_sender.clone(),
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
};
let seat = registry
.bind(min(version, 5), id, move |seat| {
seat.implement(move |event, seat| {
seat.implement_closure(move |event, seat| {
seat_data.receive(event, seat)
}, ())
})
@ -322,85 +381,28 @@ impl SeatManager {
}
fn remove_seat(&mut self, id: u32) {
use self::wl_seat::RequestsTrait as SeatRequests;
<<<<<<< HEAD:src/platform_impl/linux/wayland/event_loop.rs
match evt {
GlobalEvent::New {
id,
ref interface,
version,
} if interface == "wl_seat" =>
{
use std::cmp::min;
let mut seat_data = SeatData {
sink: self.sink.clone(),
store: self.store.clone(),
pointer: None,
keyboard: None,
touch: None,
events_loop_proxy: self.events_loop_proxy.clone(),
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
};
let seat = registry
<<<<<<< HEAD
.bind(min(version, 5), id, move |seat| {
seat.implement(move |event, seat| {
seat_data.receive(event, seat)
}, ())
})
.unwrap();
=======
.bind::<wl_seat::WlSeat>(min(version, 5), id)
.unwrap()
.implement(SeatData {
sink: self.sink.clone(),
store: self.store.clone(),
pointer: None,
keyboard: None,
touch: None,
event_loop_proxy: self.event_loop_proxy.clone(),
});
>>>>>>> Change instances of "events_loop" to "event_loop"
self.store.lock().unwrap().new_seat(&seat);
self.seats.lock().unwrap().push((id, seat));
}
GlobalEvent::Removed { id, ref interface } if interface == "wl_seat" => {
let mut seats = self.seats.lock().unwrap();
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
let (_, seat) = seats.swap_remove(idx);
if seat.version() >= 5 {
seat.release();
}
}
=======
let mut seats = self.seats.lock().unwrap();
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
let (_, seat) = seats.swap_remove(idx);
if seat.version() >= 5 {
if seat.as_ref().version() >= 5 {
seat.release();
>>>>>>> master:src/platform/linux/wayland/event_loop.rs
}
}
}
}
struct SeatData {
sink: Arc<Mutex<EventLoopSink>>,
sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>,
pointer: Option<Proxy<wl_pointer::WlPointer>>,
keyboard: Option<Proxy<wl_keyboard::WlKeyboard>>,
touch: Option<Proxy<wl_touch::WlTouch>>,
<<<<<<< HEAD
events_loop_proxy: EventsLoopProxy,
kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>,
pointer: Option<wl_pointer::WlPointer>,
keyboard: Option<wl_keyboard::WlKeyboard>,
touch: Option<wl_touch::WlTouch>,
modifiers_tracker: Arc<Mutex<ModifiersState>>,
=======
event_loop_proxy: EventLoopProxy,
>>>>>>> Change instances of "events_loop" to "event_loop"
}
impl SeatData {
fn receive(&mut self, evt: wl_seat::Event, seat: Proxy<wl_seat::WlSeat>) {
fn receive(&mut self, evt: wl_seat::Event, seat: wl_seat::WlSeat) {
match evt {
wl_seat::Event::Name { .. } => (),
wl_seat::Event::Capabilities { capabilities } => {
@ -416,8 +418,7 @@ impl SeatData {
// destroy pointer if applicable
if !capabilities.contains(wl_seat::Capability::Pointer) {
if let Some(pointer) = self.pointer.take() {
if pointer.version() >= 3 {
use self::wl_pointer::RequestsTrait;
if pointer.as_ref().version() >= 3 {
pointer.release();
}
}
@ -426,20 +427,14 @@ impl SeatData {
if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() {
self.keyboard = Some(super::keyboard::init_keyboard(
&seat,
self.sink.clone(),
<<<<<<< HEAD
self.events_loop_proxy.clone(),
self.kbd_sender.clone(),
self.modifiers_tracker.clone(),
=======
self.event_loop_proxy.clone(),
>>>>>>> Change instances of "events_loop" to "event_loop"
))
}
// destroy keyboard if applicable
if !capabilities.contains(wl_seat::Capability::Keyboard) {
if let Some(kbd) = self.keyboard.take() {
if kbd.version() >= 3 {
use self::wl_keyboard::RequestsTrait;
if kbd.as_ref().version() >= 3 {
kbd.release();
}
}
@ -455,13 +450,13 @@ impl SeatData {
// destroy touch if applicable
if !capabilities.contains(wl_seat::Capability::Touch) {
if let Some(touch) = self.touch.take() {
if touch.version() >= 3 {
use self::wl_touch::RequestsTrait;
if touch.as_ref().version() >= 3 {
touch.release();
}
}
}
}
},
_ => unreachable!()
}
}
}
@ -469,20 +464,17 @@ impl SeatData {
impl Drop for SeatData {
fn drop(&mut self) {
if let Some(pointer) = self.pointer.take() {
if pointer.version() >= 3 {
use self::wl_pointer::RequestsTrait;
if pointer.as_ref().version() >= 3 {
pointer.release();
}
}
if let Some(kbd) = self.keyboard.take() {
if kbd.version() >= 3 {
use self::wl_keyboard::RequestsTrait;
if kbd.as_ref().version() >= 3 {
kbd.release();
}
}
if let Some(touch) = self.touch.take() {
if touch.version() >= 3 {
use self::wl_touch::RequestsTrait;
if touch.as_ref().version() >= 3 {
touch.release();
}
}
@ -494,7 +486,7 @@ impl Drop for SeatData {
*/
pub struct MonitorHandle {
pub(crate) proxy: Proxy<wl_output::WlOutput>,
pub(crate) proxy: wl_output::WlOutput,
pub(crate) mgr: OutputMgr,
}

View file

@ -1,22 +1,18 @@
use std::sync::{Arc, Mutex};
use super::{make_wid, DeviceId, EventLoopProxy, EventLoopSink};
use super::{make_wid, DeviceId};
use sctk::keyboard::{
self, map_keyboard_auto_with_repeat, Event as KbEvent, KeyRepeatEvent, KeyRepeatKind,
};
use sctk::reexports::client::protocol::wl_keyboard;
use sctk::reexports::client::Proxy;
use sctk::reexports::client::protocol::wl_seat;
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
use sctk::reexports::client::protocol::{wl_keyboard, wl_seat};
use {ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};
use event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};
pub fn init_keyboard(
seat: &Proxy<wl_seat::WlSeat>,
sink: Arc<Mutex<EventLoopSink>>,
event_loop_proxy: EventLoopProxy,
seat: &wl_seat::WlSeat,
sink: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>,
modifiers_tracker: Arc<Mutex<ModifiersState>>,
) -> Proxy<wl_keyboard::WlKeyboard> {
) -> wl_keyboard::WlKeyboard {
// { variables to be captured by the closures
let target = Arc::new(Mutex::new(None));
let my_sink = sink.clone();
@ -30,18 +26,12 @@ pub fn init_keyboard(
move |evt: KbEvent, _| match evt {
KbEvent::Enter { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(true), wid);
my_sink.send((WindowEvent::Focused(true), wid)).unwrap();
*target.lock().unwrap() = Some(wid);
}
KbEvent::Leave { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(false), wid);
my_sink.send((WindowEvent::Focused(false), wid)).unwrap();
*target.lock().unwrap() = None;
}
KbEvent::Key {
@ -55,12 +45,12 @@ pub fn init_keyboard(
let state = match state {
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
wl_keyboard::KeyState::Released => ElementState::Released,
_ => unreachable!(),
};
let vkcode = key_to_vkey(rawkey, keysym);
let mut guard = my_sink.lock().unwrap();
guard.send_event(
WindowEvent::KeyboardInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
my_sink.send(
(WindowEvent::KeyboardInput {
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
input: KeyboardInput {
state: state,
scancode: rawkey,
@ -68,15 +58,15 @@ pub fn init_keyboard(
modifiers: modifiers_tracker.lock().unwrap().clone(),
},
},
wid,
);
wid)
).unwrap();
// send char event only on key press, not release
if let ElementState::Released = state {
return;
}
if let Some(txt) = utf8 {
for chr in txt.chars() {
guard.send_event(WindowEvent::ReceivedCharacter(chr), wid);
my_sink.send((WindowEvent::ReceivedCharacter(chr), wid)).unwrap();
}
}
}
@ -84,16 +74,15 @@ pub fn init_keyboard(
KbEvent::RepeatInfo { .. } => { /* Handled by smithay client toolkit */ }
KbEvent::Modifiers { modifiers: event_modifiers } => {
*modifiers_tracker.lock().unwrap() = event_modifiers.into()
}
},
},
move |repeat_event: KeyRepeatEvent, _| {
if let Some(wid) = *repeat_target.lock().unwrap() {
let state = ElementState::Pressed;
let vkcode = key_to_vkey(repeat_event.rawkey, repeat_event.keysym);
let mut guard = repeat_sink.lock().unwrap();
guard.send_event(
repeat_sink.send((
WindowEvent::KeyboardInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
input: KeyboardInput {
state: state,
scancode: repeat_event.rawkey,
@ -101,14 +90,13 @@ pub fn init_keyboard(
modifiers: my_modifiers.lock().unwrap().clone(),
},
},
wid,
);
wid)
).unwrap();
if let Some(txt) = repeat_event.utf8 {
for chr in txt.chars() {
guard.send_event(WindowEvent::ReceivedCharacter(chr), wid);
repeat_sink.send((WindowEvent::ReceivedCharacter(chr), wid)).unwrap();
}
}
event_loop_proxy.wakeup().unwrap();
}
},
);
@ -128,21 +116,15 @@ pub fn init_keyboard(
let my_sink = sink;
// }
seat.get_keyboard(|keyboard| {
keyboard.implement(move |evt, _| match evt {
keyboard.implement_closure(move |evt, _| match evt {
wl_keyboard::Event::Enter { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(true), wid);
my_sink.send((WindowEvent::Focused(true), wid)).unwrap();
target = Some(wid);
}
wl_keyboard::Event::Leave { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(false), wid);
my_sink.send((WindowEvent::Focused(false), wid)).unwrap();
target = None;
}
wl_keyboard::Event::Key { key, state, .. } => {
@ -150,10 +132,11 @@ pub fn init_keyboard(
let state = match state {
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
wl_keyboard::KeyState::Released => ElementState::Released,
_ => unreachable!()
};
my_sink.lock().unwrap().send_event(
my_sink.send((
WindowEvent::KeyboardInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
input: KeyboardInput {
state: state,
scancode: key,
@ -162,7 +145,7 @@ pub fn init_keyboard(
},
},
wid,
);
)).unwrap();
}
}
_ => (),

View file

@ -2,10 +2,9 @@
target_os = "netbsd", target_os = "openbsd"))]
pub use self::window::Window;
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopSink, MonitorHandle};
pub use self::event_loop::{EventLoop, EventLoopWindowTarget, EventLoopProxy, WindowEventsSink, MonitorHandle};
use sctk::reexports::client::protocol::wl_surface;
use sctk::reexports::client::Proxy;
mod event_loop;
mod pointer;
@ -32,6 +31,6 @@ impl WindowId {
}
#[inline]
fn make_wid(s: &Proxy<wl_surface::WlSurface>) -> WindowId {
WindowId(s.c_ptr() as usize)
fn make_wid(s: &wl_surface::WlSurface) -> WindowId {
WindowId(s.as_ref().c_ptr() as usize)
}

View file

@ -1,30 +1,27 @@
use std::sync::{Arc, Mutex};
use {ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent};
use events::ModifiersState;
use event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent, ModifiersState};
use super::DeviceId;
use super::event_loop::EventLoopSink;
use super::event_loop::WindowEventsSink;
use super::window::WindowStore;
use sctk::reexports::client::Proxy;
use sctk::reexports::client::protocol::wl_pointer::{self, Event as PtrEvent, WlPointer};
use sctk::reexports::client::protocol::wl_seat;
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
pub fn implement_pointer(
seat: &Proxy<wl_seat::WlSeat>,
sink: Arc<Mutex<EventLoopSink>>,
seat: &wl_seat::WlSeat,
sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>,
modifiers_tracker: Arc<Mutex<ModifiersState>>,
) -> Proxy<WlPointer> {
) -> WlPointer {
let mut mouse_focus = None;
let mut axis_buffer = None;
let mut axis_discrete_buffer = None;
let mut axis_state = TouchPhase::Ended;
seat.get_pointer(|pointer| {
pointer.implement(move |evt, pointer| {
pointer.implement_closure(move |evt, pointer| {
let mut sink = sink.lock().unwrap();
let store = store.lock().unwrap();
match evt {
@ -39,13 +36,13 @@ pub fn implement_pointer(
mouse_focus = Some(wid);
sink.send_event(
WindowEvent::CursorEntered {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
},
wid,
);
sink.send_event(
WindowEvent::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
position: (surface_x, surface_y).into(),
modifiers: modifiers_tracker.lock().unwrap().clone(),
},
@ -59,7 +56,7 @@ pub fn implement_pointer(
if let Some(wid) = wid {
sink.send_event(
WindowEvent::CursorLeft {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
},
wid,
);
@ -73,7 +70,7 @@ pub fn implement_pointer(
if let Some(wid) = mouse_focus {
sink.send_event(
WindowEvent::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
position: (surface_x, surface_y).into(),
modifiers: modifiers_tracker.lock().unwrap().clone(),
},
@ -86,6 +83,7 @@ pub fn implement_pointer(
let state = match state {
wl_pointer::ButtonState::Pressed => ElementState::Pressed,
wl_pointer::ButtonState::Released => ElementState::Released,
_ => unreachable!()
};
let button = match button {
0x110 => MouseButton::Left,
@ -96,7 +94,7 @@ pub fn implement_pointer(
};
sink.send_event(
WindowEvent::MouseInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
state: state,
button: button,
modifiers: modifiers_tracker.lock().unwrap().clone(),
@ -107,17 +105,18 @@ pub fn implement_pointer(
}
PtrEvent::Axis { axis, value, .. } => {
if let Some(wid) = mouse_focus {
if pointer.version() < 5 {
if pointer.as_ref().version() < 5 {
let (mut x, mut y) = (0.0, 0.0);
// old seat compatibility
match axis {
// wayland vertical sign convention is the inverse of winit
wl_pointer::Axis::VerticalScroll => y -= value as f32,
wl_pointer::Axis::HorizontalScroll => x += value as f32,
_ => unreachable!()
}
sink.send_event(
WindowEvent::MouseWheel {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()),
phase: TouchPhase::Moved,
modifiers: modifiers_tracker.lock().unwrap().clone(),
@ -130,6 +129,7 @@ pub fn implement_pointer(
// wayland vertical sign convention is the inverse of winit
wl_pointer::Axis::VerticalScroll => y -= value as f32,
wl_pointer::Axis::HorizontalScroll => x += value as f32,
_ => unreachable!()
}
axis_buffer = Some((x, y));
axis_state = match axis_state {
@ -146,7 +146,7 @@ pub fn implement_pointer(
if let Some((x, y)) = axis_discrete_buffer {
sink.send_event(
WindowEvent::MouseWheel {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::LineDelta(x as f32, y as f32),
phase: axis_state,
modifiers: modifiers_tracker.lock().unwrap().clone(),
@ -156,7 +156,7 @@ pub fn implement_pointer(
} else if let Some((x, y)) = axis_buffer {
sink.send_event(
WindowEvent::MouseWheel {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()),
phase: axis_state,
modifiers: modifiers_tracker.lock().unwrap().clone(),
@ -176,13 +176,15 @@ pub fn implement_pointer(
// wayland vertical sign convention is the inverse of winit
wl_pointer::Axis::VerticalScroll => y -= discrete,
wl_pointer::Axis::HorizontalScroll => x += discrete,
_ => unreachable!()
}
axis_discrete_buffer = Some((x, y));
axis_state = match axis_state {
TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved,
_ => TouchPhase::Started,
}
}
},
_ => unreachable!()
}
}, ())
}).unwrap()

View file

@ -1,15 +1,13 @@
use std::sync::{Arc, Mutex};
use {TouchPhase, WindowEvent};
use event::{TouchPhase, WindowEvent};
use super::{DeviceId, WindowId};
use super::event_loop::EventLoopSink;
use super::event_loop::WindowEventsSink;
use super::window::WindowStore;
use sctk::reexports::client::Proxy;
use sctk::reexports::client::protocol::wl_touch::{Event as TouchEvent, WlTouch};
use sctk::reexports::client::protocol::wl_seat;
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
struct TouchPoint {
wid: WindowId,
@ -18,13 +16,13 @@ struct TouchPoint {
}
pub(crate) fn implement_touch(
seat: &Proxy<wl_seat::WlSeat>,
sink: Arc<Mutex<EventLoopSink>>,
seat: &wl_seat::WlSeat,
sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>,
) -> Proxy<WlTouch> {
) -> WlTouch {
let mut pending_ids = Vec::new();
seat.get_touch(|touch| {
touch.implement(move |evt, _| {
touch.implement_closure(move |evt, _| {
let mut sink = sink.lock().unwrap();
let store = store.lock().unwrap();
match evt {
@ -34,8 +32,8 @@ pub(crate) fn implement_touch(
let wid = store.find_wid(&surface);
if let Some(wid) = wid {
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
WindowEvent::Touch(::event::Touch {
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Started,
location: (x, y).into(),
id: id as u64,
@ -54,8 +52,8 @@ pub(crate) fn implement_touch(
if let Some(idx) = idx {
let pt = pending_ids.remove(idx);
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
WindowEvent::Touch(::event::Touch {
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Ended,
location: pt.location.into(),
id: id as u64,
@ -69,8 +67,8 @@ pub(crate) fn implement_touch(
if let Some(pt) = pt {
pt.location = (x, y);
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
WindowEvent::Touch(::event::Touch {
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Moved,
location: (x, y).into(),
id: id as u64,
@ -82,8 +80,8 @@ pub(crate) fn implement_touch(
TouchEvent::Frame => (),
TouchEvent::Cancel => for pt in pending_ids.drain(..) {
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
WindowEvent::Touch(::event::Touch {
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Cancelled,
location: pt.location.into(),
id: pt.id as u64,
@ -91,6 +89,7 @@ pub(crate) fn implement_touch(
pt.wid,
);
},
_ => unreachable!()
}
}, ())
}).unwrap()

View file

@ -1,38 +1,33 @@
use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};
use {CreationError, MouseCursor, WindowAttributes};
use dpi::{LogicalPosition, LogicalSize};
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
use platform_impl::MonitorHandle as PlatformMonitorHandle;
use window::MonitorHandle as RootMonitorHandle;
=======
use platform::{MonitorId as PlatformMonitorId, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use window::MonitorId as RootMonitorId;
>>>>>>> master:src/platform/linux/wayland/window.rs
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use monitor::MonitorHandle as RootMonitorHandle;
use window::{CreationError, WindowAttributes, MouseCursor};
use sctk::surface::{get_dpi_factor, get_outputs};
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow, Theme};
use sctk::reexports::client::{Display, Proxy};
use sctk::reexports::client::Display;
use sctk::reexports::client::protocol::{wl_seat, wl_surface};
use sctk::reexports::client::protocol::wl_surface::RequestsTrait as SurfaceRequests;
use sctk::output::OutputMgr;
use super::{make_wid, EventLoop, MonitorHandle, WindowId};
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
pub struct Window {
surface: Proxy<wl_surface::WlSurface>,
surface: wl_surface::WlSurface,
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
outputs: OutputMgr, // Access to info for all monitors
size: Arc<Mutex<(u32, u32)>>,
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
display: Arc<Display>,
need_frame_refresh: Arc<Mutex<bool>>,
need_refresh: Arc<Mutex<bool>>
}
impl Window {
pub fn new(evlp: &EventLoop, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
// Create the window
let size = Arc::new(Mutex::new((width, height)));
@ -53,9 +48,9 @@ impl Window {
WEvent::Configure { new_size, .. } => {
let mut store = window_store.lock().unwrap();
for window in &mut store.windows {
if window.surface.equals(&my_surface) {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
window.newsize = new_size;
window.need_refresh = true;
*(window.need_refresh.lock().unwrap()) = true;
*(window.need_frame_refresh.lock().unwrap()) = true;
return;
}
@ -64,7 +59,7 @@ impl Window {
WEvent::Refresh => {
let store = window_store.lock().unwrap();
for window in &store.windows {
if window.surface.equals(&my_surface) {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
*(window.need_frame_refresh.lock().unwrap()) = true;
return;
}
@ -73,7 +68,7 @@ impl Window {
WEvent::Close => {
let mut store = window_store.lock().unwrap();
for window in &mut store.windows {
if window.surface.equals(&my_surface) {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
window.closed = true;
return;
}
@ -105,6 +100,9 @@ impl Window {
// set decorations
frame.set_decorate(attributes.decorations);
// set title
frame.set_title(attributes.title);
// min-max dimensions
frame.set_min_size(attributes.min_dimensions.map(Into::into));
frame.set_max_size(attributes.max_dimensions.map(Into::into));
@ -112,12 +110,13 @@ impl Window {
let kill_switch = Arc::new(Mutex::new(false));
let need_frame_refresh = Arc::new(Mutex::new(true));
let frame = Arc::new(Mutex::new(frame));
let need_refresh = Arc::new(Mutex::new(true));
evlp.store.lock().unwrap().windows.push(InternalWindow {
closed: false,
newsize: None,
size: size.clone(),
need_refresh: false,
need_refresh: need_refresh.clone(),
need_frame_refresh: need_frame_refresh.clone(),
surface: surface.clone(),
kill_switch: kill_switch.clone(),
@ -134,7 +133,8 @@ impl Window {
outputs: evlp.env.outputs.clone(),
size: size,
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
need_frame_refresh: need_frame_refresh,
need_frame_refresh,
need_refresh,
})
}
@ -178,6 +178,10 @@ impl Window {
Some(self.size.lock().unwrap().clone().into())
}
pub fn request_redraw(&self) {
*self.need_refresh.lock().unwrap() = true;
}
#[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
let (w, h) = self.size.lock().unwrap().clone();
@ -269,24 +273,16 @@ impl Window {
&*self.display
}
pub fn get_surface(&self) -> &Proxy<wl_surface::WlSurface> {
pub fn get_surface(&self) -> &wl_surface::WlSurface {
&self.surface
}
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
pub fn get_current_monitor(&self) -> MonitorHandle {
// we don't know how much each monitor sees us so...
// just return the most recent one ?
let guard = self.monitors.lock().unwrap();
guard.monitors.last().unwrap().clone()
=======
pub fn get_current_monitor(&self) -> MonitorId {
let output = get_outputs(&self.surface).last().unwrap().clone();
MonitorId {
MonitorHandle {
proxy: output,
mgr: self.outputs.clone(),
}
>>>>>>> master:src/platform/linux/wayland/window.rs
}
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
@ -310,10 +306,10 @@ impl Drop for Window {
*/
struct InternalWindow {
surface: Proxy<wl_surface::WlSurface>,
surface: wl_surface::WlSurface,
newsize: Option<(u32, u32)>,
size: Arc<Mutex<(u32, u32)>>,
need_refresh: bool,
need_refresh: Arc<Mutex<bool>>,
need_frame_refresh: Arc<Mutex<bool>>,
closed: bool,
kill_switch: Arc<Mutex<bool>>,
@ -333,9 +329,9 @@ impl WindowStore {
}
}
pub fn find_wid(&self, surface: &Proxy<wl_surface::WlSurface>) -> Option<WindowId> {
pub fn find_wid(&self, surface: &wl_surface::WlSurface) -> Option<WindowId> {
for window in &self.windows {
if surface.equals(&window.surface) {
if surface.as_ref().equals(&window.surface.as_ref()) {
return Some(make_wid(surface));
}
}
@ -357,7 +353,7 @@ impl WindowStore {
pruned
}
pub fn new_seat(&self, seat: &Proxy<wl_seat::WlSeat>) {
pub fn new_seat(&self, seat: &wl_seat::WlSeat) {
for window in &self.windows {
if let Some(w) = window.frame.upgrade() {
w.lock().unwrap().new_seat(seat);
@ -365,9 +361,9 @@ impl WindowStore {
}
}
fn dpi_change(&mut self, surface: &Proxy<wl_surface::WlSurface>, new: i32) {
fn dpi_change(&mut self, surface: &wl_surface::WlSurface, new: i32) {
for window in &mut self.windows {
if surface.equals(&window.surface) {
if surface.as_ref().equals(&window.surface.as_ref()) {
window.new_dpi = Some(new);
}
}
@ -384,7 +380,7 @@ impl WindowStore {
window.newsize.take(),
&mut *(window.size.lock().unwrap()),
window.new_dpi,
window.need_refresh,
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
window.closed,
make_wid(&window.surface),
@ -393,59 +389,9 @@ impl WindowStore {
if let Some(dpi) = window.new_dpi.take() {
window.current_dpi = dpi;
}
window.need_refresh = false;
// avoid re-spamming the event
window.closed = false;
}
}
}
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
/*
* Monitor list with some covenience method to compute DPI
*/
struct MonitorList {
monitors: Vec<MonitorHandle>
}
impl MonitorList {
fn new() -> MonitorList {
MonitorList {
monitors: Vec::new()
}
}
fn compute_hidpi_factor(&self) -> i32 {
let mut factor = 1;
for monitor_id in &self.monitors {
let monitor_dpi = monitor_id.get_hidpi_factor();
if monitor_dpi > factor { factor = monitor_dpi; }
}
factor
}
fn add_output(&mut self, monitor: MonitorHandle) -> Option<i32> {
let old_dpi = self.compute_hidpi_factor();
let monitor_dpi = monitor.get_hidpi_factor();
self.monitors.push(monitor);
if monitor_dpi > old_dpi {
Some(monitor_dpi)
} else {
None
}
}
fn del_output(&mut self, output: &Proxy<wl_output::WlOutput>) -> Option<i32> {
let old_dpi = self.compute_hidpi_factor();
self.monitors.retain(|m| !m.proxy.equals(output));
let new_dpi = self.compute_hidpi_factor();
if new_dpi != old_dpi {
Some(new_dpi)
} else {
None
}
}
}
=======
>>>>>>> master:src/platform/linux/wayland/window.rs

View file

@ -601,13 +601,13 @@ impl EventLoopThreadExecutor {
type ThreadExecFn = Box<Box<FnMut()>>;
#[derive(Clone)]
pub struct EventLoopProxy<T> {
pub struct EventLoopProxy<T: 'static> {
target_window: HWND,
event_send: Sender<T>,
}
unsafe impl<T: Send> Send for EventLoopProxy<T> {}
unsafe impl<T: Send + 'static> Send for EventLoopProxy<T> {}
impl<T> EventLoopProxy<T> {
impl<T: 'static> EventLoopProxy<T> {
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
unsafe {
if winuser::PostMessageW(self.target_window, *USER_EVENT_MSG_ID, 0, 0) != 0 {

View file

@ -4,7 +4,7 @@ fn needs_send<T:Send>() {}
#[test]
fn event_loop_proxy_send() {
fn is_send<T: Send>() {
fn is_send<T: 'static + Send>() {
// ensures that `winit::EventLoopProxy` implements `Send`
needs_send::<winit::event_loop::EventLoopProxy<T>>();
}