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] [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"] } wayland-client = { version = "0.23.0", features = [ "dlopen", "egl", "cursor", "eventloop"] }
smithay-client-toolkit = "0.4.3" calloop = "0.4.2"
smithay-client-toolkit = "0.6"
x11-dl = "2.18.3" x11-dl = "2.18.3"
parking_lot = "0.7" parking_lot = "0.7"
percent-encoding = "1.0" percent-encoding = "1.0"

View file

@ -163,11 +163,11 @@ impl<T> Deref for EventLoop<T> {
/// Used to send custom events to `EventLoop`. /// Used to send custom events to `EventLoop`.
#[derive(Clone)] #[derive(Clone)]
pub struct EventLoopProxy<T> { pub struct EventLoopProxy<T: 'static> {
event_loop_proxy: platform_impl::EventLoopProxy<T>, 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 /// 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 /// `UserEvent(event)` event in the event loop, where `event` is the value passed to this
/// function. /// 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 { fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
fmtr.pad("EventLoopProxy { .. }") fmtr.pad("EventLoopProxy { .. }")
} }

View file

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

View file

@ -6,26 +6,24 @@ use std::sync::Arc;
use sctk::window::{ButtonState, Theme}; use sctk::window::{ButtonState, Theme};
use { use dpi::LogicalSize;
EventLoop, use event_loop::EventLoop;
LogicalSize, use monitor::MonitorHandle;
MonitorHandle, use window::{Window, WindowBuilder};
Window,
WindowBuilder,
};
use platform_impl::{ use platform_impl::{
EventLoop as LinuxEventLoop, EventLoop as LinuxEventLoop,
Window as LinuxWindow, Window as LinuxWindow,
}; };
use platform_impl::x11::XConnection; //use platform_impl::x11::XConnection;
use platform_impl::x11::ffi::XVisualInfo; //use platform_impl::x11::ffi::XVisualInfo;
//
// TODO: stupid hack so that glutin can do its work // TODO: stupid hack so that glutin can do its work
#[doc(hidden)] //#[doc(hidden)]
pub use platform_impl::x11; //pub use platform_impl::x11;
//
pub use platform_impl::XNotSupported; //pub use platform_impl::XNotSupported;
pub use platform_impl::x11::util::WindowType as XWindowType; //pub use platform_impl::x11::util::WindowType as XWindowType;
/// Theme for wayland client side decorations /// Theme for wayland client side decorations
/// ///
@ -97,9 +95,9 @@ impl Theme for WaylandThemeObject {
/// Additional methods on `EventLoop` that are specific to Unix. /// Additional methods on `EventLoop` that are specific to Unix.
pub trait EventLoopExtUnix { pub trait EventLoopExtUnix {
/// Builds a new `EventsLoop` that is forced to use X11. /// Builds a new `EventLoops` that is forced to use X11.
fn new_x11() -> Result<Self, XNotSupported> //fn new_x11() -> Result<Self, XNotSupported>
where Self: Sized; // where Self: Sized;
/// Builds a new `EventLoop` that is forced to use Wayland. /// Builds a new `EventLoop` that is forced to use Wayland.
fn new_wayland() -> Self fn new_wayland() -> Self
@ -111,20 +109,20 @@ pub trait EventLoopExtUnix {
/// True if the `EventLoop` uses X11. /// True if the `EventLoop` uses X11.
fn is_x11(&self) -> bool; fn is_x11(&self) -> bool;
#[doc(hidden)] //#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; //fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
} }
impl EventLoopExtUnix for EventLoop { impl<T> EventLoopExtUnix for EventLoop<T> {
#[inline] //#[inline]
fn new_x11() -> Result<Self, XNotSupported> { //fn new_x11() -> Result<Self, XNotSupported> {
LinuxEventLoop::new_x11().map(|ev| // LinuxEventLoop::new_x11().map(|ev|
EventLoop { // EventLoop {
event_loop: ev, // event_loop: ev,
_marker: ::std::marker::PhantomData, // _marker: ::std::marker::PhantomData,
} // }
) // )
} //}
#[inline] #[inline]
fn new_wayland() -> Self { fn new_wayland() -> Self {
@ -147,11 +145,11 @@ impl EventLoopExtUnix for EventLoop {
!self.event_loop.is_wayland() !self.event_loop.is_wayland()
} }
#[inline] //#[inline]
#[doc(hidden)] //#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { //fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
self.event_loop.x_connection().cloned() // self.event_loop.x_connection().cloned()
} //}
} }
/// Additional methods on `Window` that are specific to Unix. /// 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>; fn get_xlib_screen_id(&self) -> Option<raw::c_int>;
#[doc(hidden)] //#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; //fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X. /// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
fn set_urgent(&self, is_urgent: bool); fn set_urgent(&self, is_urgent: bool);
@ -214,7 +212,7 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_window(&self) -> Option<raw::c_ulong> { fn get_xlib_window(&self) -> Option<raw::c_ulong> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_window()), //LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
_ => None _ => None
} }
} }
@ -222,7 +220,7 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_display(&self) -> Option<*mut raw::c_void> { fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_display()), //LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
_ => None _ => None
} }
} }
@ -230,39 +228,39 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_screen_id(&self) -> Option<raw::c_int> { fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()), //LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
_ => None _ => None
} }
} }
#[inline] //#[inline]
#[doc(hidden)] //#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { //fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.window { // match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()), // //LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
_ => None // _ => None
} // }
} //}
#[inline] #[inline]
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> { fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()), //LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn set_urgent(&self, is_urgent: bool) { fn set_urgent(&self, is_urgent: bool) {
if let LinuxWindow::X(ref w) = self.window { //if let LinuxWindow::X(ref w) = self.window {
w.set_urgent(is_urgent); // w.set_urgent(is_urgent);
} //}
} }
#[inline] #[inline]
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> { fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
match self.window { 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 _ => None
} }
} }
@ -270,7 +268,7 @@ impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> { fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
match self.window { 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 _ => None
} }
} }
@ -299,7 +297,7 @@ pub trait WindowBuilderExtUnix {
/// Build window with override-redirect flag; defaults to false. Only relevant on X11. /// Build window with override-redirect flag; defaults to false. Only relevant on X11.
fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder; fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder;
/// Build window with `_NET_WM_WINDOW_TYPE` hint; defaults to `Normal`. Only relevant on X11. /// 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. /// 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; fn with_gtk_theme_variant(self, variant: String) -> WindowBuilder;
/// Build window with resize increment hint. Only implemented on X11. /// Build window with resize increment hint. Only implemented on X11.
@ -318,9 +316,9 @@ pub trait WindowBuilderExtUnix {
impl WindowBuilderExtUnix for WindowBuilder { impl WindowBuilderExtUnix for WindowBuilder {
#[inline] #[inline]
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder { fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder {
self.platform_specific.visual_infos = Some( //self.platform_specific.visual_infos = Some(
unsafe { ptr::read(visual_infos as *const XVisualInfo) } // unsafe { ptr::read(visual_infos as *const XVisualInfo) }
); //);
self self
} }
@ -342,11 +340,11 @@ impl WindowBuilderExtUnix for WindowBuilder {
self self
} }
#[inline] //#[inline]
fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder { //fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
self.platform_specific.x11_window_type = x11_window_type; // self.platform_specific.x11_window_type = x11_window_type;
self // self
} //}
#[inline] #[inline]
fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder { fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder {

View file

@ -9,23 +9,18 @@ use std::sync::Arc;
use parking_lot::Mutex; use parking_lot::Mutex;
use sctk::reexports::client::ConnectError; use sctk::reexports::client::ConnectError;
use {
CreationError,
EventLoopClosed,
Icon,
MouseCursor,
ControlFlow,
WindowAttributes,
};
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use window::MonitorHandle as RootMonitorHandle; use icon::Icon;
use self::x11::{XConnection, XError}; use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
use self::x11::ffi::XVisualInfo; use monitor::MonitorHandle as RootMonitorHandle;
pub use self::x11::XNotSupported; use window::{WindowAttributes, CreationError, MouseCursor};
//use self::x11::{XConnection, XError};
//use self::x11::ffi::XVisualInfo;
//pub use self::x11::XNotSupported;
mod dlopen; mod dlopen;
pub mod wayland; pub mod wayland;
pub mod x11; //pub mod x11;
/// Environment variable specifying which backend should be used on unix platform. /// 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)] #[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes { pub struct PlatformSpecificWindowBuilderAttributes {
pub visual_infos: Option<XVisualInfo>, //pub visual_infos: Option<XVisualInfo>,
pub screen_id: Option<i32>, pub screen_id: Option<i32>,
pub resize_increments: Option<(u32, u32)>, pub resize_increments: Option<(u32, u32)>,
pub base_size: Option<(u32, u32)>, pub base_size: Option<(u32, u32)>,
pub class: Option<(String, String)>, pub class: Option<(String, String)>,
pub override_redirect: bool, 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 gtk_theme_variant: Option<String>,
pub app_id: Option<String> pub app_id: Option<String>
} }
lazy_static!( //lazy_static!(
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = { // pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)) // Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
}; // };
); //);
pub enum Window { pub enum Window {
X(x11::Window), //X(x11::Window),
Wayland(wayland::Window), Wayland(wayland::Window),
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum WindowId { pub enum WindowId {
X(x11::WindowId), //X(x11::WindowId),
Wayland(wayland::WindowId), Wayland(wayland::WindowId),
} }
impl WindowId { impl WindowId {
pub unsafe fn dummy() -> Self { pub unsafe fn dummy() -> Self {
WindowId::X(x11::WindowId::dummy()) WindowId::Wayland(wayland::WindowId::dummy())
} }
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DeviceId { pub enum DeviceId {
X(x11::DeviceId), //X(x11::DeviceId),
Wayland(wayland::DeviceId), Wayland(wayland::DeviceId),
} }
impl DeviceId { impl DeviceId {
pub unsafe fn dummy() -> Self { pub unsafe fn dummy() -> Self {
DeviceId::X(x11::DeviceId::dummy()) DeviceId::Wayland(wayland::DeviceId::dummy())
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum MonitorHandle { pub enum MonitorHandle {
X(x11::MonitorHandle), //X(x11::MonitorHandle),
Wayland(wayland::MonitorHandle), Wayland(wayland::MonitorHandle),
} }
@ -94,7 +89,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn get_name(&self) -> Option<String> {
match self { match self {
&MonitorHandle::X(ref m) => m.get_name(), //&MonitorHandle::X(ref m) => m.get_name(),
&MonitorHandle::Wayland(ref m) => m.get_name(), &MonitorHandle::Wayland(ref m) => m.get_name(),
} }
} }
@ -102,7 +97,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn get_native_identifier(&self) -> u32 {
match self { 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(), &MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
} }
} }
@ -110,7 +105,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn get_dimensions(&self) -> PhysicalSize {
match self { match self {
&MonitorHandle::X(ref m) => m.get_dimensions(), //&MonitorHandle::X(ref m) => m.get_dimensions(),
&MonitorHandle::Wayland(ref m) => m.get_dimensions(), &MonitorHandle::Wayland(ref m) => m.get_dimensions(),
} }
} }
@ -118,7 +113,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn get_position(&self) -> PhysicalPosition {
match self { match self {
&MonitorHandle::X(ref m) => m.get_position(), //&MonitorHandle::X(ref m) => m.get_position(),
&MonitorHandle::Wayland(ref m) => m.get_position(), &MonitorHandle::Wayland(ref m) => m.get_position(),
} }
} }
@ -126,7 +121,7 @@ impl MonitorHandle {
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn get_hidpi_factor(&self) -> f64 {
match self { 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, &MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
} }
} }
@ -134,25 +129,25 @@ impl MonitorHandle {
impl Window { impl Window {
#[inline] #[inline]
pub fn new( pub fn new<T>(
event_loop: &EventLoop, window_target: &EventLoopWindowTarget<T>,
attribs: WindowAttributes, attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> { ) -> Result<Self, CreationError> {
match *event_loop { match *window_target {
EventsLoop::Wayland(ref event_loop) => { EventLoopWindowTarget::Wayland(ref window_target) => {
wayland::Window::new(event_loop, attribs, pl_attribs).map(Window::Wayland) 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)
}, },
//EventLoop::X(ref event_loop) => {
// x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X)
//},
} }
} }
#[inline] #[inline]
pub fn id(&self) -> WindowId { pub fn id(&self) -> WindowId {
match self { 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()), &Window::Wayland(ref w) => WindowId::Wayland(w.id()),
} }
} }
@ -160,7 +155,7 @@ impl Window {
#[inline] #[inline]
pub fn set_title(&self, title: &str) { pub fn set_title(&self, title: &str) {
match self { 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), &Window::Wayland(ref w) => w.set_title(title),
} }
} }
@ -168,7 +163,7 @@ impl Window {
#[inline] #[inline]
pub fn show(&self) { pub fn show(&self) {
match self { match self {
&Window::X(ref w) => w.show(), //&Window::X(ref w) => w.show(),
&Window::Wayland(ref w) => w.show(), &Window::Wayland(ref w) => w.show(),
} }
} }
@ -176,7 +171,7 @@ impl Window {
#[inline] #[inline]
pub fn hide(&self) { pub fn hide(&self) {
match self { match self {
&Window::X(ref w) => w.hide(), //&Window::X(ref w) => w.hide(),
&Window::Wayland(ref w) => w.hide(), &Window::Wayland(ref w) => w.hide(),
} }
} }
@ -184,7 +179,7 @@ impl Window {
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn get_position(&self) -> Option<LogicalPosition> {
match self { match self {
&Window::X(ref w) => w.get_position(), //&Window::X(ref w) => w.get_position(),
&Window::Wayland(ref w) => w.get_position(), &Window::Wayland(ref w) => w.get_position(),
} }
} }
@ -192,7 +187,7 @@ impl Window {
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn get_inner_position(&self) -> Option<LogicalPosition> {
match self { 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(), &Window::Wayland(ref m) => m.get_inner_position(),
} }
} }
@ -200,7 +195,7 @@ impl Window {
#[inline] #[inline]
pub fn set_position(&self, position: LogicalPosition) { pub fn set_position(&self, position: LogicalPosition) {
match self { 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), &Window::Wayland(ref w) => w.set_position(position),
} }
} }
@ -208,7 +203,7 @@ impl Window {
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn get_inner_size(&self) -> Option<LogicalSize> {
match self { 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(), &Window::Wayland(ref w) => w.get_inner_size(),
} }
} }
@ -216,7 +211,7 @@ impl Window {
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn get_outer_size(&self) -> Option<LogicalSize> {
match self { 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(), &Window::Wayland(ref w) => w.get_outer_size(),
} }
} }
@ -224,7 +219,7 @@ impl Window {
#[inline] #[inline]
pub fn set_inner_size(&self, size: LogicalSize) { pub fn set_inner_size(&self, size: LogicalSize) {
match self { 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), &Window::Wayland(ref w) => w.set_inner_size(size),
} }
} }
@ -232,7 +227,7 @@ impl Window {
#[inline] #[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
match self { 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), &Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
} }
} }
@ -240,7 +235,7 @@ impl Window {
#[inline] #[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
match self { 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), &Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
} }
} }
@ -248,7 +243,7 @@ impl Window {
#[inline] #[inline]
pub fn set_resizable(&self, resizable: bool) { pub fn set_resizable(&self, resizable: bool) {
match self { 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), &Window::Wayland(ref w) => w.set_resizable(resizable),
} }
} }
@ -256,7 +251,7 @@ impl Window {
#[inline] #[inline]
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor(&self, cursor: MouseCursor) {
match self { 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) &Window::Wayland(ref w) => w.set_cursor(cursor)
} }
} }
@ -264,7 +259,7 @@ impl Window {
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
match self { 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), &Window::Wayland(ref window) => window.grab_cursor(grab),
} }
} }
@ -272,7 +267,7 @@ impl Window {
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn hide_cursor(&self, hide: bool) {
match self { 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), &Window::Wayland(ref window) => window.hide_cursor(hide),
} }
} }
@ -280,7 +275,7 @@ impl Window {
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn get_hidpi_factor(&self) -> f64 {
match self { 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, &Window::Wayland(ref w) => w.hidpi_factor() as f64,
} }
} }
@ -288,7 +283,7 @@ impl Window {
#[inline] #[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
match self { 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), &Window::Wayland(ref w) => w.set_cursor_position(position),
} }
} }
@ -296,7 +291,7 @@ impl Window {
#[inline] #[inline]
pub fn set_maximized(&self, maximized: bool) { pub fn set_maximized(&self, maximized: bool) {
match self { 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), &Window::Wayland(ref w) => w.set_maximized(maximized),
} }
} }
@ -304,7 +299,7 @@ impl Window {
#[inline] #[inline]
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) { pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
match self { 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) &Window::Wayland(ref w) => w.set_fullscreen(monitor)
} }
} }
@ -312,7 +307,7 @@ impl Window {
#[inline] #[inline]
pub fn set_decorations(&self, decorations: bool) { pub fn set_decorations(&self, decorations: bool) {
match self { 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) &Window::Wayland(ref w) => w.set_decorations(decorations)
} }
} }
@ -320,7 +315,7 @@ impl Window {
#[inline] #[inline]
pub fn set_always_on_top(&self, always_on_top: bool) { pub fn set_always_on_top(&self, always_on_top: bool) {
match self { 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(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -328,7 +323,7 @@ impl Window {
#[inline] #[inline]
pub fn set_window_icon(&self, window_icon: Option<Icon>) { pub fn set_window_icon(&self, window_icon: Option<Icon>) {
match self { match self {
&Window::X(ref w) => w.set_window_icon(window_icon), //&Window::X(ref w) => w.set_window_icon(window_icon),
&Window::Wayland(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -336,15 +331,23 @@ impl Window {
#[inline] #[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) { pub fn set_ime_spot(&self, position: LogicalPosition) {
match self { match self {
&Window::X(ref w) => w.set_ime_spot(position), //&Window::X(ref w) => w.set_ime_spot(position),
&Window::Wayland(_) => (), &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] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn get_current_monitor(&self) -> RootMonitorHandle {
match self { 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()) }, &Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
} }
} }
@ -352,10 +355,10 @@ impl Window {
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
match self { match self {
&Window::X(ref window) => window.get_available_monitors() //&Window::X(ref window) => window.get_available_monitors()
.into_iter() // .into_iter()
.map(MonitorHandle::X) // .map(MonitorHandle::X)
.collect(), // .collect(),
&Window::Wayland(ref window) => window.get_available_monitors() &Window::Wayland(ref window) => window.get_available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
@ -366,12 +369,13 @@ impl Window {
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn get_primary_monitor(&self) -> MonitorHandle {
match self { 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()), &Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
} }
} }
} }
/*
unsafe extern "C" fn x_error_callback( unsafe extern "C" fn x_error_callback(
display: *mut x11::ffi::Display, display: *mut x11::ffi::Display,
event: *mut x11::ffi::XErrorEvent, event: *mut x11::ffi::XErrorEvent,
@ -401,20 +405,21 @@ unsafe extern "C" fn x_error_callback(
// Fun fact: this return value is completely ignored. // Fun fact: this return value is completely ignored.
0 0
} }
*/
pub enum EventLoop { pub enum EventLoop<T: 'static> {
Wayland(wayland::EventLoop), Wayland(wayland::EventLoop<T>),
X(x11::EventLoop) //X(x11::EventLoop)
} }
#[derive(Clone)] #[derive(Clone)]
pub enum EventLoopProxy { pub enum EventLoopProxy<T: 'static> {
X(x11::EventLoopProxy), //X(x11::EventLoopProxy),
Wayland(wayland::EventLoopProxy), Wayland(wayland::EventLoopProxy<T>),
} }
impl EventLoop { impl<T:'static> EventLoop<T> {
pub fn new() -> EventLoop { pub fn new() -> EventLoop<T> {
if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) { if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) {
match env_var.as_str() { match env_var.as_str() {
"x11" => { "x11" => {
@ -450,19 +455,20 @@ impl EventLoop {
panic!(err_string); panic!(err_string);
} }
pub fn new_wayland() -> Result<EventLoop, ConnectError> { pub fn new_wayland() -> Result<EventLoop<T>, ConnectError> {
wayland::EventLoop::new() wayland::EventLoop::new()
.map(EventLoop::Wayland) .map(EventLoop::Wayland)
} }
pub fn new_x11() -> Result<EventLoop, XNotSupported> { pub fn new_x11() -> Result<EventLoop<T>, () /*XNotSupported*/> {
X11_BACKEND //X11_BACKEND
.lock() // .lock()
.as_ref() // .as_ref()
.map(Arc::clone) // .map(Arc::clone)
.map(x11::EventLoop::new) // .map(x11::EventLoop::new)
.map(EventLoop::X) // .map(EventLoop::X)
.map_err(|err| err.clone()) // .map_err(|err| err.clone())
unimplemented!()
} }
#[inline] #[inline]
@ -473,12 +479,12 @@ impl EventLoop {
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
.collect(), .collect(),
EventLoop::X(ref evlp) => evlp //EventLoop::X(ref evlp) => evlp
.x_connection() // .x_connection()
.get_available_monitors() // .get_available_monitors()
.into_iter() // .into_iter()
.map(MonitorHandle::X) // .map(MonitorHandle::X)
.collect(), // .collect(),
} }
} }
@ -486,32 +492,32 @@ impl EventLoop {
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn get_primary_monitor(&self) -> MonitorHandle {
match *self { match *self {
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()), 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 { match *self {
EventLoop::Wayland(ref evlp) => EventLoopProxy::Wayland(evlp.create_proxy()), 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) pub fn run_return<F>(&mut self, callback: F)
where F: FnMut(::Event) where F: FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{ {
match *self { match *self {
EventLoop::Wayland(ref mut evlp) => evlp.poll_events(callback), EventLoop::Wayland(ref mut evlp) => evlp.run_return(callback),
EventLoop::X(ref mut evlp) => evlp.poll_events(callback) //EventLoop::X(ref mut evlp) => evlp.run_return(callback)
} }
} }
pub fn run_forever<F>(&mut self, callback: F) pub fn run<F>(self, callback: F) -> !
where F: FnMut(::Event) -> ControlFlow where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
{ {
match *self { match self {
EventLoop::Wayland(ref mut evlp) => evlp.run_forever(callback), EventLoop::Wayland(evlp) => evlp.run(callback),
EventLoop::X(ref mut evlp) => evlp.run_forever(callback) //EventLoop::X(ref mut evlp) => evlp.run(callback)
} }
} }
@ -519,24 +525,36 @@ impl EventLoop {
pub fn is_wayland(&self) -> bool { pub fn is_wayland(&self) -> bool {
match *self { match *self {
EventLoop::Wayland(_) => true, EventLoop::Wayland(_) => true,
EventLoop::X(_) => false, //EventLoop::X(_) => false,
} }
} }
#[inline] pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> {
pub fn x_connection(&self) -> Option<&Arc<XConnection>> {
match *self { match *self {
EventLoop::Wayland(_) => None, EventLoop::Wayland(ref evl) => evl.window_target(),
EventLoop::X(ref ev) => Some(ev.x_connection()), //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 enum EventLoopWindowTarget<T> {
pub fn wakeup(&self) -> Result<(), EventLoopClosed> { Wayland(wayland::EventLoopWindowTarget<T>),
match *self { //X(x11::EventLoopWIndowTarget<T>)
EventLoopProxy::Wayland(ref proxy) => proxy.wakeup(),
EventLoopProxy::X(ref proxy) => proxy.wakeup(),
}
}
} }

View file

@ -1,10 +1,13 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt; use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering}; use std::rc::Rc;
use std::sync::{Arc, Mutex, Weak}; 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::window::WindowStore;
use super::WindowId; use super::WindowId;
@ -13,54 +16,61 @@ use sctk::output::OutputMgr;
use sctk::reexports::client::protocol::{ use sctk::reexports::client::protocol::{
wl_keyboard, wl_output, wl_pointer, wl_registry, wl_seat, wl_touch, 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::Environment;
use sctk::reexports::client::protocol::wl_display::RequestsTrait as DisplayRequests; pub struct WindowEventsSink {
use sctk::reexports::client::protocol::wl_surface::RequestsTrait; buffer: VecDeque<(::event::WindowEvent, ::window::WindowId)>,
use ModifiersState;
pub struct EventLoopSink {
buffer: VecDeque<::Event>,
} }
impl EventLoopSink { impl WindowEventsSink {
pub fn new() -> EventLoopSink { pub fn new() -> WindowEventsSink {
EventLoopSink { WindowEventsSink {
buffer: VecDeque::new(), buffer: VecDeque::new(),
} }
} }
pub fn send_event(&mut self, evt: ::WindowEvent, wid: WindowId) { pub fn send_event(&mut self, evt: ::event::WindowEvent, wid: WindowId) {
let evt = ::Event::WindowEvent { self.buffer.push_back((evt, ::window::WindowId(::platform_impl::WindowId::Wayland(wid))));
event: evt,
window_id: ::WindowId(::platform::WindowId::Wayland(wid)),
};
self.buffer.push_back(evt);
} }
pub fn send_raw_event(&mut self, evt: ::Event) { fn empty_with<F, T>(&mut self, mut callback: F)
self.buffer.push_back(evt);
}
fn empty_with<F>(&mut self, callback: &mut F)
where where
F: FnMut(::Event), F: FnMut(::event::Event<T>),
{ {
for evt in self.buffer.drain(..) { for (evt, wid) in self.buffer.drain(..) {
callback(evt) callback(::event::Event::WindowEvent { event: evt, window_id: wid})
} }
} }
} }
pub struct EventLoop { pub struct EventLoop<T: 'static> {
// The Event Queue // The loop
pub evq: RefCell<EventQueue>, 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 // our sink, shared with some handlers, buffering the events
sink: Arc<Mutex<EventLoopSink>>, sink: Arc<Mutex<WindowEventsSink>>,
// Whether or not there is a pending `Awakened` event to be emitted. pending_user_events: Rc<RefCell<VecDeque<T>>>,
pending_wakeup: Arc<AtomicBool>, _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 // The window store
pub store: Arc<Mutex<WindowStore>>, pub store: Arc<Mutex<WindowStore>>,
// the env // the env
@ -70,57 +80,40 @@ pub struct EventLoop {
// The wayland display // The wayland display
pub display: Arc<Display>, pub display: Arc<Display>,
// The list of seats // 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`. impl<T: 'static> EventLoopProxy<T> {
// pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs. self.user_sender.send(event).map_err(|_| EventLoopClosed)
#[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 EventLoop { impl<T: 'static> EventLoop<T> {
pub fn new() -> Result<EventLoop, ConnectError> { pub fn new() -> Result<EventLoop<T>, ConnectError> {
let (display, mut event_queue) = Display::connect_to_env()?; let (display, mut event_queue) = Display::connect_to_env()?;
let display = Arc::new(display); let display = Arc::new(display);
let pending_wakeup = Arc::new(AtomicBool::new(false)); let sink = Arc::new(Mutex::new(WindowEventsSink::new()));
let sink = Arc::new(Mutex::new(EventLoopSink::new()));
let store = Arc::new(Mutex::new(WindowStore::new())); let store = Arc::new(Mutex::new(WindowStore::new()));
let seats = Arc::new(Mutex::new(Vec::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 { let mut seat_manager = SeatManager {
sink: sink.clone(), sink: sink.clone(),
store: store.clone(), store: store.clone(),
seats: seats.clone(), seats: seats.clone(),
events_loop_proxy: EventsLoopProxy { kbd_sender,
display: Arc::downgrade(&display),
pending_wakeup: Arc::downgrade(&pending_wakeup),
},
}; };
let env = Environment::from_display_with_cb( let env = Environment::from_display_with_cb(
@ -142,92 +135,160 @@ impl EventLoop {
}, },
).unwrap(); ).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 { Ok(EventLoop {
display, inner_loop,
evq: RefCell::new(event_queue),
sink, sink,
pending_wakeup, pending_user_events,
store, display: display.clone(),
env, outputs: env.outputs.clone(),
cleanup_needed: Arc::new(Mutex::new(false)), _user_source: user_source,
seats, 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 { EventLoopProxy {
display: Arc::downgrade(&self.display), user_sender: self.user_sender.clone()
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
} }
} }
pub fn poll_events<F>(&mut self, mut callback: F) pub fn run<F>(mut self, callback: F) -> !
where where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
F: FnMut(::Event), {
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 // send pending events to the server
self.display.flush().expect("Wayland connection lost."); self.display.flush().expect("Wayland connection lost.");
// dispatch any pre-buffered events let mut control_flow = ControlFlow::default();
self.sink.lock().unwrap().empty_with(&mut callback);
// try to read pending events let sink = self.sink.clone();
if let Some(h) = self.evq.get_mut().prepare_read() { let user_events = self.pending_user_events.clone();
h.read_events().expect("Wayland connection lost.");
}
// dispatch wayland events
self.evq
.get_mut()
.dispatch_pending()
.expect("Wayland connection lost.");
self.post_dispatch_triggers();
// dispatch buffered events to client callback(::event::Event::NewEvents(::event::StartCause::Init), &self.window_target, &mut control_flow);
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);
loop { loop {
// dispatch events blocking if needed
self.evq
.get_mut()
.dispatch()
.expect("Wayland connection lost.");
self.post_dispatch_triggers(); self.post_dispatch_triggers();
// empty buffer of events // 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() { callback(::event::Event::EventsCleared, &self.window_target, &mut control_flow);
break;
// 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 { 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> { 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 * Private EventLoop Internals
*/ */
impl EventLoop { impl<T> EventLoop<T> {
fn post_dispatch_triggers(&mut self) { fn post_dispatch_triggers(&mut self) {
let mut sink = self.sink.lock().unwrap(); let mut sink = self.sink.lock().unwrap();
// process a possible pending wakeup call let window_target = match self.window_target.p {
if self.pending_wakeup.load(Ordering::Relaxed) { ::platform_impl::EventLoopWindowTarget::Wayland(ref wt) => wt,
sink.send_raw_event(::Event::Awakened); _ => unreachable!()
self.pending_wakeup.store(false, Ordering::Relaxed); };
}
// prune possible dead windows // 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 { if *cleanup_needed {
let pruned = self.store.lock().unwrap().cleanup(); let pruned = window_target.store.lock().unwrap().cleanup();
*cleanup_needed = false; *cleanup_needed = false;
for wid in pruned { for wid in pruned {
sink.send_event(::WindowEvent::Destroyed, wid); sink.send_event(::event::WindowEvent::Destroyed, wid);
} }
} }
} }
// process pending resize/refresh // 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| { |newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
if let Some(frame) = frame { if let Some(frame) = frame {
if let Some((w, h)) = newsize { if let Some((w, h)) = newsize {
frame.resize(w, h); frame.resize(w, h);
frame.refresh(); frame.refresh();
let logical_size = ::LogicalSize::new(w as f64, h as f64); let logical_size = ::dpi::LogicalSize::new(w as f64, h as f64);
sink.send_event(::WindowEvent::Resized(logical_size), wid); sink.send_event(::event::WindowEvent::Resized(logical_size), wid);
*size = (w, h); *size = (w, h);
} else if frame_refresh { } else if frame_refresh {
frame.refresh(); frame.refresh();
@ -272,13 +332,13 @@ impl EventLoop {
} }
} }
if let Some(dpi) = new_dpi { 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 { if refresh {
sink.send_event(::WindowEvent::Redraw, wid); sink.send_event(::event::WindowEvent::RedrawRequested, wid);
} }
if closed { if closed {
sink.send_event(::WindowEvent::CloseRequested, wid); sink.send_event(::event::WindowEvent::CloseRequested, wid);
} }
}, },
) )
@ -290,15 +350,14 @@ impl EventLoop {
*/ */
struct SeatManager { struct SeatManager {
sink: Arc<Mutex<EventLoopSink>>, sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>, store: Arc<Mutex<WindowStore>>,
seats: Arc<Mutex<Vec<(u32, Proxy<wl_seat::WlSeat>)>>>, seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
event_loop_proxy: EventLoopProxy, kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>
} }
impl SeatManager { impl SeatManager {
fn add_seat(&mut self, id: u32, version: u32, registry: Proxy<wl_registry::WlRegistry>) { fn add_seat(&mut self, id: u32, version: u32, registry: wl_registry::WlRegistry) {
use self::wl_registry::RequestsTrait as RegistryRequests;
use std::cmp::min; use std::cmp::min;
let mut seat_data = SeatData { let mut seat_data = SeatData {
@ -307,12 +366,12 @@ impl SeatManager {
pointer: None, pointer: None,
keyboard: None, keyboard: None,
touch: 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())), modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
}; };
let seat = registry let seat = registry
.bind(min(version, 5), id, move |seat| { .bind(min(version, 5), id, move |seat| {
seat.implement(move |event, seat| { seat.implement_closure(move |event, seat| {
seat_data.receive(event, seat) seat_data.receive(event, seat)
}, ()) }, ())
}) })
@ -322,85 +381,28 @@ impl SeatManager {
} }
fn remove_seat(&mut self, id: u32) { 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(); let mut seats = self.seats.lock().unwrap();
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) { if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
let (_, seat) = seats.swap_remove(idx); let (_, seat) = seats.swap_remove(idx);
if seat.version() >= 5 { if seat.as_ref().version() >= 5 {
seat.release(); seat.release();
>>>>>>> master:src/platform/linux/wayland/event_loop.rs
} }
} }
} }
} }
struct SeatData { struct SeatData {
sink: Arc<Mutex<EventLoopSink>>, sink: Arc<Mutex<WindowEventsSink>>,
store: Arc<Mutex<WindowStore>>, store: Arc<Mutex<WindowStore>>,
pointer: Option<Proxy<wl_pointer::WlPointer>>, kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>,
keyboard: Option<Proxy<wl_keyboard::WlKeyboard>>, pointer: Option<wl_pointer::WlPointer>,
touch: Option<Proxy<wl_touch::WlTouch>>, keyboard: Option<wl_keyboard::WlKeyboard>,
<<<<<<< HEAD touch: Option<wl_touch::WlTouch>,
events_loop_proxy: EventsLoopProxy,
modifiers_tracker: Arc<Mutex<ModifiersState>>, modifiers_tracker: Arc<Mutex<ModifiersState>>,
=======
event_loop_proxy: EventLoopProxy,
>>>>>>> Change instances of "events_loop" to "event_loop"
} }
impl SeatData { 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 { match evt {
wl_seat::Event::Name { .. } => (), wl_seat::Event::Name { .. } => (),
wl_seat::Event::Capabilities { capabilities } => { wl_seat::Event::Capabilities { capabilities } => {
@ -416,8 +418,7 @@ impl SeatData {
// destroy pointer if applicable // destroy pointer if applicable
if !capabilities.contains(wl_seat::Capability::Pointer) { if !capabilities.contains(wl_seat::Capability::Pointer) {
if let Some(pointer) = self.pointer.take() { if let Some(pointer) = self.pointer.take() {
if pointer.version() >= 3 { if pointer.as_ref().version() >= 3 {
use self::wl_pointer::RequestsTrait;
pointer.release(); pointer.release();
} }
} }
@ -426,20 +427,14 @@ impl SeatData {
if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() { if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() {
self.keyboard = Some(super::keyboard::init_keyboard( self.keyboard = Some(super::keyboard::init_keyboard(
&seat, &seat,
self.sink.clone(), self.kbd_sender.clone(),
<<<<<<< HEAD
self.events_loop_proxy.clone(),
self.modifiers_tracker.clone(), self.modifiers_tracker.clone(),
=======
self.event_loop_proxy.clone(),
>>>>>>> Change instances of "events_loop" to "event_loop"
)) ))
} }
// destroy keyboard if applicable // destroy keyboard if applicable
if !capabilities.contains(wl_seat::Capability::Keyboard) { if !capabilities.contains(wl_seat::Capability::Keyboard) {
if let Some(kbd) = self.keyboard.take() { if let Some(kbd) = self.keyboard.take() {
if kbd.version() >= 3 { if kbd.as_ref().version() >= 3 {
use self::wl_keyboard::RequestsTrait;
kbd.release(); kbd.release();
} }
} }
@ -455,13 +450,13 @@ impl SeatData {
// destroy touch if applicable // destroy touch if applicable
if !capabilities.contains(wl_seat::Capability::Touch) { if !capabilities.contains(wl_seat::Capability::Touch) {
if let Some(touch) = self.touch.take() { if let Some(touch) = self.touch.take() {
if touch.version() >= 3 { if touch.as_ref().version() >= 3 {
use self::wl_touch::RequestsTrait;
touch.release(); touch.release();
} }
} }
} }
} },
_ => unreachable!()
} }
} }
} }
@ -469,20 +464,17 @@ impl SeatData {
impl Drop for SeatData { impl Drop for SeatData {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(pointer) = self.pointer.take() { if let Some(pointer) = self.pointer.take() {
if pointer.version() >= 3 { if pointer.as_ref().version() >= 3 {
use self::wl_pointer::RequestsTrait;
pointer.release(); pointer.release();
} }
} }
if let Some(kbd) = self.keyboard.take() { if let Some(kbd) = self.keyboard.take() {
if kbd.version() >= 3 { if kbd.as_ref().version() >= 3 {
use self::wl_keyboard::RequestsTrait;
kbd.release(); kbd.release();
} }
} }
if let Some(touch) = self.touch.take() { if let Some(touch) = self.touch.take() {
if touch.version() >= 3 { if touch.as_ref().version() >= 3 {
use self::wl_touch::RequestsTrait;
touch.release(); touch.release();
} }
} }
@ -494,7 +486,7 @@ impl Drop for SeatData {
*/ */
pub struct MonitorHandle { pub struct MonitorHandle {
pub(crate) proxy: Proxy<wl_output::WlOutput>, pub(crate) proxy: wl_output::WlOutput,
pub(crate) mgr: OutputMgr, pub(crate) mgr: OutputMgr,
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -1,38 +1,33 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak}; use std::sync::{Arc, Mutex, Weak};
use {CreationError, MouseCursor, WindowAttributes};
use dpi::{LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use platform_impl::MonitorHandle as PlatformMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use window::MonitorHandle as RootMonitorHandle; use window::{CreationError, WindowAttributes, MouseCursor};
=======
use platform::{MonitorId as PlatformMonitorId, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use window::MonitorId as RootMonitorId;
>>>>>>> master:src/platform/linux/wayland/window.rs
use sctk::surface::{get_dpi_factor, get_outputs}; use sctk::surface::{get_dpi_factor, get_outputs};
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow, Theme}; 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_seat, wl_surface};
use sctk::reexports::client::protocol::wl_surface::RequestsTrait as SurfaceRequests;
use sctk::output::OutputMgr; 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}; use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
pub struct Window { pub struct Window {
surface: Proxy<wl_surface::WlSurface>, surface: wl_surface::WlSurface,
frame: Arc<Mutex<SWindow<ConceptFrame>>>, frame: Arc<Mutex<SWindow<ConceptFrame>>>,
outputs: OutputMgr, // Access to info for all monitors outputs: OutputMgr, // Access to info for all monitors
size: Arc<Mutex<(u32, u32)>>, size: Arc<Mutex<(u32, u32)>>,
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>), kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
display: Arc<Display>, display: Arc<Display>,
need_frame_refresh: Arc<Mutex<bool>>, need_frame_refresh: Arc<Mutex<bool>>,
need_refresh: Arc<Mutex<bool>>
} }
impl Window { 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)); let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
// Create the window // Create the window
let size = Arc::new(Mutex::new((width, height))); let size = Arc::new(Mutex::new((width, height)));
@ -53,9 +48,9 @@ impl Window {
WEvent::Configure { new_size, .. } => { WEvent::Configure { new_size, .. } => {
let mut store = window_store.lock().unwrap(); let mut store = window_store.lock().unwrap();
for window in &mut store.windows { 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.newsize = new_size;
window.need_refresh = true; *(window.need_refresh.lock().unwrap()) = true;
*(window.need_frame_refresh.lock().unwrap()) = true; *(window.need_frame_refresh.lock().unwrap()) = true;
return; return;
} }
@ -64,7 +59,7 @@ impl Window {
WEvent::Refresh => { WEvent::Refresh => {
let store = window_store.lock().unwrap(); let store = window_store.lock().unwrap();
for window in &store.windows { 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; *(window.need_frame_refresh.lock().unwrap()) = true;
return; return;
} }
@ -73,7 +68,7 @@ impl Window {
WEvent::Close => { WEvent::Close => {
let mut store = window_store.lock().unwrap(); let mut store = window_store.lock().unwrap();
for window in &mut store.windows { 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; window.closed = true;
return; return;
} }
@ -105,6 +100,9 @@ impl Window {
// set decorations // set decorations
frame.set_decorate(attributes.decorations); frame.set_decorate(attributes.decorations);
// set title
frame.set_title(attributes.title);
// min-max dimensions // min-max dimensions
frame.set_min_size(attributes.min_dimensions.map(Into::into)); frame.set_min_size(attributes.min_dimensions.map(Into::into));
frame.set_max_size(attributes.max_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 kill_switch = Arc::new(Mutex::new(false));
let need_frame_refresh = Arc::new(Mutex::new(true)); let need_frame_refresh = Arc::new(Mutex::new(true));
let frame = Arc::new(Mutex::new(frame)); let frame = Arc::new(Mutex::new(frame));
let need_refresh = Arc::new(Mutex::new(true));
evlp.store.lock().unwrap().windows.push(InternalWindow { evlp.store.lock().unwrap().windows.push(InternalWindow {
closed: false, closed: false,
newsize: None, newsize: None,
size: size.clone(), size: size.clone(),
need_refresh: false, need_refresh: need_refresh.clone(),
need_frame_refresh: need_frame_refresh.clone(), need_frame_refresh: need_frame_refresh.clone(),
surface: surface.clone(), surface: surface.clone(),
kill_switch: kill_switch.clone(), kill_switch: kill_switch.clone(),
@ -134,7 +133,8 @@ impl Window {
outputs: evlp.env.outputs.clone(), outputs: evlp.env.outputs.clone(),
size: size, size: size,
kill_switch: (kill_switch, evlp.cleanup_needed.clone()), 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()) Some(self.size.lock().unwrap().clone().into())
} }
pub fn request_redraw(&self) {
*self.need_refresh.lock().unwrap() = true;
}
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn get_outer_size(&self) -> Option<LogicalSize> {
let (w, h) = self.size.lock().unwrap().clone(); let (w, h) = self.size.lock().unwrap().clone();
@ -269,24 +273,16 @@ impl Window {
&*self.display &*self.display
} }
pub fn get_surface(&self) -> &Proxy<wl_surface::WlSurface> { pub fn get_surface(&self) -> &wl_surface::WlSurface {
&self.surface &self.surface
} }
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
pub fn get_current_monitor(&self) -> MonitorHandle { 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(); let output = get_outputs(&self.surface).last().unwrap().clone();
MonitorId { MonitorHandle {
proxy: output, proxy: output,
mgr: self.outputs.clone(), mgr: self.outputs.clone(),
} }
>>>>>>> master:src/platform/linux/wayland/window.rs
} }
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
@ -310,10 +306,10 @@ impl Drop for Window {
*/ */
struct InternalWindow { struct InternalWindow {
surface: Proxy<wl_surface::WlSurface>, surface: wl_surface::WlSurface,
newsize: Option<(u32, u32)>, newsize: Option<(u32, u32)>,
size: Arc<Mutex<(u32, u32)>>, size: Arc<Mutex<(u32, u32)>>,
need_refresh: bool, need_refresh: Arc<Mutex<bool>>,
need_frame_refresh: Arc<Mutex<bool>>, need_frame_refresh: Arc<Mutex<bool>>,
closed: bool, closed: bool,
kill_switch: Arc<Mutex<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 { for window in &self.windows {
if surface.equals(&window.surface) { if surface.as_ref().equals(&window.surface.as_ref()) {
return Some(make_wid(surface)); return Some(make_wid(surface));
} }
} }
@ -357,7 +353,7 @@ impl WindowStore {
pruned 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 { for window in &self.windows {
if let Some(w) = window.frame.upgrade() { if let Some(w) = window.frame.upgrade() {
w.lock().unwrap().new_seat(seat); 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 { 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); window.new_dpi = Some(new);
} }
} }
@ -384,7 +380,7 @@ impl WindowStore {
window.newsize.take(), window.newsize.take(),
&mut *(window.size.lock().unwrap()), &mut *(window.size.lock().unwrap()),
window.new_dpi, 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), ::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
window.closed, window.closed,
make_wid(&window.surface), make_wid(&window.surface),
@ -393,59 +389,9 @@ impl WindowStore {
if let Some(dpi) = window.new_dpi.take() { if let Some(dpi) = window.new_dpi.take() {
window.current_dpi = dpi; window.current_dpi = dpi;
} }
window.need_refresh = false;
// avoid re-spamming the event // avoid re-spamming the event
window.closed = false; 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()>>; type ThreadExecFn = Box<Box<FnMut()>>;
#[derive(Clone)] #[derive(Clone)]
pub struct EventLoopProxy<T> { pub struct EventLoopProxy<T: 'static> {
target_window: HWND, target_window: HWND,
event_send: Sender<T>, 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> { pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
unsafe { unsafe {
if winuser::PostMessageW(self.target_window, *USER_EVENT_MSG_ID, 0, 0) != 0 { 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] #[test]
fn event_loop_proxy_send() { fn event_loop_proxy_send() {
fn is_send<T: Send>() { fn is_send<T: 'static + Send>() {
// ensures that `winit::EventLoopProxy` implements `Send` // ensures that `winit::EventLoopProxy` implements `Send`
needs_send::<winit::event_loop::EventLoopProxy<T>>(); needs_send::<winit::event_loop::EventLoopProxy<T>>();
} }