From 6513351e0c628a4497894b0c1bdc411adde3475c Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Thu, 21 Feb 2019 10:51:43 +0100 Subject: [PATCH] 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 --- Cargo.toml | 5 +- src/event_loop.rs | 6 +- src/lib.rs | 2 + src/platform/unix.rs | 124 +++-- src/platform_impl/linux/mod.rs | 250 +++++----- src/platform_impl/linux/wayland/event_loop.rs | 458 +++++++++--------- src/platform_impl/linux/wayland/keyboard.rs | 73 ++- src/platform_impl/linux/wayland/mod.rs | 7 +- src/platform_impl/linux/wayland/pointer.rs | 40 +- src/platform_impl/linux/wayland/touch.rs | 31 +- src/platform_impl/linux/wayland/window.rs | 120 ++--- src/platform_impl/windows/event_loop.rs | 6 +- tests/send_objects.rs | 2 +- 13 files changed, 532 insertions(+), 592 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7017dc95..375d4738 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/event_loop.rs b/src/event_loop.rs index ca217f7c..ab6839cd 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -163,11 +163,11 @@ impl Deref for EventLoop { /// Used to send custom events to `EventLoop`. #[derive(Clone)] -pub struct EventLoopProxy { +pub struct EventLoopProxy { event_loop_proxy: platform_impl::EventLoopProxy, } -impl EventLoopProxy { +impl EventLoopProxy { /// 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 EventLoopProxy { } } -impl fmt::Debug for EventLoopProxy { +impl fmt::Debug for EventLoopProxy { fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { fmtr.pad("EventLoopProxy { .. }") } diff --git a/src/lib.rs b/src/lib.rs index ff374806..2066d061 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 983ccf0d..5bde480d 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -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 - where Self: Sized; + /// Builds a new `EventLoops` that is forced to use X11. + //fn new_x11() -> Result + // 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>; + //#[doc(hidden)] + //fn get_xlib_xconnection(&self) -> Option>; } -impl EventLoopExtUnix for EventLoop { - #[inline] - fn new_x11() -> Result { - LinuxEventLoop::new_x11().map(|ev| - EventLoop { - event_loop: ev, - _marker: ::std::marker::PhantomData, - } - ) - } +impl EventLoopExtUnix for EventLoop { + //#[inline] + //fn new_x11() -> Result { + // 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> { - self.event_loop.x_connection().cloned() - } + //#[inline] + //#[doc(hidden)] + //fn get_xlib_xconnection(&self) -> Option> { + // 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; - #[doc(hidden)] - fn get_xlib_xconnection(&self) -> Option>; + //#[doc(hidden)] + //fn get_xlib_xconnection(&self) -> Option>; /// 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 { 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 { 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> { - match self.window { - LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()), - _ => None - } - } + //#[inline] + //#[doc(hidden)] + //fn get_xlib_xconnection(&self) -> Option> { + // 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(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 { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index a1bdbe5f..94f324ed 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -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, + //pub visual_infos: Option, pub screen_id: Option, 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, pub app_id: Option } -lazy_static!( - pub static ref X11_BACKEND: Mutex, XNotSupported>> = { - Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)) - }; -); +//lazy_static!( +// pub static ref X11_BACKEND: Mutex, 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 { 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( + window_target: &EventLoopWindowTarget, attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { - 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 { 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 { 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 { 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 { 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) { 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) { 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) { 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) { 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 { 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 { + Wayland(wayland::EventLoop), + //X(x11::EventLoop) } #[derive(Clone)] -pub enum EventLoopProxy { - X(x11::EventLoopProxy), - Wayland(wayland::EventLoopProxy), +pub enum EventLoopProxy { + //X(x11::EventLoopProxy), + Wayland(wayland::EventLoopProxy), } -impl EventLoop { - pub fn new() -> EventLoop { +impl EventLoop { + pub fn new() -> EventLoop { 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 { + pub fn new_wayland() -> Result, ConnectError> { wayland::EventLoop::new() .map(EventLoop::Wayland) } - pub fn new_x11() -> Result { - 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, () /*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 { 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(&mut self, callback: F) - where F: FnMut(::Event) + pub fn run_return(&mut self, callback: F) + where F: FnMut(::event::Event, &RootELW, &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(&mut self, callback: F) - where F: FnMut(::Event) -> ControlFlow + pub fn run(self, callback: F) -> ! + where F: 'static + FnMut(::event::Event, &RootELW, &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> { + pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget { 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> { + // match *self { + // EventLoop::Wayland(_) => None, + // EventLoop::X(ref ev) => Some(ev.x_connection()), + // } + //} +} + +impl EventLoopProxy { + 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 { + Wayland(wayland::EventLoopWindowTarget), + //X(x11::EventLoopWIndowTarget) } diff --git a/src/platform_impl/linux/wayland/event_loop.rs b/src/platform_impl/linux/wayland/event_loop.rs index 25416233..346d3536 100644 --- a/src/platform_impl/linux/wayland/event_loop.rs +++ b/src/platform_impl/linux/wayland/event_loop.rs @@ -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(&mut self, callback: &mut F) + fn empty_with(&mut self, mut callback: F) where - F: FnMut(::Event), + F: FnMut(::event::Event), { - 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, +pub struct EventLoop { + // The loop + inner_loop: ::calloop::EventLoop<()>, + // The wayland display + pub display: Arc, + // the output manager + pub outputs: OutputMgr, // our sink, shared with some handlers, buffering the events - sink: Arc>, - // Whether or not there is a pending `Awakened` event to be emitted. - pending_wakeup: Arc, + sink: Arc>, + pending_user_events: Rc>>, + _user_source: ::calloop::Source<::calloop::channel::Channel>, + user_sender: ::calloop::channel::Sender, + _kbd_source: ::calloop::Source<::calloop::channel::Channel<(::event::WindowEvent, super::WindowId)>>, + window_target: RootELW +} + +// 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 { + user_sender: ::calloop::channel::Sender +} + +pub struct EventLoopWindowTarget { + // the event queue + pub evq: RefCell<::calloop::Source>, // The window store pub store: Arc>, // the env @@ -70,57 +80,40 @@ pub struct EventLoop { // The wayland display pub display: Arc, // The list of seats - pub seats: Arc)>>>, + pub seats: Arc>>, + _marker: ::std::marker::PhantomData } -// 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, - pending_wakeup: Weak, -} - -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 EventLoopProxy { + pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { + self.user_sender.send(event).map_err(|_| EventLoopClosed) } } -impl EventLoop { - pub fn new() -> Result { +impl EventLoop { + pub fn new() -> Result, 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 { EventLoopProxy { - display: Arc::downgrade(&self.display), - pending_wakeup: Arc::downgrade(&self.pending_wakeup), + user_sender: self.user_sender.clone() } } - pub fn poll_events(&mut self, mut callback: F) - where - F: FnMut(::Event), + pub fn run(mut self, callback: F) -> ! + where F: 'static + FnMut(::event::Event, &RootELW, &mut ControlFlow) + { + self.run_return(callback); + ::std::process::exit(0); + } + + pub fn run_return(&mut self, mut callback: F) + where F: FnMut(::event::Event, &RootELW, &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(&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 { - get_available_monitors(&self.env.outputs) + get_available_monitors(&self.outputs) + } + + pub fn window_target(&self) -> &RootELW { + &self.window_target } } @@ -235,34 +296,33 @@ impl EventLoop { * Private EventLoop Internals */ -impl EventLoop { +impl EventLoop { 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>, + sink: Arc>, store: Arc>, - seats: Arc)>>>, - event_loop_proxy: EventLoopProxy, + seats: Arc>>, + kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)> } impl SeatManager { - fn add_seat(&mut self, id: u32, version: u32, registry: Proxy) { - 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::(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>, + sink: Arc>, store: Arc>, - pointer: Option>, - keyboard: Option>, - touch: Option>, -<<<<<<< HEAD - events_loop_proxy: EventsLoopProxy, + kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>, + pointer: Option, + keyboard: Option, + touch: Option, modifiers_tracker: Arc>, -======= - event_loop_proxy: EventLoopProxy, ->>>>>>> Change instances of "events_loop" to "event_loop" } impl SeatData { - fn receive(&mut self, evt: wl_seat::Event, seat: Proxy) { + 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, + pub(crate) proxy: wl_output::WlOutput, pub(crate) mgr: OutputMgr, } diff --git a/src/platform_impl/linux/wayland/keyboard.rs b/src/platform_impl/linux/wayland/keyboard.rs index d8457d5d..420d0ab6 100644 --- a/src/platform_impl/linux/wayland/keyboard.rs +++ b/src/platform_impl/linux/wayland/keyboard.rs @@ -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, - sink: Arc>, - event_loop_proxy: EventLoopProxy, + seat: &wl_seat::WlSeat, + sink: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>, modifiers_tracker: Arc>, -) -> Proxy { +) -> 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(); } } _ => (), diff --git a/src/platform_impl/linux/wayland/mod.rs b/src/platform_impl/linux/wayland/mod.rs index 224959d5..44397ea2 100644 --- a/src/platform_impl/linux/wayland/mod.rs +++ b/src/platform_impl/linux/wayland/mod.rs @@ -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) -> WindowId { - WindowId(s.c_ptr() as usize) +fn make_wid(s: &wl_surface::WlSurface) -> WindowId { + WindowId(s.as_ref().c_ptr() as usize) } diff --git a/src/platform_impl/linux/wayland/pointer.rs b/src/platform_impl/linux/wayland/pointer.rs index d910a5ea..cbada78b 100644 --- a/src/platform_impl/linux/wayland/pointer.rs +++ b/src/platform_impl/linux/wayland/pointer.rs @@ -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, - sink: Arc>, + seat: &wl_seat::WlSeat, + sink: Arc>, store: Arc>, modifiers_tracker: Arc>, -) -> Proxy { +) -> 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() diff --git a/src/platform_impl/linux/wayland/touch.rs b/src/platform_impl/linux/wayland/touch.rs index a357f3aa..765d524a 100644 --- a/src/platform_impl/linux/wayland/touch.rs +++ b/src/platform_impl/linux/wayland/touch.rs @@ -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, - sink: Arc>, + seat: &wl_seat::WlSeat, + sink: Arc>, store: Arc>, -) -> Proxy { +) -> 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() diff --git a/src/platform_impl/linux/wayland/window.rs b/src/platform_impl/linux/wayland/window.rs index 20653858..622b3f8d 100644 --- a/src/platform_impl/linux/wayland/window.rs +++ b/src/platform_impl/linux/wayland/window.rs @@ -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, + surface: wl_surface::WlSurface, frame: Arc>>, outputs: OutputMgr, // Access to info for all monitors size: Arc>, kill_switch: (Arc>, Arc>), display: Arc, need_frame_refresh: Arc>, + need_refresh: Arc> } impl Window { - pub fn new(evlp: &EventLoop, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result { + pub fn new(evlp: &EventLoopWindowTarget, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result { 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 { let (w, h) = self.size.lock().unwrap().clone(); @@ -269,24 +273,16 @@ impl Window { &*self.display } - pub fn get_surface(&self) -> &Proxy { + 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 { @@ -310,10 +306,10 @@ impl Drop for Window { */ struct InternalWindow { - surface: Proxy, + surface: wl_surface::WlSurface, newsize: Option<(u32, u32)>, size: Arc>, - need_refresh: bool, + need_refresh: Arc>, need_frame_refresh: Arc>, closed: bool, kill_switch: Arc>, @@ -333,9 +329,9 @@ impl WindowStore { } } - pub fn find_wid(&self, surface: &Proxy) -> Option { + pub fn find_wid(&self, surface: &wl_surface::WlSurface) -> Option { 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) { + 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, 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 -} - -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 { - 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) -> Option { - 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 diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 9bc874b6..1d7a4aa1 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -601,13 +601,13 @@ impl EventLoopThreadExecutor { type ThreadExecFn = Box>; #[derive(Clone)] -pub struct EventLoopProxy { +pub struct EventLoopProxy { target_window: HWND, event_send: Sender, } -unsafe impl Send for EventLoopProxy {} +unsafe impl Send for EventLoopProxy {} -impl EventLoopProxy { +impl EventLoopProxy { pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { unsafe { if winuser::PostMessageW(self.target_window, *USER_EVENT_MSG_ID, 0, 0) != 0 { diff --git a/tests/send_objects.rs b/tests/send_objects.rs index 9220203f..ad1f248a 100644 --- a/tests/send_objects.rs +++ b/tests/send_objects.rs @@ -4,7 +4,7 @@ fn needs_send() {} #[test] fn event_loop_proxy_send() { - fn is_send() { + fn is_send() { // ensures that `winit::EventLoopProxy` implements `Send` needs_send::>(); }