From 50008dff3d0bac64d73f3149712dc2cca00a7327 Mon Sep 17 00:00:00 2001 From: trimental Date: Mon, 15 Oct 2018 07:15:43 +0800 Subject: [PATCH] Upgrade to smithay-client-toolkit 0.4 (#671) * Upgrade to smithay-client-toolkit 0.4 * Fix PR points --- CHANGELOG.md | 3 + Cargo.toml | 4 +- src/platform/linux/wayland/event_loop.rs | 63 ++--- src/platform/linux/wayland/keyboard.rs | 99 ++++---- src/platform/linux/wayland/pointer.rs | 308 ++++++++++++----------- src/platform/linux/wayland/touch.rs | 128 +++++----- src/platform/linux/wayland/window.rs | 20 +- 7 files changed, 326 insertions(+), 299 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da072ed5..fbd20808 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Unreleased +- On Wayland, titles will now be displayed in the window header decoration +- On Wayland, key repetition is now ended when keyboard loses focus +- On Wayland, windows will now use more stylish and modern client side decorations. - On Wayland, windows will use server-side decorations when available. - Added support for F16-F24 keys. - Fixed graphical glitches when resizing on Wayland. diff --git a/Cargo.toml b/Cargo.toml index 27dcd381..e27c85e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,8 +54,8 @@ features = [ ] [target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies] -wayland-client = { version = "0.20.10", features = [ "dlopen", "egl", "cursor"] } -smithay-client-toolkit = "0.3.0" +wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] } +smithay-client-toolkit = "0.4" x11-dl = "2.18.3" parking_lot = "0.6" percent-encoding = "1.0" diff --git a/src/platform/linux/wayland/event_loop.rs b/src/platform/linux/wayland/event_loop.rs index 0639044e..cdfc9544 100644 --- a/src/platform/linux/wayland/event_loop.rs +++ b/src/platform/linux/wayland/event_loop.rs @@ -10,7 +10,6 @@ use super::window::WindowStore; use super::WindowId; use sctk::output::OutputMgr; -use sctk::reexports::client::commons::Implementation; use sctk::reexports::client::protocol::{ wl_keyboard, wl_output, wl_pointer, wl_registry, wl_seat, wl_touch, }; @@ -93,7 +92,7 @@ impl EventsLoopProxy { // Update the `EventsLoop`'s `pending_wakeup` flag. wakeup.store(true, Ordering::Relaxed); // Cause the `EventsLoop` to break from `dispatch` if it is currently blocked. - let _ = display.sync(); + let _ = display.sync(|callback| callback.implement(|_, _| {}, ())); display.flush().map_err(|_| EventsLoopClosed)?; Ok(()) } @@ -112,17 +111,21 @@ impl EventsLoop { let store = Arc::new(Mutex::new(WindowStore::new())); let seats = Arc::new(Mutex::new(Vec::new())); - let env = Environment::from_registry_with_cb( - display.get_registry().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), + }, + }; + + let env = Environment::from_display_with_cb( + &display, &mut event_queue, - SeatManager { - sink: sink.clone(), - store: store.clone(), - seats: seats.clone(), - events_loop_proxy: EventsLoopProxy { - display: Arc::downgrade(&display), - pending_wakeup: Arc::downgrade(&pending_wakeup), - }, + move |event, registry| { + seat_manager.receive(event, registry) }, ).unwrap(); @@ -280,7 +283,7 @@ struct SeatManager { events_loop_proxy: EventsLoopProxy, } -impl Implementation, GlobalEvent> for SeatManager { +impl SeatManager { fn receive(&mut self, evt: GlobalEvent, registry: Proxy) { use self::wl_registry::RequestsTrait as RegistryRequests; use self::wl_seat::RequestsTrait as SeatRequests; @@ -292,17 +295,22 @@ impl Implementation, GlobalEvent> for SeatManager } 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(), + }; let seat = registry - .bind::(min(version, 5), id) - .unwrap() - .implement(SeatData { - sink: self.sink.clone(), - store: self.store.clone(), - pointer: None, - keyboard: None, - touch: None, - events_loop_proxy: self.events_loop_proxy.clone(), - }); + .bind(min(version, 5), id, move |seat| { + seat.implement(move |event, seat| { + seat_data.receive(event, seat) + }, ()) + }) + .unwrap(); self.store.lock().unwrap().new_seat(&seat); self.seats.lock().unwrap().push((id, seat)); } @@ -329,16 +337,15 @@ struct SeatData { events_loop_proxy: EventsLoopProxy, } -impl Implementation, wl_seat::Event> for SeatData { +impl SeatData { fn receive(&mut self, evt: wl_seat::Event, seat: Proxy) { - use self::wl_seat::RequestsTrait as SeatRequests; match evt { wl_seat::Event::Name { .. } => (), wl_seat::Event::Capabilities { capabilities } => { // create pointer if applicable if capabilities.contains(wl_seat::Capability::Pointer) && self.pointer.is_none() { self.pointer = Some(super::pointer::implement_pointer( - seat.get_pointer().unwrap(), + &seat, self.sink.clone(), self.store.clone(), )) @@ -355,7 +362,7 @@ impl Implementation, wl_seat::Event> for SeatData { // create keyboard if applicable if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() { self.keyboard = Some(super::keyboard::init_keyboard( - seat.get_keyboard().unwrap(), + &seat, self.sink.clone(), self.events_loop_proxy.clone(), )) @@ -372,7 +379,7 @@ impl Implementation, wl_seat::Event> for SeatData { // create touch if applicable if capabilities.contains(wl_seat::Capability::Touch) && self.touch.is_none() { self.touch = Some(super::touch::implement_touch( - seat.get_touch().unwrap(), + &seat, self.sink.clone(), self.store.clone(), )) diff --git a/src/platform/linux/wayland/keyboard.rs b/src/platform/linux/wayland/keyboard.rs index e1001178..c7264895 100644 --- a/src/platform/linux/wayland/keyboard.rs +++ b/src/platform/linux/wayland/keyboard.rs @@ -5,11 +5,14 @@ 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::{NewProxy, Proxy}; +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}; pub fn init_keyboard( - keyboard: NewProxy, + seat: &Proxy, sink: Arc>, events_loop_proxy: EventsLoopProxy, ) -> Proxy { @@ -18,9 +21,11 @@ pub fn init_keyboard( let my_sink = sink.clone(); let repeat_sink = sink.clone(); let repeat_target = target.clone(); + let modifiers = Arc::new(Mutex::new(ModifiersState::default())); + let my_modifiers = modifiers.clone(); // } let ret = map_keyboard_auto_with_repeat( - keyboard, + seat, KeyRepeatKind::System, move |evt: KbEvent, _| match evt { KbEvent::Enter { surface, .. } => { @@ -40,7 +45,6 @@ pub fn init_keyboard( *target.lock().unwrap() = None; } KbEvent::Key { - modifiers, rawkey, keysym, state, @@ -61,7 +65,7 @@ pub fn init_keyboard( state: state, scancode: rawkey, virtual_keycode: vkcode, - modifiers: modifiers.into(), + modifiers: modifiers.lock().unwrap().clone(), }, }, wid, @@ -78,6 +82,9 @@ pub fn init_keyboard( } } KbEvent::RepeatInfo { .. } => { /* Handled by smithay client toolkit */ } + KbEvent::Modifiers { modifiers: event_modifiers } => { + *modifiers.lock().unwrap() = event_modifiers.into() + } }, move |repeat_event: KeyRepeatEvent, _| { if let Some(wid) = *repeat_target.lock().unwrap() { @@ -91,7 +98,7 @@ pub fn init_keyboard( state: state, scancode: repeat_event.rawkey, virtual_keycode: vkcode, - modifiers: repeat_event.modifiers.into(), + modifiers: my_modifiers.lock().unwrap().clone(), }, }, wid, @@ -108,7 +115,7 @@ pub fn init_keyboard( match ret { Ok(keyboard) => keyboard, - Err((_, keyboard)) => { + Err(_) => { // This is a fallback impl if libxkbcommon was not available // This case should probably never happen, as most wayland // compositors _need_ libxkbcommon anyway... @@ -120,45 +127,47 @@ pub fn init_keyboard( let mut target = None; let my_sink = sink; // } - keyboard.implement(move |evt, _| match evt { - wl_keyboard::Event::Enter { surface, .. } => { - let wid = make_wid(&surface); - my_sink - .lock() - .unwrap() - .send_event(WindowEvent::Focused(true), wid); - target = Some(wid); - } - wl_keyboard::Event::Leave { surface, .. } => { - let wid = make_wid(&surface); - my_sink - .lock() - .unwrap() - .send_event(WindowEvent::Focused(false), wid); - target = None; - } - wl_keyboard::Event::Key { key, state, .. } => { - if let Some(wid) = target { - let state = match state { - wl_keyboard::KeyState::Pressed => ElementState::Pressed, - wl_keyboard::KeyState::Released => ElementState::Released, - }; - my_sink.lock().unwrap().send_event( - WindowEvent::KeyboardInput { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - input: KeyboardInput { - state: state, - scancode: key, - virtual_keycode: None, - modifiers: ModifiersState::default(), - }, - }, - wid, - ); + seat.get_keyboard(|keyboard| { + keyboard.implement(move |evt, _| match evt { + wl_keyboard::Event::Enter { surface, .. } => { + let wid = make_wid(&surface); + my_sink + .lock() + .unwrap() + .send_event(WindowEvent::Focused(true), wid); + target = Some(wid); } - } - _ => (), - }) + wl_keyboard::Event::Leave { surface, .. } => { + let wid = make_wid(&surface); + my_sink + .lock() + .unwrap() + .send_event(WindowEvent::Focused(false), wid); + target = None; + } + wl_keyboard::Event::Key { key, state, .. } => { + if let Some(wid) = target { + let state = match state { + wl_keyboard::KeyState::Pressed => ElementState::Pressed, + wl_keyboard::KeyState::Released => ElementState::Released, + }; + my_sink.lock().unwrap().send_event( + WindowEvent::KeyboardInput { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + input: KeyboardInput { + state: state, + scancode: key, + virtual_keycode: None, + modifiers: ModifiersState::default(), + }, + }, + wid, + ); + } + } + _ => (), + }, ()) + }).unwrap() } } } diff --git a/src/platform/linux/wayland/pointer.rs b/src/platform/linux/wayland/pointer.rs index 51b02f89..7f809913 100644 --- a/src/platform/linux/wayland/pointer.rs +++ b/src/platform/linux/wayland/pointer.rs @@ -7,11 +7,13 @@ use super::DeviceId; use super::event_loop::EventsLoopSink; use super::window::WindowStore; -use sctk::reexports::client::{NewProxy, Proxy}; +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( - pointer: NewProxy, + seat: &Proxy, sink: Arc>, store: Arc>, ) -> Proxy { @@ -20,146 +22,30 @@ pub fn implement_pointer( let mut axis_discrete_buffer = None; let mut axis_state = TouchPhase::Ended; - pointer.implement(move |evt, pointer: Proxy<_>| { - let mut sink = sink.lock().unwrap(); - let store = store.lock().unwrap(); - match evt { - PtrEvent::Enter { - surface, - surface_x, - surface_y, - .. - } => { - let wid = store.find_wid(&surface); - if let Some(wid) = wid { - mouse_focus = Some(wid); - sink.send_event( - WindowEvent::CursorEntered { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - }, - wid, - ); - sink.send_event( - WindowEvent::CursorMoved { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - position: (surface_x, surface_y).into(), - // TODO: replace dummy value with actual modifier state - modifiers: ModifiersState::default(), - }, - wid, - ); - } - } - PtrEvent::Leave { surface, .. } => { - mouse_focus = None; - let wid = store.find_wid(&surface); - if let Some(wid) = wid { - sink.send_event( - WindowEvent::CursorLeft { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - }, - wid, - ); - } - } - PtrEvent::Motion { - surface_x, - surface_y, - .. - } => { - if let Some(wid) = mouse_focus { - sink.send_event( - WindowEvent::CursorMoved { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - position: (surface_x, surface_y).into(), - // TODO: replace dummy value with actual modifier state - modifiers: ModifiersState::default(), - }, - wid, - ); - } - } - PtrEvent::Button { button, state, .. } => { - if let Some(wid) = mouse_focus { - let state = match state { - wl_pointer::ButtonState::Pressed => ElementState::Pressed, - wl_pointer::ButtonState::Released => ElementState::Released, - }; - let button = match button { - 0x110 => MouseButton::Left, - 0x111 => MouseButton::Right, - 0x112 => MouseButton::Middle, - // TODO figure out the translation ? - _ => return, - }; - sink.send_event( - WindowEvent::MouseInput { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - state: state, - button: button, - // TODO: replace dummy value with actual modifier state - modifiers: ModifiersState::default(), - }, - wid, - ); - } - } - PtrEvent::Axis { axis, value, .. } => { - if let Some(wid) = mouse_focus { - if pointer.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, - } + seat.get_pointer(|pointer| { + pointer.implement(move |evt, pointer| { + let mut sink = sink.lock().unwrap(); + let store = store.lock().unwrap(); + match evt { + PtrEvent::Enter { + surface, + surface_x, + surface_y, + .. + } => { + let wid = store.find_wid(&surface); + if let Some(wid) = wid { + mouse_focus = Some(wid); sink.send_event( - WindowEvent::MouseWheel { + WindowEvent::CursorEntered { device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()), - phase: TouchPhase::Moved, - // TODO: replace dummy value with actual modifier state - modifiers: ModifiersState::default(), }, wid, ); - } else { - let (mut x, mut y) = axis_buffer.unwrap_or((0.0, 0.0)); - 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, - } - axis_buffer = Some((x, y)); - axis_state = match axis_state { - TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved, - _ => TouchPhase::Started, - } - } - } - } - PtrEvent::Frame => { - let axis_buffer = axis_buffer.take(); - let axis_discrete_buffer = axis_discrete_buffer.take(); - if let Some(wid) = mouse_focus { - if let Some((x, y)) = axis_discrete_buffer { sink.send_event( - WindowEvent::MouseWheel { + WindowEvent::CursorMoved { device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - delta: MouseScrollDelta::LineDelta(x as f32, y as f32), - phase: axis_state, - // TODO: replace dummy value with actual modifier state - modifiers: ModifiersState::default(), - }, - wid, - ); - } else if let Some((x, y)) = axis_buffer { - sink.send_event( - WindowEvent::MouseWheel { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()), - phase: axis_state, + position: (surface_x, surface_y).into(), // TODO: replace dummy value with actual modifier state modifiers: ModifiersState::default(), }, @@ -167,24 +53,142 @@ pub fn implement_pointer( ); } } - } - PtrEvent::AxisSource { .. } => (), - PtrEvent::AxisStop { .. } => { - axis_state = TouchPhase::Ended; - } - PtrEvent::AxisDiscrete { axis, discrete } => { - let (mut x, mut y) = axis_discrete_buffer.unwrap_or((0, 0)); - match axis { - // wayland vertical sign convention is the inverse of winit - wl_pointer::Axis::VerticalScroll => y -= discrete, - wl_pointer::Axis::HorizontalScroll => x += discrete, + PtrEvent::Leave { surface, .. } => { + mouse_focus = None; + let wid = store.find_wid(&surface); + if let Some(wid) = wid { + sink.send_event( + WindowEvent::CursorLeft { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + }, + wid, + ); + } } - axis_discrete_buffer = Some((x, y)); - axis_state = match axis_state { - TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved, - _ => TouchPhase::Started, + PtrEvent::Motion { + surface_x, + surface_y, + .. + } => { + if let Some(wid) = mouse_focus { + sink.send_event( + WindowEvent::CursorMoved { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + position: (surface_x, surface_y).into(), + // TODO: replace dummy value with actual modifier state + modifiers: ModifiersState::default(), + }, + wid, + ); + } + } + PtrEvent::Button { button, state, .. } => { + if let Some(wid) = mouse_focus { + let state = match state { + wl_pointer::ButtonState::Pressed => ElementState::Pressed, + wl_pointer::ButtonState::Released => ElementState::Released, + }; + let button = match button { + 0x110 => MouseButton::Left, + 0x111 => MouseButton::Right, + 0x112 => MouseButton::Middle, + // TODO figure out the translation ? + _ => return, + }; + sink.send_event( + WindowEvent::MouseInput { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + state: state, + button: button, + // TODO: replace dummy value with actual modifier state + modifiers: ModifiersState::default(), + }, + wid, + ); + } + } + PtrEvent::Axis { axis, value, .. } => { + if let Some(wid) = mouse_focus { + if pointer.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, + } + sink.send_event( + WindowEvent::MouseWheel { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()), + phase: TouchPhase::Moved, + // TODO: replace dummy value with actual modifier state + modifiers: ModifiersState::default(), + }, + wid, + ); + } else { + let (mut x, mut y) = axis_buffer.unwrap_or((0.0, 0.0)); + 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, + } + axis_buffer = Some((x, y)); + axis_state = match axis_state { + TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved, + _ => TouchPhase::Started, + } + } + } + } + PtrEvent::Frame => { + let axis_buffer = axis_buffer.take(); + let axis_discrete_buffer = axis_discrete_buffer.take(); + if let Some(wid) = mouse_focus { + if let Some((x, y)) = axis_discrete_buffer { + sink.send_event( + WindowEvent::MouseWheel { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + delta: MouseScrollDelta::LineDelta(x as f32, y as f32), + phase: axis_state, + // TODO: replace dummy value with actual modifier state + modifiers: ModifiersState::default(), + }, + wid, + ); + } else if let Some((x, y)) = axis_buffer { + sink.send_event( + WindowEvent::MouseWheel { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + delta: MouseScrollDelta::PixelDelta((x as f64, y as f64).into()), + phase: axis_state, + // TODO: replace dummy value with actual modifier state + modifiers: ModifiersState::default(), + }, + wid, + ); + } + } + } + PtrEvent::AxisSource { .. } => (), + PtrEvent::AxisStop { .. } => { + axis_state = TouchPhase::Ended; + } + PtrEvent::AxisDiscrete { axis, discrete } => { + let (mut x, mut y) = axis_discrete_buffer.unwrap_or((0, 0)); + match axis { + // wayland vertical sign convention is the inverse of winit + wl_pointer::Axis::VerticalScroll => y -= discrete, + wl_pointer::Axis::HorizontalScroll => x += discrete, + } + axis_discrete_buffer = Some((x, y)); + axis_state = match axis_state { + TouchPhase::Started | TouchPhase::Moved => TouchPhase::Moved, + _ => TouchPhase::Started, + } } } - } - }) + }, ()) + }).unwrap() } diff --git a/src/platform/linux/wayland/touch.rs b/src/platform/linux/wayland/touch.rs index 01416b9c..e9e28d61 100644 --- a/src/platform/linux/wayland/touch.rs +++ b/src/platform/linux/wayland/touch.rs @@ -6,8 +6,10 @@ use super::{DeviceId, WindowId}; use super::event_loop::EventsLoopSink; use super::window::WindowStore; -use sctk::reexports::client::{NewProxy, Proxy}; +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, @@ -16,78 +18,80 @@ struct TouchPoint { } pub(crate) fn implement_touch( - touch: NewProxy, + seat: &Proxy, sink: Arc>, store: Arc>, ) -> Proxy { let mut pending_ids = Vec::new(); - touch.implement(move |evt, _| { - let mut sink = sink.lock().unwrap(); - let store = store.lock().unwrap(); - match evt { - TouchEvent::Down { - surface, id, x, y, .. - } => { - let wid = store.find_wid(&surface); - if let Some(wid) = wid { - sink.send_event( - WindowEvent::Touch(::Touch { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - phase: TouchPhase::Started, - location: (x, y).into(), - id: id as u64, - }), - wid, - ); - pending_ids.push(TouchPoint { - wid: wid, - location: (x, y), - id: id, - }); + seat.get_touch(|touch| { + touch.implement(move |evt, _| { + let mut sink = sink.lock().unwrap(); + let store = store.lock().unwrap(); + match evt { + TouchEvent::Down { + surface, id, x, y, .. + } => { + let wid = store.find_wid(&surface); + if let Some(wid) = wid { + sink.send_event( + WindowEvent::Touch(::Touch { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + phase: TouchPhase::Started, + location: (x, y).into(), + id: id as u64, + }), + wid, + ); + pending_ids.push(TouchPoint { + wid: wid, + location: (x, y), + id: id, + }); + } } - } - TouchEvent::Up { id, .. } => { - let idx = pending_ids.iter().position(|p| p.id == id); - if let Some(idx) = idx { - let pt = pending_ids.remove(idx); + TouchEvent::Up { id, .. } => { + let idx = pending_ids.iter().position(|p| p.id == id); + if let Some(idx) = idx { + let pt = pending_ids.remove(idx); + sink.send_event( + WindowEvent::Touch(::Touch { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + phase: TouchPhase::Ended, + location: pt.location.into(), + id: id as u64, + }), + pt.wid, + ); + } + } + TouchEvent::Motion { id, x, y, .. } => { + let pt = pending_ids.iter_mut().find(|p| p.id == id); + if let Some(pt) = pt { + pt.location = (x, y); + sink.send_event( + WindowEvent::Touch(::Touch { + device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), + phase: TouchPhase::Moved, + location: (x, y).into(), + id: id as u64, + }), + pt.wid, + ); + } + } + TouchEvent::Frame => (), + TouchEvent::Cancel => for pt in pending_ids.drain(..) { sink.send_event( WindowEvent::Touch(::Touch { device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - phase: TouchPhase::Ended, + phase: TouchPhase::Cancelled, location: pt.location.into(), - id: id as u64, + id: pt.id as u64, }), pt.wid, ); - } + }, } - TouchEvent::Motion { id, x, y, .. } => { - let pt = pending_ids.iter_mut().find(|p| p.id == id); - if let Some(pt) = pt { - pt.location = (x, y); - sink.send_event( - WindowEvent::Touch(::Touch { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - phase: TouchPhase::Moved, - location: (x, y).into(), - id: id as u64, - }), - pt.wid, - ); - } - } - TouchEvent::Frame => (), - TouchEvent::Cancel => for pt in pending_ids.drain(..) { - sink.send_event( - WindowEvent::Touch(::Touch { - device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)), - phase: TouchPhase::Cancelled, - location: pt.location.into(), - id: pt.id as u64, - }), - pt.wid, - ); - }, - } - }) + }, ()) + }).unwrap() } diff --git a/src/platform/linux/wayland/window.rs b/src/platform/linux/wayland/window.rs index c373cbd3..6d9da8b0 100644 --- a/src/platform/linux/wayland/window.rs +++ b/src/platform/linux/wayland/window.rs @@ -6,7 +6,7 @@ use dpi::{LogicalPosition, LogicalSize}; use platform::MonitorId as PlatformMonitorId; use window::MonitorId as RootMonitorId; -use sctk::window::{BasicFrame, Event as WEvent, Window as SWindow}; +use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow}; use sctk::reexports::client::{Display, Proxy}; use sctk::reexports::client::protocol::{wl_seat, wl_surface, wl_output}; use sctk::reexports::client::protocol::wl_compositor::RequestsTrait as CompositorRequests; @@ -18,7 +18,7 @@ use platform::platform::wayland::event_loop::{get_available_monitors, get_primar pub struct Window { surface: Proxy, - frame: Arc>>, + frame: Arc>>, monitors: Arc>, // Monitors this window is currently on outputs: OutputMgr, // Access to info for all monitors size: Arc>, @@ -36,11 +36,11 @@ impl Window { // monitor tracking let monitor_list = Arc::new(Mutex::new(MonitorList::new())); - let surface = evlp.env.compositor.create_surface().unwrap().implement({ + let surface = evlp.env.compositor.create_surface(|surface| { let list = monitor_list.clone(); let omgr = evlp.env.outputs.clone(); let window_store = evlp.store.clone(); - move |event, surface: Proxy| match event { + surface.implement(move |event, surface| match event { wl_surface::Event::Enter { output } => { let dpi_change = list.lock().unwrap().add_output(MonitorId { proxy: output, @@ -64,16 +64,16 @@ impl Window { } } } - } - }); + }, ()) + }).unwrap(); let window_store = evlp.store.clone(); let my_surface = surface.clone(); - let mut frame = SWindow::::init_from_env( + let mut frame = SWindow::::init_from_env( &evlp.env, surface.clone(), (width, height), - move |event, ()| match event { + move |event| match event { WEvent::Configure { new_size, .. } => { let mut store = window_store.lock().unwrap(); for window in &mut store.windows { @@ -324,7 +324,7 @@ struct InternalWindow { need_frame_refresh: Arc>, closed: bool, kill_switch: Arc>, - frame: Weak>>, + frame: Weak>>, current_dpi: i32, new_dpi: Option } @@ -382,7 +382,7 @@ impl WindowStore { pub fn for_each(&mut self, mut f: F) where - F: FnMut(Option<(u32, u32)>, &mut (u32, u32), Option, bool, bool, bool, WindowId, Option<&mut SWindow>), + F: FnMut(Option<(u32, u32)>, &mut (u32, u32), Option, bool, bool, bool, WindowId, Option<&mut SWindow>), { for window in &mut self.windows { let opt_arc = window.frame.upgrade();