mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-09 21:01:29 +11:00
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:
parent
9602716ed2
commit
6513351e0c
|
@ -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"
|
||||
|
|
|
@ -163,11 +163,11 @@ impl<T> Deref for EventLoop<T> {
|
|||
|
||||
/// Used to send custom events to `EventLoop`.
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy<T> {
|
||||
pub struct EventLoopProxy<T: 'static> {
|
||||
event_loop_proxy: platform_impl::EventLoopProxy<T>,
|
||||
}
|
||||
|
||||
impl<T> EventLoopProxy<T> {
|
||||
impl<T: 'static> EventLoopProxy<T> {
|
||||
/// Send an event to the `EventLoop` from which this proxy was created. This emits a
|
||||
/// `UserEvent(event)` event in the event loop, where `event` is the value passed to this
|
||||
/// function.
|
||||
|
@ -178,7 +178,7 @@ impl<T> EventLoopProxy<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for EventLoopProxy<T> {
|
||||
impl<T: 'static> fmt::Debug for EventLoopProxy<T> {
|
||||
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmtr.pad("EventLoopProxy { .. }")
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -6,26 +6,24 @@ use std::sync::Arc;
|
|||
|
||||
use sctk::window::{ButtonState, Theme};
|
||||
|
||||
use {
|
||||
EventLoop,
|
||||
LogicalSize,
|
||||
MonitorHandle,
|
||||
Window,
|
||||
WindowBuilder,
|
||||
};
|
||||
use dpi::LogicalSize;
|
||||
use event_loop::EventLoop;
|
||||
use monitor::MonitorHandle;
|
||||
use window::{Window, WindowBuilder};
|
||||
|
||||
use platform_impl::{
|
||||
EventLoop as LinuxEventLoop,
|
||||
Window as LinuxWindow,
|
||||
};
|
||||
use platform_impl::x11::XConnection;
|
||||
use platform_impl::x11::ffi::XVisualInfo;
|
||||
|
||||
//use platform_impl::x11::XConnection;
|
||||
//use platform_impl::x11::ffi::XVisualInfo;
|
||||
//
|
||||
// TODO: stupid hack so that glutin can do its work
|
||||
#[doc(hidden)]
|
||||
pub use platform_impl::x11;
|
||||
|
||||
pub use platform_impl::XNotSupported;
|
||||
pub use platform_impl::x11::util::WindowType as XWindowType;
|
||||
//#[doc(hidden)]
|
||||
//pub use platform_impl::x11;
|
||||
//
|
||||
//pub use platform_impl::XNotSupported;
|
||||
//pub use platform_impl::x11::util::WindowType as XWindowType;
|
||||
|
||||
/// Theme for wayland client side decorations
|
||||
///
|
||||
|
@ -97,9 +95,9 @@ impl Theme for WaylandThemeObject {
|
|||
|
||||
/// Additional methods on `EventLoop` that are specific to Unix.
|
||||
pub trait EventLoopExtUnix {
|
||||
/// Builds a new `EventsLoop` that is forced to use X11.
|
||||
fn new_x11() -> Result<Self, XNotSupported>
|
||||
where Self: Sized;
|
||||
/// Builds a new `EventLoops` that is forced to use X11.
|
||||
//fn new_x11() -> Result<Self, XNotSupported>
|
||||
// where Self: Sized;
|
||||
|
||||
/// Builds a new `EventLoop` that is forced to use Wayland.
|
||||
fn new_wayland() -> Self
|
||||
|
@ -111,20 +109,20 @@ pub trait EventLoopExtUnix {
|
|||
/// True if the `EventLoop` uses X11.
|
||||
fn is_x11(&self) -> bool;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||
//#[doc(hidden)]
|
||||
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||
}
|
||||
|
||||
impl EventLoopExtUnix for EventLoop {
|
||||
#[inline]
|
||||
fn new_x11() -> Result<Self, XNotSupported> {
|
||||
LinuxEventLoop::new_x11().map(|ev|
|
||||
EventLoop {
|
||||
event_loop: ev,
|
||||
_marker: ::std::marker::PhantomData,
|
||||
}
|
||||
)
|
||||
}
|
||||
impl<T> EventLoopExtUnix for EventLoop<T> {
|
||||
//#[inline]
|
||||
//fn new_x11() -> Result<Self, XNotSupported> {
|
||||
// LinuxEventLoop::new_x11().map(|ev|
|
||||
// EventLoop {
|
||||
// event_loop: ev,
|
||||
// _marker: ::std::marker::PhantomData,
|
||||
// }
|
||||
// )
|
||||
//}
|
||||
|
||||
#[inline]
|
||||
fn new_wayland() -> Self {
|
||||
|
@ -147,11 +145,11 @@ impl EventLoopExtUnix for EventLoop {
|
|||
!self.event_loop.is_wayland()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||
self.event_loop.x_connection().cloned()
|
||||
}
|
||||
//#[inline]
|
||||
//#[doc(hidden)]
|
||||
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||
// self.event_loop.x_connection().cloned()
|
||||
//}
|
||||
}
|
||||
|
||||
/// Additional methods on `Window` that are specific to Unix.
|
||||
|
@ -170,8 +168,8 @@ pub trait WindowExtUnix {
|
|||
|
||||
fn get_xlib_screen_id(&self) -> Option<raw::c_int>;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||
//#[doc(hidden)]
|
||||
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||
|
||||
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
|
||||
fn set_urgent(&self, is_urgent: bool);
|
||||
|
@ -214,7 +212,7 @@ impl WindowExtUnix for Window {
|
|||
#[inline]
|
||||
fn get_xlib_window(&self) -> Option<raw::c_ulong> {
|
||||
match self.window {
|
||||
LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
|
||||
//LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +220,7 @@ impl WindowExtUnix for Window {
|
|||
#[inline]
|
||||
fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
|
||||
match self.window {
|
||||
LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
|
||||
//LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -230,39 +228,39 @@ impl WindowExtUnix for Window {
|
|||
#[inline]
|
||||
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
|
||||
match self.window {
|
||||
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
|
||||
//LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||
match self.window {
|
||||
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
//#[inline]
|
||||
//#[doc(hidden)]
|
||||
//fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||
// match self.window {
|
||||
// //LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
|
||||
// _ => None
|
||||
// }
|
||||
//}
|
||||
|
||||
#[inline]
|
||||
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
|
||||
match self.window {
|
||||
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
|
||||
//LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_urgent(&self, is_urgent: bool) {
|
||||
if let LinuxWindow::X(ref w) = self.window {
|
||||
w.set_urgent(is_urgent);
|
||||
}
|
||||
//if let LinuxWindow::X(ref w) = self.window {
|
||||
// w.set_urgent(is_urgent);
|
||||
//}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
|
||||
match self.window {
|
||||
LinuxWindow::Wayland(ref w) => Some(w.get_surface().c_ptr() as *mut _),
|
||||
LinuxWindow::Wayland(ref w) => Some(w.get_surface().as_ref().c_ptr() as *mut _),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +268,7 @@ impl WindowExtUnix for Window {
|
|||
#[inline]
|
||||
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
|
||||
match self.window {
|
||||
LinuxWindow::Wayland(ref w) => Some(w.get_display().c_ptr() as *mut _),
|
||||
LinuxWindow::Wayland(ref w) => Some(w.get_display().as_ref().c_ptr() as *mut _),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +297,7 @@ pub trait WindowBuilderExtUnix {
|
|||
/// Build window with override-redirect flag; defaults to false. Only relevant on X11.
|
||||
fn with_override_redirect(self, override_redirect: bool) -> WindowBuilder;
|
||||
/// Build window with `_NET_WM_WINDOW_TYPE` hint; defaults to `Normal`. Only relevant on X11.
|
||||
fn with_x11_window_type(self, x11_window_type: XWindowType) -> WindowBuilder;
|
||||
//fn with_x11_window_type(self, x11_window_type: XWindowType) -> WindowBuilder;
|
||||
/// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11.
|
||||
fn with_gtk_theme_variant(self, variant: String) -> WindowBuilder;
|
||||
/// Build window with resize increment hint. Only implemented on X11.
|
||||
|
@ -318,9 +316,9 @@ pub trait WindowBuilderExtUnix {
|
|||
impl WindowBuilderExtUnix for WindowBuilder {
|
||||
#[inline]
|
||||
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder {
|
||||
self.platform_specific.visual_infos = Some(
|
||||
unsafe { ptr::read(visual_infos as *const XVisualInfo) }
|
||||
);
|
||||
//self.platform_specific.visual_infos = Some(
|
||||
// unsafe { ptr::read(visual_infos as *const XVisualInfo) }
|
||||
//);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -342,11 +340,11 @@ impl WindowBuilderExtUnix for WindowBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
|
||||
self.platform_specific.x11_window_type = x11_window_type;
|
||||
self
|
||||
}
|
||||
//#[inline]
|
||||
//fn with_x11_window_type(mut self, x11_window_type: XWindowType) -> WindowBuilder {
|
||||
// self.platform_specific.x11_window_type = x11_window_type;
|
||||
// self
|
||||
//}
|
||||
|
||||
#[inline]
|
||||
fn with_resize_increments(mut self, increments: LogicalSize) -> WindowBuilder {
|
||||
|
|
|
@ -9,23 +9,18 @@ use std::sync::Arc;
|
|||
use parking_lot::Mutex;
|
||||
use sctk::reexports::client::ConnectError;
|
||||
|
||||
use {
|
||||
CreationError,
|
||||
EventLoopClosed,
|
||||
Icon,
|
||||
MouseCursor,
|
||||
ControlFlow,
|
||||
WindowAttributes,
|
||||
};
|
||||
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||
use window::MonitorHandle as RootMonitorHandle;
|
||||
use self::x11::{XConnection, XError};
|
||||
use self::x11::ffi::XVisualInfo;
|
||||
pub use self::x11::XNotSupported;
|
||||
use icon::Icon;
|
||||
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use window::{WindowAttributes, CreationError, MouseCursor};
|
||||
//use self::x11::{XConnection, XError};
|
||||
//use self::x11::ffi::XVisualInfo;
|
||||
//pub use self::x11::XNotSupported;
|
||||
|
||||
mod dlopen;
|
||||
pub mod wayland;
|
||||
pub mod x11;
|
||||
//pub mod x11;
|
||||
|
||||
/// Environment variable specifying which backend should be used on unix platform.
|
||||
///
|
||||
|
@ -38,55 +33,55 @@ const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND";
|
|||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||
pub visual_infos: Option<XVisualInfo>,
|
||||
//pub visual_infos: Option<XVisualInfo>,
|
||||
pub screen_id: Option<i32>,
|
||||
pub resize_increments: Option<(u32, u32)>,
|
||||
pub base_size: Option<(u32, u32)>,
|
||||
pub class: Option<(String, String)>,
|
||||
pub override_redirect: bool,
|
||||
pub x11_window_type: x11::util::WindowType,
|
||||
//pub x11_window_type: x11::util::WindowType,
|
||||
pub gtk_theme_variant: Option<String>,
|
||||
pub app_id: Option<String>
|
||||
}
|
||||
|
||||
lazy_static!(
|
||||
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
|
||||
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
|
||||
};
|
||||
);
|
||||
//lazy_static!(
|
||||
// pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
|
||||
// Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
|
||||
// };
|
||||
//);
|
||||
|
||||
pub enum Window {
|
||||
X(x11::Window),
|
||||
//X(x11::Window),
|
||||
Wayland(wayland::Window),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum WindowId {
|
||||
X(x11::WindowId),
|
||||
//X(x11::WindowId),
|
||||
Wayland(wayland::WindowId),
|
||||
}
|
||||
|
||||
impl WindowId {
|
||||
pub unsafe fn dummy() -> Self {
|
||||
WindowId::X(x11::WindowId::dummy())
|
||||
WindowId::Wayland(wayland::WindowId::dummy())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum DeviceId {
|
||||
X(x11::DeviceId),
|
||||
//X(x11::DeviceId),
|
||||
Wayland(wayland::DeviceId),
|
||||
}
|
||||
|
||||
impl DeviceId {
|
||||
pub unsafe fn dummy() -> Self {
|
||||
DeviceId::X(x11::DeviceId::dummy())
|
||||
DeviceId::Wayland(wayland::DeviceId::dummy())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MonitorHandle {
|
||||
X(x11::MonitorHandle),
|
||||
//X(x11::MonitorHandle),
|
||||
Wayland(wayland::MonitorHandle),
|
||||
}
|
||||
|
||||
|
@ -94,7 +89,7 @@ impl MonitorHandle {
|
|||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_name(),
|
||||
//&MonitorHandle::X(ref m) => m.get_name(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_name(),
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +97,7 @@ impl MonitorHandle {
|
|||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> u32 {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_native_identifier(),
|
||||
//&MonitorHandle::X(ref m) => m.get_native_identifier(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +105,7 @@ impl MonitorHandle {
|
|||
#[inline]
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_dimensions(),
|
||||
//&MonitorHandle::X(ref m) => m.get_dimensions(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_dimensions(),
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +113,7 @@ impl MonitorHandle {
|
|||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_position(),
|
||||
//&MonitorHandle::X(ref m) => m.get_position(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_position(),
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +121,7 @@ impl MonitorHandle {
|
|||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
|
||||
//&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
|
||||
}
|
||||
}
|
||||
|
@ -134,25 +129,25 @@ impl MonitorHandle {
|
|||
|
||||
impl Window {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
event_loop: &EventLoop,
|
||||
pub fn new<T>(
|
||||
window_target: &EventLoopWindowTarget<T>,
|
||||
attribs: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, CreationError> {
|
||||
match *event_loop {
|
||||
EventsLoop::Wayland(ref event_loop) => {
|
||||
wayland::Window::new(event_loop, attribs, pl_attribs).map(Window::Wayland)
|
||||
},
|
||||
EventLoop::X(ref event_loop) => {
|
||||
x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X)
|
||||
match *window_target {
|
||||
EventLoopWindowTarget::Wayland(ref window_target) => {
|
||||
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
|
||||
},
|
||||
//EventLoop::X(ref event_loop) => {
|
||||
// x11::Window::new(event_loop, attribs, pl_attribs).map(Window::X)
|
||||
//},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> WindowId {
|
||||
match self {
|
||||
&Window::X(ref w) => WindowId::X(w.id()),
|
||||
//&Window::X(ref w) => WindowId::X(w.id()),
|
||||
&Window::Wayland(ref w) => WindowId::Wayland(w.id()),
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +155,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_title(&self, title: &str) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_title(title),
|
||||
//&Window::X(ref w) => w.set_title(title),
|
||||
&Window::Wayland(ref w) => w.set_title(title),
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +163,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn show(&self) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.show(),
|
||||
//&Window::X(ref w) => w.show(),
|
||||
&Window::Wayland(ref w) => w.show(),
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +171,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.hide(),
|
||||
//&Window::X(ref w) => w.hide(),
|
||||
&Window::Wayland(ref w) => w.hide(),
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +179,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_position(),
|
||||
//&Window::X(ref w) => w.get_position(),
|
||||
&Window::Wayland(ref w) => w.get_position(),
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +187,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
match self {
|
||||
&Window::X(ref m) => m.get_inner_position(),
|
||||
//&Window::X(ref m) => m.get_inner_position(),
|
||||
&Window::Wayland(ref m) => m.get_inner_position(),
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +195,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_position(&self, position: LogicalPosition) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_position(position),
|
||||
//&Window::X(ref w) => w.set_position(position),
|
||||
&Window::Wayland(ref w) => w.set_position(position),
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +203,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_inner_size(),
|
||||
//&Window::X(ref w) => w.get_inner_size(),
|
||||
&Window::Wayland(ref w) => w.get_inner_size(),
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +211,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_outer_size(),
|
||||
//&Window::X(ref w) => w.get_outer_size(),
|
||||
&Window::Wayland(ref w) => w.get_outer_size(),
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +219,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_inner_size(size),
|
||||
//&Window::X(ref w) => w.set_inner_size(size),
|
||||
&Window::Wayland(ref w) => w.set_inner_size(size),
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +227,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_min_dimensions(dimensions),
|
||||
//&Window::X(ref w) => w.set_min_dimensions(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +235,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_max_dimensions(dimensions),
|
||||
//&Window::X(ref w) => w.set_max_dimensions(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +243,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_resizable(resizable),
|
||||
//&Window::X(ref w) => w.set_resizable(resizable),
|
||||
&Window::Wayland(ref w) => w.set_resizable(resizable),
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +251,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_cursor(cursor),
|
||||
//&Window::X(ref w) => w.set_cursor(cursor),
|
||||
&Window::Wayland(ref w) => w.set_cursor(cursor)
|
||||
}
|
||||
}
|
||||
|
@ -264,7 +259,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
match self {
|
||||
&Window::X(ref window) => window.grab_cursor(grab),
|
||||
//&Window::X(ref window) => window.grab_cursor(grab),
|
||||
&Window::Wayland(ref window) => window.grab_cursor(grab),
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +267,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
match self {
|
||||
&Window::X(ref window) => window.hide_cursor(hide),
|
||||
//&Window::X(ref window) => window.hide_cursor(hide),
|
||||
&Window::Wayland(ref window) => window.hide_cursor(hide),
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +275,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_hidpi_factor(),
|
||||
//&Window::X(ref w) => w.get_hidpi_factor(),
|
||||
&Window::Wayland(ref w) => w.hidpi_factor() as f64,
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +283,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_cursor_position(position),
|
||||
//&Window::X(ref w) => w.set_cursor_position(position),
|
||||
&Window::Wayland(ref w) => w.set_cursor_position(position),
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +291,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_maximized(&self, maximized: bool) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_maximized(maximized),
|
||||
//&Window::X(ref w) => w.set_maximized(maximized),
|
||||
&Window::Wayland(ref w) => w.set_maximized(maximized),
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +299,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_fullscreen(monitor),
|
||||
//&Window::X(ref w) => w.set_fullscreen(monitor),
|
||||
&Window::Wayland(ref w) => w.set_fullscreen(monitor)
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +307,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_decorations(&self, decorations: bool) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_decorations(decorations),
|
||||
//&Window::X(ref w) => w.set_decorations(decorations),
|
||||
&Window::Wayland(ref w) => w.set_decorations(decorations)
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +315,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_always_on_top(&self, always_on_top: bool) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_always_on_top(always_on_top),
|
||||
//&Window::X(ref w) => w.set_always_on_top(always_on_top),
|
||||
&Window::Wayland(_) => (),
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +323,7 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_window_icon(&self, window_icon: Option<Icon>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_window_icon(window_icon),
|
||||
//&Window::X(ref w) => w.set_window_icon(window_icon),
|
||||
&Window::Wayland(_) => (),
|
||||
}
|
||||
}
|
||||
|
@ -336,15 +331,23 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_ime_spot(&self, position: LogicalPosition) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_ime_spot(position),
|
||||
//&Window::X(ref w) => w.set_ime_spot(position),
|
||||
&Window::Wayland(_) => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_redraw(&self) {
|
||||
match self {
|
||||
//&Window::X(ref w) => w.request_redraw(),
|
||||
&Window::Wayland(ref w) => w.request_redraw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
match self {
|
||||
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
|
||||
//&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
|
||||
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
|
||||
}
|
||||
}
|
||||
|
@ -352,10 +355,10 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
match self {
|
||||
&Window::X(ref window) => window.get_available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::X)
|
||||
.collect(),
|
||||
//&Window::X(ref window) => window.get_available_monitors()
|
||||
// .into_iter()
|
||||
// .map(MonitorHandle::X)
|
||||
// .collect(),
|
||||
&Window::Wayland(ref window) => window.get_available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::Wayland)
|
||||
|
@ -366,12 +369,13 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
match self {
|
||||
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
|
||||
//&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
|
||||
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
unsafe extern "C" fn x_error_callback(
|
||||
display: *mut x11::ffi::Display,
|
||||
event: *mut x11::ffi::XErrorEvent,
|
||||
|
@ -401,20 +405,21 @@ unsafe extern "C" fn x_error_callback(
|
|||
// Fun fact: this return value is completely ignored.
|
||||
0
|
||||
}
|
||||
*/
|
||||
|
||||
pub enum EventLoop {
|
||||
Wayland(wayland::EventLoop),
|
||||
X(x11::EventLoop)
|
||||
pub enum EventLoop<T: 'static> {
|
||||
Wayland(wayland::EventLoop<T>),
|
||||
//X(x11::EventLoop)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum EventLoopProxy {
|
||||
X(x11::EventLoopProxy),
|
||||
Wayland(wayland::EventLoopProxy),
|
||||
pub enum EventLoopProxy<T: 'static> {
|
||||
//X(x11::EventLoopProxy),
|
||||
Wayland(wayland::EventLoopProxy<T>),
|
||||
}
|
||||
|
||||
impl EventLoop {
|
||||
pub fn new() -> EventLoop {
|
||||
impl<T:'static> EventLoop<T> {
|
||||
pub fn new() -> EventLoop<T> {
|
||||
if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) {
|
||||
match env_var.as_str() {
|
||||
"x11" => {
|
||||
|
@ -450,19 +455,20 @@ impl EventLoop {
|
|||
panic!(err_string);
|
||||
}
|
||||
|
||||
pub fn new_wayland() -> Result<EventLoop, ConnectError> {
|
||||
pub fn new_wayland() -> Result<EventLoop<T>, ConnectError> {
|
||||
wayland::EventLoop::new()
|
||||
.map(EventLoop::Wayland)
|
||||
}
|
||||
|
||||
pub fn new_x11() -> Result<EventLoop, XNotSupported> {
|
||||
X11_BACKEND
|
||||
.lock()
|
||||
.as_ref()
|
||||
.map(Arc::clone)
|
||||
.map(x11::EventLoop::new)
|
||||
.map(EventLoop::X)
|
||||
.map_err(|err| err.clone())
|
||||
pub fn new_x11() -> Result<EventLoop<T>, () /*XNotSupported*/> {
|
||||
//X11_BACKEND
|
||||
// .lock()
|
||||
// .as_ref()
|
||||
// .map(Arc::clone)
|
||||
// .map(x11::EventLoop::new)
|
||||
// .map(EventLoop::X)
|
||||
// .map_err(|err| err.clone())
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -473,12 +479,12 @@ impl EventLoop {
|
|||
.into_iter()
|
||||
.map(MonitorHandle::Wayland)
|
||||
.collect(),
|
||||
EventLoop::X(ref evlp) => evlp
|
||||
.x_connection()
|
||||
.get_available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::X)
|
||||
.collect(),
|
||||
//EventLoop::X(ref evlp) => evlp
|
||||
// .x_connection()
|
||||
// .get_available_monitors()
|
||||
// .into_iter()
|
||||
// .map(MonitorHandle::X)
|
||||
// .collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,32 +492,32 @@ impl EventLoop {
|
|||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
match *self {
|
||||
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()),
|
||||
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
|
||||
//EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||
match *self {
|
||||
EventLoop::Wayland(ref evlp) => EventLoopProxy::Wayland(evlp.create_proxy()),
|
||||
EventLoop::X(ref evlp) => EventLoopProxy::X(evlp.create_proxy()),
|
||||
//EventLoop::X(ref evlp) => EventLoopProxy::X(evlp.create_proxy()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll_events<F>(&mut self, callback: F)
|
||||
where F: FnMut(::Event)
|
||||
pub fn run_return<F>(&mut self, callback: F)
|
||||
where F: FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
match *self {
|
||||
EventLoop::Wayland(ref mut evlp) => evlp.poll_events(callback),
|
||||
EventLoop::X(ref mut evlp) => evlp.poll_events(callback)
|
||||
EventLoop::Wayland(ref mut evlp) => evlp.run_return(callback),
|
||||
//EventLoop::X(ref mut evlp) => evlp.run_return(callback)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_forever<F>(&mut self, callback: F)
|
||||
where F: FnMut(::Event) -> ControlFlow
|
||||
pub fn run<F>(self, callback: F) -> !
|
||||
where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
match *self {
|
||||
EventLoop::Wayland(ref mut evlp) => evlp.run_forever(callback),
|
||||
EventLoop::X(ref mut evlp) => evlp.run_forever(callback)
|
||||
match self {
|
||||
EventLoop::Wayland(evlp) => evlp.run(callback),
|
||||
//EventLoop::X(ref mut evlp) => evlp.run(callback)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,24 +525,36 @@ impl EventLoop {
|
|||
pub fn is_wayland(&self) -> bool {
|
||||
match *self {
|
||||
EventLoop::Wayland(_) => true,
|
||||
EventLoop::X(_) => false,
|
||||
//EventLoop::X(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn x_connection(&self) -> Option<&Arc<XConnection>> {
|
||||
pub fn window_target(&self) -> &::event_loop::EventLoopWindowTarget<T> {
|
||||
match *self {
|
||||
EventLoop::Wayland(_) => None,
|
||||
EventLoop::X(ref ev) => Some(ev.x_connection()),
|
||||
EventLoop::Wayland(ref evl) => evl.window_target(),
|
||||
//EventLoop::X(ref evl) => evl.window_target()
|
||||
}
|
||||
}
|
||||
|
||||
//#[inline]
|
||||
//pub fn x_connection(&self) -> Option<&Arc<XConnection>> {
|
||||
// match *self {
|
||||
// EventLoop::Wayland(_) => None,
|
||||
// EventLoop::X(ref ev) => Some(ev.x_connection()),
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
impl<T: 'static> EventLoopProxy<T> {
|
||||
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
|
||||
match *self {
|
||||
EventLoopProxy::Wayland(ref proxy) => proxy.send_event(event),
|
||||
//EventLoopProxy::X(ref proxy) => proxy.wakeup(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
pub fn wakeup(&self) -> Result<(), EventLoopClosed> {
|
||||
match *self {
|
||||
EventLoopProxy::Wayland(ref proxy) => proxy.wakeup(),
|
||||
EventLoopProxy::X(ref proxy) => proxy.wakeup(),
|
||||
}
|
||||
}
|
||||
pub enum EventLoopWindowTarget<T> {
|
||||
Wayland(wayland::EventLoopWindowTarget<T>),
|
||||
//X(x11::EventLoopWIndowTarget<T>)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
|
||||
use {ControlFlow, EventLoopClosed, PhysicalPosition, PhysicalSize};
|
||||
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
|
||||
use event::ModifiersState;
|
||||
use dpi::{PhysicalPosition, PhysicalSize};
|
||||
|
||||
use super::window::WindowStore;
|
||||
use super::WindowId;
|
||||
|
@ -13,54 +16,61 @@ use sctk::output::OutputMgr;
|
|||
use sctk::reexports::client::protocol::{
|
||||
wl_keyboard, wl_output, wl_pointer, wl_registry, wl_seat, wl_touch,
|
||||
};
|
||||
use sctk::reexports::client::{ConnectError, Display, EventQueue, GlobalEvent, Proxy};
|
||||
use sctk::reexports::client::{ConnectError, Display, EventQueue, GlobalEvent};
|
||||
use sctk::Environment;
|
||||
|
||||
use sctk::reexports::client::protocol::wl_display::RequestsTrait as DisplayRequests;
|
||||
use sctk::reexports::client::protocol::wl_surface::RequestsTrait;
|
||||
|
||||
use ModifiersState;
|
||||
|
||||
pub struct EventLoopSink {
|
||||
buffer: VecDeque<::Event>,
|
||||
pub struct WindowEventsSink {
|
||||
buffer: VecDeque<(::event::WindowEvent, ::window::WindowId)>,
|
||||
}
|
||||
|
||||
impl EventLoopSink {
|
||||
pub fn new() -> EventLoopSink {
|
||||
EventLoopSink {
|
||||
impl WindowEventsSink {
|
||||
pub fn new() -> WindowEventsSink {
|
||||
WindowEventsSink {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_event(&mut self, evt: ::WindowEvent, wid: WindowId) {
|
||||
let evt = ::Event::WindowEvent {
|
||||
event: evt,
|
||||
window_id: ::WindowId(::platform::WindowId::Wayland(wid)),
|
||||
};
|
||||
self.buffer.push_back(evt);
|
||||
pub fn send_event(&mut self, evt: ::event::WindowEvent, wid: WindowId) {
|
||||
self.buffer.push_back((evt, ::window::WindowId(::platform_impl::WindowId::Wayland(wid))));
|
||||
}
|
||||
|
||||
pub fn send_raw_event(&mut self, evt: ::Event) {
|
||||
self.buffer.push_back(evt);
|
||||
}
|
||||
|
||||
fn empty_with<F>(&mut self, callback: &mut F)
|
||||
fn empty_with<F, T>(&mut self, mut callback: F)
|
||||
where
|
||||
F: FnMut(::Event),
|
||||
F: FnMut(::event::Event<T>),
|
||||
{
|
||||
for evt in self.buffer.drain(..) {
|
||||
callback(evt)
|
||||
for (evt, wid) in self.buffer.drain(..) {
|
||||
callback(::event::Event::WindowEvent { event: evt, window_id: wid})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventLoop {
|
||||
// The Event Queue
|
||||
pub evq: RefCell<EventQueue>,
|
||||
pub struct EventLoop<T: 'static> {
|
||||
// The loop
|
||||
inner_loop: ::calloop::EventLoop<()>,
|
||||
// The wayland display
|
||||
pub display: Arc<Display>,
|
||||
// the output manager
|
||||
pub outputs: OutputMgr,
|
||||
// our sink, shared with some handlers, buffering the events
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
// Whether or not there is a pending `Awakened` event to be emitted.
|
||||
pending_wakeup: Arc<AtomicBool>,
|
||||
sink: Arc<Mutex<WindowEventsSink>>,
|
||||
pending_user_events: Rc<RefCell<VecDeque<T>>>,
|
||||
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
|
||||
user_sender: ::calloop::channel::Sender<T>,
|
||||
_kbd_source: ::calloop::Source<::calloop::channel::Channel<(::event::WindowEvent, super::WindowId)>>,
|
||||
window_target: RootELW<T>
|
||||
}
|
||||
|
||||
// A handle that can be sent across threads and used to wake up the `EventLoop`.
|
||||
//
|
||||
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy<T: 'static> {
|
||||
user_sender: ::calloop::channel::Sender<T>
|
||||
}
|
||||
|
||||
pub struct EventLoopWindowTarget<T> {
|
||||
// the event queue
|
||||
pub evq: RefCell<::calloop::Source<EventQueue>>,
|
||||
// The window store
|
||||
pub store: Arc<Mutex<WindowStore>>,
|
||||
// the env
|
||||
|
@ -70,57 +80,40 @@ pub struct EventLoop {
|
|||
// The wayland display
|
||||
pub display: Arc<Display>,
|
||||
// The list of seats
|
||||
pub seats: Arc<Mutex<Vec<(u32, Proxy<wl_seat::WlSeat>)>>>,
|
||||
pub seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
|
||||
_marker: ::std::marker::PhantomData<T>
|
||||
}
|
||||
|
||||
// A handle that can be sent across threads and used to wake up the `EventLoop`.
|
||||
//
|
||||
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy {
|
||||
display: Weak<Display>,
|
||||
pending_wakeup: Weak<AtomicBool>,
|
||||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
// Causes the `EventLoop` to stop blocking on `run_forever` and emit an `Awakened` event.
|
||||
//
|
||||
// Returns `Err` if the associated `EventLoop` no longer exists.
|
||||
pub fn wakeup(&self) -> Result<(), EventLoopClosed> {
|
||||
let display = self.display.upgrade();
|
||||
let wakeup = self.pending_wakeup.upgrade();
|
||||
match (display, wakeup) {
|
||||
(Some(display), Some(wakeup)) => {
|
||||
// Update the `EventLoop`'s `pending_wakeup` flag.
|
||||
wakeup.store(true, Ordering::Relaxed);
|
||||
// Cause the `EventLoop` to break from `dispatch` if it is currently blocked.
|
||||
let _ = display.sync(|callback| callback.implement(|_, _| {}, ()));
|
||||
display.flush().map_err(|_| EventLoopClosed)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(EventLoopClosed),
|
||||
}
|
||||
impl<T: 'static> EventLoopProxy<T> {
|
||||
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
|
||||
self.user_sender.send(event).map_err(|_| EventLoopClosed)
|
||||
}
|
||||
}
|
||||
|
||||
impl EventLoop {
|
||||
pub fn new() -> Result<EventLoop, ConnectError> {
|
||||
impl<T: 'static> EventLoop<T> {
|
||||
pub fn new() -> Result<EventLoop<T>, ConnectError> {
|
||||
let (display, mut event_queue) = Display::connect_to_env()?;
|
||||
|
||||
let display = Arc::new(display);
|
||||
let pending_wakeup = Arc::new(AtomicBool::new(false));
|
||||
let sink = Arc::new(Mutex::new(EventLoopSink::new()));
|
||||
let sink = Arc::new(Mutex::new(WindowEventsSink::new()));
|
||||
let store = Arc::new(Mutex::new(WindowStore::new()));
|
||||
let seats = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let inner_loop = ::calloop::EventLoop::new().unwrap();
|
||||
|
||||
let (kbd_sender, kbd_channel) = ::calloop::channel::channel();
|
||||
let kbd_sink = sink.clone();
|
||||
let kbd_source = inner_loop.handle().insert_source(kbd_channel, move |evt, &mut()| {
|
||||
if let ::calloop::channel::Event::Msg((evt, wid)) = evt {
|
||||
kbd_sink.lock().unwrap().send_event(evt, wid);
|
||||
}
|
||||
}).unwrap();
|
||||
|
||||
let mut seat_manager = SeatManager {
|
||||
sink: sink.clone(),
|
||||
store: store.clone(),
|
||||
seats: seats.clone(),
|
||||
events_loop_proxy: EventsLoopProxy {
|
||||
display: Arc::downgrade(&display),
|
||||
pending_wakeup: Arc::downgrade(&pending_wakeup),
|
||||
},
|
||||
kbd_sender,
|
||||
};
|
||||
|
||||
let env = Environment::from_display_with_cb(
|
||||
|
@ -142,92 +135,160 @@ impl EventLoop {
|
|||
},
|
||||
).unwrap();
|
||||
|
||||
let source = inner_loop.handle().insert_source(event_queue, |(), &mut ()| {}).unwrap();
|
||||
|
||||
let pending_user_events = Rc::new(RefCell::new(VecDeque::new()));
|
||||
let pending_user_events2 = pending_user_events.clone();
|
||||
|
||||
let (user_sender, user_channel) = ::calloop::channel::channel();
|
||||
|
||||
let user_source = inner_loop.handle().insert_source(user_channel, move |evt, &mut()| {
|
||||
if let ::calloop::channel::Event::Msg(msg) = evt {
|
||||
pending_user_events2.borrow_mut().push_back(msg);
|
||||
}
|
||||
}).unwrap();
|
||||
|
||||
Ok(EventLoop {
|
||||
display,
|
||||
evq: RefCell::new(event_queue),
|
||||
inner_loop,
|
||||
sink,
|
||||
pending_wakeup,
|
||||
store,
|
||||
env,
|
||||
cleanup_needed: Arc::new(Mutex::new(false)),
|
||||
seats,
|
||||
pending_user_events,
|
||||
display: display.clone(),
|
||||
outputs: env.outputs.clone(),
|
||||
_user_source: user_source,
|
||||
user_sender,
|
||||
_kbd_source: kbd_source,
|
||||
window_target: RootELW {
|
||||
p: ::platform_impl::EventLoopWindowTarget::Wayland(EventLoopWindowTarget {
|
||||
evq: RefCell::new(source),
|
||||
store,
|
||||
env,
|
||||
cleanup_needed: Arc::new(Mutex::new(false)),
|
||||
seats,
|
||||
display,
|
||||
_marker: ::std::marker::PhantomData
|
||||
}),
|
||||
_marker: ::std::marker::PhantomData
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||
EventLoopProxy {
|
||||
display: Arc::downgrade(&self.display),
|
||||
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
|
||||
user_sender: self.user_sender.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll_events<F>(&mut self, mut callback: F)
|
||||
where
|
||||
F: FnMut(::Event),
|
||||
pub fn run<F>(mut self, callback: F) -> !
|
||||
where F: 'static + FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
self.run_return(callback);
|
||||
::std::process::exit(0);
|
||||
}
|
||||
|
||||
pub fn run_return<F>(&mut self, mut callback: F)
|
||||
where F: FnMut(::event::Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
// send pending events to the server
|
||||
self.display.flush().expect("Wayland connection lost.");
|
||||
|
||||
// dispatch any pre-buffered events
|
||||
self.sink.lock().unwrap().empty_with(&mut callback);
|
||||
let mut control_flow = ControlFlow::default();
|
||||
|
||||
// try to read pending events
|
||||
if let Some(h) = self.evq.get_mut().prepare_read() {
|
||||
h.read_events().expect("Wayland connection lost.");
|
||||
}
|
||||
// dispatch wayland events
|
||||
self.evq
|
||||
.get_mut()
|
||||
.dispatch_pending()
|
||||
.expect("Wayland connection lost.");
|
||||
self.post_dispatch_triggers();
|
||||
let sink = self.sink.clone();
|
||||
let user_events = self.pending_user_events.clone();
|
||||
|
||||
// dispatch buffered events to client
|
||||
self.sink.lock().unwrap().empty_with(&mut callback);
|
||||
}
|
||||
|
||||
pub fn run_forever<F>(&mut self, mut callback: F)
|
||||
where
|
||||
F: FnMut(::Event) -> ControlFlow,
|
||||
{
|
||||
// send pending events to the server
|
||||
self.display.flush().expect("Wayland connection lost.");
|
||||
|
||||
// Check for control flow by wrapping the callback.
|
||||
let control_flow = ::std::cell::Cell::new(ControlFlow::Continue);
|
||||
let mut callback = |event| {
|
||||
if let ControlFlow::Break = callback(event) {
|
||||
control_flow.set(ControlFlow::Break);
|
||||
}
|
||||
};
|
||||
|
||||
// dispatch any pre-buffered events
|
||||
self.post_dispatch_triggers();
|
||||
self.sink.lock().unwrap().empty_with(&mut callback);
|
||||
callback(::event::Event::NewEvents(::event::StartCause::Init), &self.window_target, &mut control_flow);
|
||||
|
||||
loop {
|
||||
// dispatch events blocking if needed
|
||||
self.evq
|
||||
.get_mut()
|
||||
.dispatch()
|
||||
.expect("Wayland connection lost.");
|
||||
self.post_dispatch_triggers();
|
||||
|
||||
// empty buffer of events
|
||||
self.sink.lock().unwrap().empty_with(&mut callback);
|
||||
{
|
||||
let mut guard = sink.lock().unwrap();
|
||||
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow));
|
||||
}
|
||||
// empty user events
|
||||
{
|
||||
let mut guard = user_events.borrow_mut();
|
||||
for evt in guard.drain(..) {
|
||||
callback(::event::Event::UserEvent(evt), &self.window_target, &mut control_flow);
|
||||
}
|
||||
}
|
||||
|
||||
if let ControlFlow::Break = control_flow.get() {
|
||||
break;
|
||||
callback(::event::Event::EventsCleared, &self.window_target, &mut control_flow);
|
||||
|
||||
// fo a second run of post-dispatch-triggers, to handle user-generated "request-redraw"
|
||||
self.post_dispatch_triggers();
|
||||
{
|
||||
let mut guard = sink.lock().unwrap();
|
||||
guard.empty_with(|evt| callback(evt, &self.window_target, &mut control_flow));
|
||||
}
|
||||
|
||||
// send pending events to the server
|
||||
self.display.flush().expect("Wayland connection lost.");
|
||||
|
||||
match control_flow {
|
||||
ControlFlow::Exit => break,
|
||||
ControlFlow::Poll => {
|
||||
// non-blocking dispatch
|
||||
self.inner_loop.dispatch(Some(::std::time::Duration::from_millis(0)), &mut ()).unwrap();
|
||||
control_flow = ControlFlow::default();
|
||||
callback(::event::Event::NewEvents(::event::StartCause::Poll), &self.window_target, &mut control_flow);
|
||||
},
|
||||
ControlFlow::Wait => {
|
||||
self.inner_loop.dispatch(None, &mut ()).unwrap();
|
||||
control_flow = ControlFlow::default();
|
||||
callback(
|
||||
::event::Event::NewEvents(::event::StartCause::WaitCancelled {
|
||||
start: Instant::now(),
|
||||
requested_resume: None
|
||||
}),
|
||||
&self.window_target,
|
||||
&mut control_flow
|
||||
);
|
||||
},
|
||||
ControlFlow::WaitUntil(deadline) => {
|
||||
let start = Instant::now();
|
||||
// compute the blocking duration
|
||||
let duration = deadline.duration_since(::std::cmp::max(deadline, start));
|
||||
self.inner_loop.dispatch(Some(duration), &mut ()).unwrap();
|
||||
control_flow = ControlFlow::default();
|
||||
let now = Instant::now();
|
||||
if now < deadline {
|
||||
callback(
|
||||
::event::Event::NewEvents(::event::StartCause::WaitCancelled {
|
||||
start,
|
||||
requested_resume: Some(deadline)
|
||||
}),
|
||||
&self.window_target,
|
||||
&mut control_flow
|
||||
);
|
||||
} else {
|
||||
callback(
|
||||
::event::Event::NewEvents(::event::StartCause::ResumeTimeReached {
|
||||
start,
|
||||
requested_resume: deadline
|
||||
}),
|
||||
&self.window_target,
|
||||
&mut control_flow
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
get_primary_monitor(&self.env.outputs)
|
||||
get_primary_monitor(&self.outputs)
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
get_available_monitors(&self.env.outputs)
|
||||
get_available_monitors(&self.outputs)
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootELW<T> {
|
||||
&self.window_target
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,34 +296,33 @@ impl EventLoop {
|
|||
* Private EventLoop Internals
|
||||
*/
|
||||
|
||||
impl EventLoop {
|
||||
impl<T> EventLoop<T> {
|
||||
fn post_dispatch_triggers(&mut self) {
|
||||
let mut sink = self.sink.lock().unwrap();
|
||||
// process a possible pending wakeup call
|
||||
if self.pending_wakeup.load(Ordering::Relaxed) {
|
||||
sink.send_raw_event(::Event::Awakened);
|
||||
self.pending_wakeup.store(false, Ordering::Relaxed);
|
||||
}
|
||||
let window_target = match self.window_target.p {
|
||||
::platform_impl::EventLoopWindowTarget::Wayland(ref wt) => wt,
|
||||
_ => unreachable!()
|
||||
};
|
||||
// prune possible dead windows
|
||||
{
|
||||
let mut cleanup_needed = self.cleanup_needed.lock().unwrap();
|
||||
let mut cleanup_needed = window_target.cleanup_needed.lock().unwrap();
|
||||
if *cleanup_needed {
|
||||
let pruned = self.store.lock().unwrap().cleanup();
|
||||
let pruned = window_target.store.lock().unwrap().cleanup();
|
||||
*cleanup_needed = false;
|
||||
for wid in pruned {
|
||||
sink.send_event(::WindowEvent::Destroyed, wid);
|
||||
sink.send_event(::event::WindowEvent::Destroyed, wid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// process pending resize/refresh
|
||||
self.store.lock().unwrap().for_each(
|
||||
window_target.store.lock().unwrap().for_each(
|
||||
|newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
|
||||
if let Some(frame) = frame {
|
||||
if let Some((w, h)) = newsize {
|
||||
frame.resize(w, h);
|
||||
frame.refresh();
|
||||
let logical_size = ::LogicalSize::new(w as f64, h as f64);
|
||||
sink.send_event(::WindowEvent::Resized(logical_size), wid);
|
||||
let logical_size = ::dpi::LogicalSize::new(w as f64, h as f64);
|
||||
sink.send_event(::event::WindowEvent::Resized(logical_size), wid);
|
||||
*size = (w, h);
|
||||
} else if frame_refresh {
|
||||
frame.refresh();
|
||||
|
@ -272,13 +332,13 @@ impl EventLoop {
|
|||
}
|
||||
}
|
||||
if let Some(dpi) = new_dpi {
|
||||
sink.send_event(::WindowEvent::HiDpiFactorChanged(dpi as f64), wid);
|
||||
sink.send_event(::event::WindowEvent::HiDpiFactorChanged(dpi as f64), wid);
|
||||
}
|
||||
if refresh {
|
||||
sink.send_event(::WindowEvent::Redraw, wid);
|
||||
sink.send_event(::event::WindowEvent::RedrawRequested, wid);
|
||||
}
|
||||
if closed {
|
||||
sink.send_event(::WindowEvent::CloseRequested, wid);
|
||||
sink.send_event(::event::WindowEvent::CloseRequested, wid);
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -290,15 +350,14 @@ impl EventLoop {
|
|||
*/
|
||||
|
||||
struct SeatManager {
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
sink: Arc<Mutex<WindowEventsSink>>,
|
||||
store: Arc<Mutex<WindowStore>>,
|
||||
seats: Arc<Mutex<Vec<(u32, Proxy<wl_seat::WlSeat>)>>>,
|
||||
event_loop_proxy: EventLoopProxy,
|
||||
seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
|
||||
kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>
|
||||
}
|
||||
|
||||
impl SeatManager {
|
||||
fn add_seat(&mut self, id: u32, version: u32, registry: Proxy<wl_registry::WlRegistry>) {
|
||||
use self::wl_registry::RequestsTrait as RegistryRequests;
|
||||
fn add_seat(&mut self, id: u32, version: u32, registry: wl_registry::WlRegistry) {
|
||||
use std::cmp::min;
|
||||
|
||||
let mut seat_data = SeatData {
|
||||
|
@ -307,12 +366,12 @@ impl SeatManager {
|
|||
pointer: None,
|
||||
keyboard: None,
|
||||
touch: None,
|
||||
events_loop_proxy: self.events_loop_proxy.clone(),
|
||||
kbd_sender: self.kbd_sender.clone(),
|
||||
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
||||
};
|
||||
let seat = registry
|
||||
.bind(min(version, 5), id, move |seat| {
|
||||
seat.implement(move |event, seat| {
|
||||
seat.implement_closure(move |event, seat| {
|
||||
seat_data.receive(event, seat)
|
||||
}, ())
|
||||
})
|
||||
|
@ -322,85 +381,28 @@ impl SeatManager {
|
|||
}
|
||||
|
||||
fn remove_seat(&mut self, id: u32) {
|
||||
use self::wl_seat::RequestsTrait as SeatRequests;
|
||||
<<<<<<< HEAD:src/platform_impl/linux/wayland/event_loop.rs
|
||||
match evt {
|
||||
GlobalEvent::New {
|
||||
id,
|
||||
ref interface,
|
||||
version,
|
||||
} if interface == "wl_seat" =>
|
||||
{
|
||||
use std::cmp::min;
|
||||
|
||||
let mut seat_data = SeatData {
|
||||
sink: self.sink.clone(),
|
||||
store: self.store.clone(),
|
||||
pointer: None,
|
||||
keyboard: None,
|
||||
touch: None,
|
||||
events_loop_proxy: self.events_loop_proxy.clone(),
|
||||
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
||||
};
|
||||
let seat = registry
|
||||
<<<<<<< HEAD
|
||||
.bind(min(version, 5), id, move |seat| {
|
||||
seat.implement(move |event, seat| {
|
||||
seat_data.receive(event, seat)
|
||||
}, ())
|
||||
})
|
||||
.unwrap();
|
||||
=======
|
||||
.bind::<wl_seat::WlSeat>(min(version, 5), id)
|
||||
.unwrap()
|
||||
.implement(SeatData {
|
||||
sink: self.sink.clone(),
|
||||
store: self.store.clone(),
|
||||
pointer: None,
|
||||
keyboard: None,
|
||||
touch: None,
|
||||
event_loop_proxy: self.event_loop_proxy.clone(),
|
||||
});
|
||||
>>>>>>> Change instances of "events_loop" to "event_loop"
|
||||
self.store.lock().unwrap().new_seat(&seat);
|
||||
self.seats.lock().unwrap().push((id, seat));
|
||||
}
|
||||
GlobalEvent::Removed { id, ref interface } if interface == "wl_seat" => {
|
||||
let mut seats = self.seats.lock().unwrap();
|
||||
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
|
||||
let (_, seat) = seats.swap_remove(idx);
|
||||
if seat.version() >= 5 {
|
||||
seat.release();
|
||||
}
|
||||
}
|
||||
=======
|
||||
let mut seats = self.seats.lock().unwrap();
|
||||
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
|
||||
let (_, seat) = seats.swap_remove(idx);
|
||||
if seat.version() >= 5 {
|
||||
if seat.as_ref().version() >= 5 {
|
||||
seat.release();
|
||||
>>>>>>> master:src/platform/linux/wayland/event_loop.rs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SeatData {
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
sink: Arc<Mutex<WindowEventsSink>>,
|
||||
store: Arc<Mutex<WindowStore>>,
|
||||
pointer: Option<Proxy<wl_pointer::WlPointer>>,
|
||||
keyboard: Option<Proxy<wl_keyboard::WlKeyboard>>,
|
||||
touch: Option<Proxy<wl_touch::WlTouch>>,
|
||||
<<<<<<< HEAD
|
||||
events_loop_proxy: EventsLoopProxy,
|
||||
kbd_sender: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>,
|
||||
pointer: Option<wl_pointer::WlPointer>,
|
||||
keyboard: Option<wl_keyboard::WlKeyboard>,
|
||||
touch: Option<wl_touch::WlTouch>,
|
||||
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
||||
=======
|
||||
event_loop_proxy: EventLoopProxy,
|
||||
>>>>>>> Change instances of "events_loop" to "event_loop"
|
||||
}
|
||||
|
||||
impl SeatData {
|
||||
fn receive(&mut self, evt: wl_seat::Event, seat: Proxy<wl_seat::WlSeat>) {
|
||||
fn receive(&mut self, evt: wl_seat::Event, seat: wl_seat::WlSeat) {
|
||||
match evt {
|
||||
wl_seat::Event::Name { .. } => (),
|
||||
wl_seat::Event::Capabilities { capabilities } => {
|
||||
|
@ -416,8 +418,7 @@ impl SeatData {
|
|||
// destroy pointer if applicable
|
||||
if !capabilities.contains(wl_seat::Capability::Pointer) {
|
||||
if let Some(pointer) = self.pointer.take() {
|
||||
if pointer.version() >= 3 {
|
||||
use self::wl_pointer::RequestsTrait;
|
||||
if pointer.as_ref().version() >= 3 {
|
||||
pointer.release();
|
||||
}
|
||||
}
|
||||
|
@ -426,20 +427,14 @@ impl SeatData {
|
|||
if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() {
|
||||
self.keyboard = Some(super::keyboard::init_keyboard(
|
||||
&seat,
|
||||
self.sink.clone(),
|
||||
<<<<<<< HEAD
|
||||
self.events_loop_proxy.clone(),
|
||||
self.kbd_sender.clone(),
|
||||
self.modifiers_tracker.clone(),
|
||||
=======
|
||||
self.event_loop_proxy.clone(),
|
||||
>>>>>>> Change instances of "events_loop" to "event_loop"
|
||||
))
|
||||
}
|
||||
// destroy keyboard if applicable
|
||||
if !capabilities.contains(wl_seat::Capability::Keyboard) {
|
||||
if let Some(kbd) = self.keyboard.take() {
|
||||
if kbd.version() >= 3 {
|
||||
use self::wl_keyboard::RequestsTrait;
|
||||
if kbd.as_ref().version() >= 3 {
|
||||
kbd.release();
|
||||
}
|
||||
}
|
||||
|
@ -455,13 +450,13 @@ impl SeatData {
|
|||
// destroy touch if applicable
|
||||
if !capabilities.contains(wl_seat::Capability::Touch) {
|
||||
if let Some(touch) = self.touch.take() {
|
||||
if touch.version() >= 3 {
|
||||
use self::wl_touch::RequestsTrait;
|
||||
if touch.as_ref().version() >= 3 {
|
||||
touch.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,20 +464,17 @@ impl SeatData {
|
|||
impl Drop for SeatData {
|
||||
fn drop(&mut self) {
|
||||
if let Some(pointer) = self.pointer.take() {
|
||||
if pointer.version() >= 3 {
|
||||
use self::wl_pointer::RequestsTrait;
|
||||
if pointer.as_ref().version() >= 3 {
|
||||
pointer.release();
|
||||
}
|
||||
}
|
||||
if let Some(kbd) = self.keyboard.take() {
|
||||
if kbd.version() >= 3 {
|
||||
use self::wl_keyboard::RequestsTrait;
|
||||
if kbd.as_ref().version() >= 3 {
|
||||
kbd.release();
|
||||
}
|
||||
}
|
||||
if let Some(touch) = self.touch.take() {
|
||||
if touch.version() >= 3 {
|
||||
use self::wl_touch::RequestsTrait;
|
||||
if touch.as_ref().version() >= 3 {
|
||||
touch.release();
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +486,7 @@ impl Drop for SeatData {
|
|||
*/
|
||||
|
||||
pub struct MonitorHandle {
|
||||
pub(crate) proxy: Proxy<wl_output::WlOutput>,
|
||||
pub(crate) proxy: wl_output::WlOutput,
|
||||
pub(crate) mgr: OutputMgr,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::{make_wid, DeviceId, EventLoopProxy, EventLoopSink};
|
||||
use super::{make_wid, DeviceId};
|
||||
use sctk::keyboard::{
|
||||
self, map_keyboard_auto_with_repeat, Event as KbEvent, KeyRepeatEvent, KeyRepeatKind,
|
||||
};
|
||||
use sctk::reexports::client::protocol::wl_keyboard;
|
||||
use sctk::reexports::client::Proxy;
|
||||
use sctk::reexports::client::protocol::wl_seat;
|
||||
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
|
||||
use sctk::reexports::client::protocol::{wl_keyboard, wl_seat};
|
||||
|
||||
use {ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};
|
||||
use event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};
|
||||
|
||||
pub fn init_keyboard(
|
||||
seat: &Proxy<wl_seat::WlSeat>,
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
event_loop_proxy: EventLoopProxy,
|
||||
seat: &wl_seat::WlSeat,
|
||||
sink: ::calloop::channel::Sender<(::event::WindowEvent, super::WindowId)>,
|
||||
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
||||
) -> Proxy<wl_keyboard::WlKeyboard> {
|
||||
) -> wl_keyboard::WlKeyboard {
|
||||
// { variables to be captured by the closures
|
||||
let target = Arc::new(Mutex::new(None));
|
||||
let my_sink = sink.clone();
|
||||
|
@ -30,18 +26,12 @@ pub fn init_keyboard(
|
|||
move |evt: KbEvent, _| match evt {
|
||||
KbEvent::Enter { surface, .. } => {
|
||||
let wid = make_wid(&surface);
|
||||
my_sink
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send_event(WindowEvent::Focused(true), wid);
|
||||
my_sink.send((WindowEvent::Focused(true), wid)).unwrap();
|
||||
*target.lock().unwrap() = Some(wid);
|
||||
}
|
||||
KbEvent::Leave { surface, .. } => {
|
||||
let wid = make_wid(&surface);
|
||||
my_sink
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send_event(WindowEvent::Focused(false), wid);
|
||||
my_sink.send((WindowEvent::Focused(false), wid)).unwrap();
|
||||
*target.lock().unwrap() = None;
|
||||
}
|
||||
KbEvent::Key {
|
||||
|
@ -55,12 +45,12 @@ pub fn init_keyboard(
|
|||
let state = match state {
|
||||
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
|
||||
wl_keyboard::KeyState::Released => ElementState::Released,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let vkcode = key_to_vkey(rawkey, keysym);
|
||||
let mut guard = my_sink.lock().unwrap();
|
||||
guard.send_event(
|
||||
WindowEvent::KeyboardInput {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
my_sink.send(
|
||||
(WindowEvent::KeyboardInput {
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
input: KeyboardInput {
|
||||
state: state,
|
||||
scancode: rawkey,
|
||||
|
@ -68,15 +58,15 @@ pub fn init_keyboard(
|
|||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
},
|
||||
},
|
||||
wid,
|
||||
);
|
||||
wid)
|
||||
).unwrap();
|
||||
// send char event only on key press, not release
|
||||
if let ElementState::Released = state {
|
||||
return;
|
||||
}
|
||||
if let Some(txt) = utf8 {
|
||||
for chr in txt.chars() {
|
||||
guard.send_event(WindowEvent::ReceivedCharacter(chr), wid);
|
||||
my_sink.send((WindowEvent::ReceivedCharacter(chr), wid)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,16 +74,15 @@ pub fn init_keyboard(
|
|||
KbEvent::RepeatInfo { .. } => { /* Handled by smithay client toolkit */ }
|
||||
KbEvent::Modifiers { modifiers: event_modifiers } => {
|
||||
*modifiers_tracker.lock().unwrap() = event_modifiers.into()
|
||||
}
|
||||
},
|
||||
},
|
||||
move |repeat_event: KeyRepeatEvent, _| {
|
||||
if let Some(wid) = *repeat_target.lock().unwrap() {
|
||||
let state = ElementState::Pressed;
|
||||
let vkcode = key_to_vkey(repeat_event.rawkey, repeat_event.keysym);
|
||||
let mut guard = repeat_sink.lock().unwrap();
|
||||
guard.send_event(
|
||||
repeat_sink.send((
|
||||
WindowEvent::KeyboardInput {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
input: KeyboardInput {
|
||||
state: state,
|
||||
scancode: repeat_event.rawkey,
|
||||
|
@ -101,14 +90,13 @@ pub fn init_keyboard(
|
|||
modifiers: my_modifiers.lock().unwrap().clone(),
|
||||
},
|
||||
},
|
||||
wid,
|
||||
);
|
||||
wid)
|
||||
).unwrap();
|
||||
if let Some(txt) = repeat_event.utf8 {
|
||||
for chr in txt.chars() {
|
||||
guard.send_event(WindowEvent::ReceivedCharacter(chr), wid);
|
||||
repeat_sink.send((WindowEvent::ReceivedCharacter(chr), wid)).unwrap();
|
||||
}
|
||||
}
|
||||
event_loop_proxy.wakeup().unwrap();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -128,21 +116,15 @@ pub fn init_keyboard(
|
|||
let my_sink = sink;
|
||||
// }
|
||||
seat.get_keyboard(|keyboard| {
|
||||
keyboard.implement(move |evt, _| match evt {
|
||||
keyboard.implement_closure(move |evt, _| match evt {
|
||||
wl_keyboard::Event::Enter { surface, .. } => {
|
||||
let wid = make_wid(&surface);
|
||||
my_sink
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send_event(WindowEvent::Focused(true), wid);
|
||||
my_sink.send((WindowEvent::Focused(true), wid)).unwrap();
|
||||
target = Some(wid);
|
||||
}
|
||||
wl_keyboard::Event::Leave { surface, .. } => {
|
||||
let wid = make_wid(&surface);
|
||||
my_sink
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send_event(WindowEvent::Focused(false), wid);
|
||||
my_sink.send((WindowEvent::Focused(false), wid)).unwrap();
|
||||
target = None;
|
||||
}
|
||||
wl_keyboard::Event::Key { key, state, .. } => {
|
||||
|
@ -150,10 +132,11 @@ pub fn init_keyboard(
|
|||
let state = match state {
|
||||
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
|
||||
wl_keyboard::KeyState::Released => ElementState::Released,
|
||||
_ => unreachable!()
|
||||
};
|
||||
my_sink.lock().unwrap().send_event(
|
||||
my_sink.send((
|
||||
WindowEvent::KeyboardInput {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
input: KeyboardInput {
|
||||
state: state,
|
||||
scancode: key,
|
||||
|
@ -162,7 +145,7 @@ pub fn init_keyboard(
|
|||
},
|
||||
},
|
||||
wid,
|
||||
);
|
||||
)).unwrap();
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
target_os = "netbsd", target_os = "openbsd"))]
|
||||
|
||||
pub use self::window::Window;
|
||||
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopSink, MonitorHandle};
|
||||
pub use self::event_loop::{EventLoop, EventLoopWindowTarget, EventLoopProxy, WindowEventsSink, MonitorHandle};
|
||||
|
||||
use sctk::reexports::client::protocol::wl_surface;
|
||||
use sctk::reexports::client::Proxy;
|
||||
|
||||
mod event_loop;
|
||||
mod pointer;
|
||||
|
@ -32,6 +31,6 @@ impl WindowId {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn make_wid(s: &Proxy<wl_surface::WlSurface>) -> WindowId {
|
||||
WindowId(s.c_ptr() as usize)
|
||||
fn make_wid(s: &wl_surface::WlSurface) -> WindowId {
|
||||
WindowId(s.as_ref().c_ptr() as usize)
|
||||
}
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use {ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent};
|
||||
use events::ModifiersState;
|
||||
use event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent, ModifiersState};
|
||||
|
||||
use super::DeviceId;
|
||||
use super::event_loop::EventLoopSink;
|
||||
use super::event_loop::WindowEventsSink;
|
||||
use super::window::WindowStore;
|
||||
|
||||
use sctk::reexports::client::Proxy;
|
||||
use sctk::reexports::client::protocol::wl_pointer::{self, Event as PtrEvent, WlPointer};
|
||||
use sctk::reexports::client::protocol::wl_seat;
|
||||
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
|
||||
|
||||
pub fn implement_pointer(
|
||||
seat: &Proxy<wl_seat::WlSeat>,
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
seat: &wl_seat::WlSeat,
|
||||
sink: Arc<Mutex<WindowEventsSink>>,
|
||||
store: Arc<Mutex<WindowStore>>,
|
||||
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
||||
) -> Proxy<WlPointer> {
|
||||
) -> WlPointer {
|
||||
let mut mouse_focus = None;
|
||||
let mut axis_buffer = None;
|
||||
let mut axis_discrete_buffer = None;
|
||||
let mut axis_state = TouchPhase::Ended;
|
||||
|
||||
seat.get_pointer(|pointer| {
|
||||
pointer.implement(move |evt, pointer| {
|
||||
pointer.implement_closure(move |evt, pointer| {
|
||||
let mut sink = sink.lock().unwrap();
|
||||
let store = store.lock().unwrap();
|
||||
match evt {
|
||||
|
@ -39,13 +36,13 @@ pub fn implement_pointer(
|
|||
mouse_focus = Some(wid);
|
||||
sink.send_event(
|
||||
WindowEvent::CursorEntered {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
},
|
||||
wid,
|
||||
);
|
||||
sink.send_event(
|
||||
WindowEvent::CursorMoved {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
position: (surface_x, surface_y).into(),
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
},
|
||||
|
@ -59,7 +56,7 @@ pub fn implement_pointer(
|
|||
if let Some(wid) = wid {
|
||||
sink.send_event(
|
||||
WindowEvent::CursorLeft {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
},
|
||||
wid,
|
||||
);
|
||||
|
@ -73,7 +70,7 @@ pub fn implement_pointer(
|
|||
if let Some(wid) = mouse_focus {
|
||||
sink.send_event(
|
||||
WindowEvent::CursorMoved {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
position: (surface_x, surface_y).into(),
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
},
|
||||
|
@ -86,6 +83,7 @@ pub fn implement_pointer(
|
|||
let state = match state {
|
||||
wl_pointer::ButtonState::Pressed => ElementState::Pressed,
|
||||
wl_pointer::ButtonState::Released => ElementState::Released,
|
||||
_ => unreachable!()
|
||||
};
|
||||
let button = match button {
|
||||
0x110 => MouseButton::Left,
|
||||
|
@ -96,7 +94,7 @@ pub fn implement_pointer(
|
|||
};
|
||||
sink.send_event(
|
||||
WindowEvent::MouseInput {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
state: state,
|
||||
button: button,
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
|
@ -107,17 +105,18 @@ pub fn implement_pointer(
|
|||
}
|
||||
PtrEvent::Axis { axis, value, .. } => {
|
||||
if let Some(wid) = mouse_focus {
|
||||
if pointer.version() < 5 {
|
||||
if pointer.as_ref().version() < 5 {
|
||||
let (mut x, mut y) = (0.0, 0.0);
|
||||
// old seat compatibility
|
||||
match axis {
|
||||
// wayland vertical sign convention is the inverse of winit
|
||||
wl_pointer::Axis::VerticalScroll => y -= value as f32,
|
||||
wl_pointer::Axis::HorizontalScroll => x += value as f32,
|
||||
_ => unreachable!()
|
||||
}
|
||||
sink.send_event(
|
||||
WindowEvent::MouseWheel {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()),
|
||||
phase: TouchPhase::Moved,
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
|
@ -130,6 +129,7 @@ pub fn implement_pointer(
|
|||
// wayland vertical sign convention is the inverse of winit
|
||||
wl_pointer::Axis::VerticalScroll => y -= value as f32,
|
||||
wl_pointer::Axis::HorizontalScroll => x += value as f32,
|
||||
_ => unreachable!()
|
||||
}
|
||||
axis_buffer = Some((x, y));
|
||||
axis_state = match axis_state {
|
||||
|
@ -146,7 +146,7 @@ pub fn implement_pointer(
|
|||
if let Some((x, y)) = axis_discrete_buffer {
|
||||
sink.send_event(
|
||||
WindowEvent::MouseWheel {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
delta: MouseScrollDelta::LineDelta(x as f32, y as f32),
|
||||
phase: axis_state,
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
|
@ -156,7 +156,7 @@ pub fn implement_pointer(
|
|||
} else if let Some((x, y)) = axis_buffer {
|
||||
sink.send_event(
|
||||
WindowEvent::MouseWheel {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()),
|
||||
phase: axis_state,
|
||||
modifiers: modifiers_tracker.lock().unwrap().clone(),
|
||||
|
@ -176,13 +176,15 @@ pub fn implement_pointer(
|
|||
// wayland vertical sign convention is the inverse of winit
|
||||
wl_pointer::Axis::VerticalScroll => y -= discrete,
|
||||
wl_pointer::Axis::HorizontalScroll => x += discrete,
|
||||
_ => unreachable!()
|
||||
}
|
||||
axis_discrete_buffer = Some((x, y));
|
||||
axis_state = match axis_state {
|
||||
TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved,
|
||||
_ => TouchPhase::Started,
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}, ())
|
||||
}).unwrap()
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use {TouchPhase, WindowEvent};
|
||||
use event::{TouchPhase, WindowEvent};
|
||||
|
||||
use super::{DeviceId, WindowId};
|
||||
use super::event_loop::EventLoopSink;
|
||||
use super::event_loop::WindowEventsSink;
|
||||
use super::window::WindowStore;
|
||||
|
||||
use sctk::reexports::client::Proxy;
|
||||
use sctk::reexports::client::protocol::wl_touch::{Event as TouchEvent, WlTouch};
|
||||
use sctk::reexports::client::protocol::wl_seat;
|
||||
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;
|
||||
|
||||
struct TouchPoint {
|
||||
wid: WindowId,
|
||||
|
@ -18,13 +16,13 @@ struct TouchPoint {
|
|||
}
|
||||
|
||||
pub(crate) fn implement_touch(
|
||||
seat: &Proxy<wl_seat::WlSeat>,
|
||||
sink: Arc<Mutex<EventLoopSink>>,
|
||||
seat: &wl_seat::WlSeat,
|
||||
sink: Arc<Mutex<WindowEventsSink>>,
|
||||
store: Arc<Mutex<WindowStore>>,
|
||||
) -> Proxy<WlTouch> {
|
||||
) -> WlTouch {
|
||||
let mut pending_ids = Vec::new();
|
||||
seat.get_touch(|touch| {
|
||||
touch.implement(move |evt, _| {
|
||||
touch.implement_closure(move |evt, _| {
|
||||
let mut sink = sink.lock().unwrap();
|
||||
let store = store.lock().unwrap();
|
||||
match evt {
|
||||
|
@ -34,8 +32,8 @@ pub(crate) fn implement_touch(
|
|||
let wid = store.find_wid(&surface);
|
||||
if let Some(wid) = wid {
|
||||
sink.send_event(
|
||||
WindowEvent::Touch(::Touch {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
WindowEvent::Touch(::event::Touch {
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
phase: TouchPhase::Started,
|
||||
location: (x, y).into(),
|
||||
id: id as u64,
|
||||
|
@ -54,8 +52,8 @@ pub(crate) fn implement_touch(
|
|||
if let Some(idx) = idx {
|
||||
let pt = pending_ids.remove(idx);
|
||||
sink.send_event(
|
||||
WindowEvent::Touch(::Touch {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
WindowEvent::Touch(::event::Touch {
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
phase: TouchPhase::Ended,
|
||||
location: pt.location.into(),
|
||||
id: id as u64,
|
||||
|
@ -69,8 +67,8 @@ pub(crate) fn implement_touch(
|
|||
if let Some(pt) = pt {
|
||||
pt.location = (x, y);
|
||||
sink.send_event(
|
||||
WindowEvent::Touch(::Touch {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
WindowEvent::Touch(::event::Touch {
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
phase: TouchPhase::Moved,
|
||||
location: (x, y).into(),
|
||||
id: id as u64,
|
||||
|
@ -82,8 +80,8 @@ pub(crate) fn implement_touch(
|
|||
TouchEvent::Frame => (),
|
||||
TouchEvent::Cancel => for pt in pending_ids.drain(..) {
|
||||
sink.send_event(
|
||||
WindowEvent::Touch(::Touch {
|
||||
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
|
||||
WindowEvent::Touch(::event::Touch {
|
||||
device_id: ::event::DeviceId(::platform_impl::DeviceId::Wayland(DeviceId)),
|
||||
phase: TouchPhase::Cancelled,
|
||||
location: pt.location.into(),
|
||||
id: pt.id as u64,
|
||||
|
@ -91,6 +89,7 @@ pub(crate) fn implement_touch(
|
|||
pt.wid,
|
||||
);
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}, ())
|
||||
}).unwrap()
|
||||
|
|
|
@ -1,38 +1,33 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
|
||||
use {CreationError, MouseCursor, WindowAttributes};
|
||||
use dpi::{LogicalPosition, LogicalSize};
|
||||
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
|
||||
use platform_impl::MonitorHandle as PlatformMonitorHandle;
|
||||
use window::MonitorHandle as RootMonitorHandle;
|
||||
=======
|
||||
use platform::{MonitorId as PlatformMonitorId, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
||||
use window::MonitorId as RootMonitorId;
|
||||
>>>>>>> master:src/platform/linux/wayland/window.rs
|
||||
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use window::{CreationError, WindowAttributes, MouseCursor};
|
||||
|
||||
use sctk::surface::{get_dpi_factor, get_outputs};
|
||||
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow, Theme};
|
||||
use sctk::reexports::client::{Display, Proxy};
|
||||
use sctk::reexports::client::Display;
|
||||
use sctk::reexports::client::protocol::{wl_seat, wl_surface};
|
||||
use sctk::reexports::client::protocol::wl_surface::RequestsTrait as SurfaceRequests;
|
||||
use sctk::output::OutputMgr;
|
||||
|
||||
use super::{make_wid, EventLoop, MonitorHandle, WindowId};
|
||||
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
||||
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
|
||||
|
||||
pub struct Window {
|
||||
surface: Proxy<wl_surface::WlSurface>,
|
||||
surface: wl_surface::WlSurface,
|
||||
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
||||
outputs: OutputMgr, // Access to info for all monitors
|
||||
size: Arc<Mutex<(u32, u32)>>,
|
||||
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
||||
display: Arc<Display>,
|
||||
need_frame_refresh: Arc<Mutex<bool>>,
|
||||
need_refresh: Arc<Mutex<bool>>
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(evlp: &EventLoop, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
|
||||
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
|
||||
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
|
||||
// Create the window
|
||||
let size = Arc::new(Mutex::new((width, height)));
|
||||
|
@ -53,9 +48,9 @@ impl Window {
|
|||
WEvent::Configure { new_size, .. } => {
|
||||
let mut store = window_store.lock().unwrap();
|
||||
for window in &mut store.windows {
|
||||
if window.surface.equals(&my_surface) {
|
||||
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
||||
window.newsize = new_size;
|
||||
window.need_refresh = true;
|
||||
*(window.need_refresh.lock().unwrap()) = true;
|
||||
*(window.need_frame_refresh.lock().unwrap()) = true;
|
||||
return;
|
||||
}
|
||||
|
@ -64,7 +59,7 @@ impl Window {
|
|||
WEvent::Refresh => {
|
||||
let store = window_store.lock().unwrap();
|
||||
for window in &store.windows {
|
||||
if window.surface.equals(&my_surface) {
|
||||
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
||||
*(window.need_frame_refresh.lock().unwrap()) = true;
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +68,7 @@ impl Window {
|
|||
WEvent::Close => {
|
||||
let mut store = window_store.lock().unwrap();
|
||||
for window in &mut store.windows {
|
||||
if window.surface.equals(&my_surface) {
|
||||
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
||||
window.closed = true;
|
||||
return;
|
||||
}
|
||||
|
@ -105,6 +100,9 @@ impl Window {
|
|||
// set decorations
|
||||
frame.set_decorate(attributes.decorations);
|
||||
|
||||
// set title
|
||||
frame.set_title(attributes.title);
|
||||
|
||||
// min-max dimensions
|
||||
frame.set_min_size(attributes.min_dimensions.map(Into::into));
|
||||
frame.set_max_size(attributes.max_dimensions.map(Into::into));
|
||||
|
@ -112,12 +110,13 @@ impl Window {
|
|||
let kill_switch = Arc::new(Mutex::new(false));
|
||||
let need_frame_refresh = Arc::new(Mutex::new(true));
|
||||
let frame = Arc::new(Mutex::new(frame));
|
||||
let need_refresh = Arc::new(Mutex::new(true));
|
||||
|
||||
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
||||
closed: false,
|
||||
newsize: None,
|
||||
size: size.clone(),
|
||||
need_refresh: false,
|
||||
need_refresh: need_refresh.clone(),
|
||||
need_frame_refresh: need_frame_refresh.clone(),
|
||||
surface: surface.clone(),
|
||||
kill_switch: kill_switch.clone(),
|
||||
|
@ -134,7 +133,8 @@ impl Window {
|
|||
outputs: evlp.env.outputs.clone(),
|
||||
size: size,
|
||||
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
||||
need_frame_refresh: need_frame_refresh,
|
||||
need_frame_refresh,
|
||||
need_refresh,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -178,6 +178,10 @@ impl Window {
|
|||
Some(self.size.lock().unwrap().clone().into())
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
*self.need_refresh.lock().unwrap() = true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
let (w, h) = self.size.lock().unwrap().clone();
|
||||
|
@ -269,24 +273,16 @@ impl Window {
|
|||
&*self.display
|
||||
}
|
||||
|
||||
pub fn get_surface(&self) -> &Proxy<wl_surface::WlSurface> {
|
||||
pub fn get_surface(&self) -> &wl_surface::WlSurface {
|
||||
&self.surface
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
|
||||
pub fn get_current_monitor(&self) -> MonitorHandle {
|
||||
// we don't know how much each monitor sees us so...
|
||||
// just return the most recent one ?
|
||||
let guard = self.monitors.lock().unwrap();
|
||||
guard.monitors.last().unwrap().clone()
|
||||
=======
|
||||
pub fn get_current_monitor(&self) -> MonitorId {
|
||||
let output = get_outputs(&self.surface).last().unwrap().clone();
|
||||
MonitorId {
|
||||
MonitorHandle {
|
||||
proxy: output,
|
||||
mgr: self.outputs.clone(),
|
||||
}
|
||||
>>>>>>> master:src/platform/linux/wayland/window.rs
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
|
@ -310,10 +306,10 @@ impl Drop for Window {
|
|||
*/
|
||||
|
||||
struct InternalWindow {
|
||||
surface: Proxy<wl_surface::WlSurface>,
|
||||
surface: wl_surface::WlSurface,
|
||||
newsize: Option<(u32, u32)>,
|
||||
size: Arc<Mutex<(u32, u32)>>,
|
||||
need_refresh: bool,
|
||||
need_refresh: Arc<Mutex<bool>>,
|
||||
need_frame_refresh: Arc<Mutex<bool>>,
|
||||
closed: bool,
|
||||
kill_switch: Arc<Mutex<bool>>,
|
||||
|
@ -333,9 +329,9 @@ impl WindowStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_wid(&self, surface: &Proxy<wl_surface::WlSurface>) -> Option<WindowId> {
|
||||
pub fn find_wid(&self, surface: &wl_surface::WlSurface) -> Option<WindowId> {
|
||||
for window in &self.windows {
|
||||
if surface.equals(&window.surface) {
|
||||
if surface.as_ref().equals(&window.surface.as_ref()) {
|
||||
return Some(make_wid(surface));
|
||||
}
|
||||
}
|
||||
|
@ -357,7 +353,7 @@ impl WindowStore {
|
|||
pruned
|
||||
}
|
||||
|
||||
pub fn new_seat(&self, seat: &Proxy<wl_seat::WlSeat>) {
|
||||
pub fn new_seat(&self, seat: &wl_seat::WlSeat) {
|
||||
for window in &self.windows {
|
||||
if let Some(w) = window.frame.upgrade() {
|
||||
w.lock().unwrap().new_seat(seat);
|
||||
|
@ -365,9 +361,9 @@ impl WindowStore {
|
|||
}
|
||||
}
|
||||
|
||||
fn dpi_change(&mut self, surface: &Proxy<wl_surface::WlSurface>, new: i32) {
|
||||
fn dpi_change(&mut self, surface: &wl_surface::WlSurface, new: i32) {
|
||||
for window in &mut self.windows {
|
||||
if surface.equals(&window.surface) {
|
||||
if surface.as_ref().equals(&window.surface.as_ref()) {
|
||||
window.new_dpi = Some(new);
|
||||
}
|
||||
}
|
||||
|
@ -384,7 +380,7 @@ impl WindowStore {
|
|||
window.newsize.take(),
|
||||
&mut *(window.size.lock().unwrap()),
|
||||
window.new_dpi,
|
||||
window.need_refresh,
|
||||
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
|
||||
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
||||
window.closed,
|
||||
make_wid(&window.surface),
|
||||
|
@ -393,59 +389,9 @@ impl WindowStore {
|
|||
if let Some(dpi) = window.new_dpi.take() {
|
||||
window.current_dpi = dpi;
|
||||
}
|
||||
window.need_refresh = false;
|
||||
// avoid re-spamming the event
|
||||
window.closed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD:src/platform_impl/linux/wayland/window.rs
|
||||
|
||||
/*
|
||||
* Monitor list with some covenience method to compute DPI
|
||||
*/
|
||||
|
||||
struct MonitorList {
|
||||
monitors: Vec<MonitorHandle>
|
||||
}
|
||||
|
||||
impl MonitorList {
|
||||
fn new() -> MonitorList {
|
||||
MonitorList {
|
||||
monitors: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_hidpi_factor(&self) -> i32 {
|
||||
let mut factor = 1;
|
||||
for monitor_id in &self.monitors {
|
||||
let monitor_dpi = monitor_id.get_hidpi_factor();
|
||||
if monitor_dpi > factor { factor = monitor_dpi; }
|
||||
}
|
||||
factor
|
||||
}
|
||||
|
||||
fn add_output(&mut self, monitor: MonitorHandle) -> Option<i32> {
|
||||
let old_dpi = self.compute_hidpi_factor();
|
||||
let monitor_dpi = monitor.get_hidpi_factor();
|
||||
self.monitors.push(monitor);
|
||||
if monitor_dpi > old_dpi {
|
||||
Some(monitor_dpi)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn del_output(&mut self, output: &Proxy<wl_output::WlOutput>) -> Option<i32> {
|
||||
let old_dpi = self.compute_hidpi_factor();
|
||||
self.monitors.retain(|m| !m.proxy.equals(output));
|
||||
let new_dpi = self.compute_hidpi_factor();
|
||||
if new_dpi != old_dpi {
|
||||
Some(new_dpi)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
=======
|
||||
>>>>>>> master:src/platform/linux/wayland/window.rs
|
||||
|
|
|
@ -601,13 +601,13 @@ impl EventLoopThreadExecutor {
|
|||
type ThreadExecFn = Box<Box<FnMut()>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy<T> {
|
||||
pub struct EventLoopProxy<T: 'static> {
|
||||
target_window: HWND,
|
||||
event_send: Sender<T>,
|
||||
}
|
||||
unsafe impl<T: Send> Send for EventLoopProxy<T> {}
|
||||
unsafe impl<T: Send + 'static> Send for EventLoopProxy<T> {}
|
||||
|
||||
impl<T> EventLoopProxy<T> {
|
||||
impl<T: 'static> EventLoopProxy<T> {
|
||||
pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
|
||||
unsafe {
|
||||
if winuser::PostMessageW(self.target_window, *USER_EVENT_MSG_ID, 0, 0) != 0 {
|
||||
|
|
|
@ -4,7 +4,7 @@ fn needs_send<T:Send>() {}
|
|||
|
||||
#[test]
|
||||
fn event_loop_proxy_send() {
|
||||
fn is_send<T: Send>() {
|
||||
fn is_send<T: 'static + Send>() {
|
||||
// ensures that `winit::EventLoopProxy` implements `Send`
|
||||
needs_send::<winit::event_loop::EventLoopProxy<T>>();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue