From 50c87d6da7daf007f4e97a19f62f6c44e1795e76 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Fri, 27 May 2022 15:39:48 +0200 Subject: [PATCH] wayland: implement wl_seat v8 --- src/backend.rs | 6 +++-- src/backends/metal/input.rs | 38 ++++++++++++-------------- src/backends/x.rs | 8 +++--- src/ifs/wl_seat.rs | 2 +- src/ifs/wl_seat/event_handling.rs | 45 ++++++++++++++++++------------- src/ifs/wl_seat/pointer_owner.rs | 8 +++--- src/ifs/wl_seat/wl_pointer.rs | 25 +++++++++++------ src/it/test_backend.rs | 10 +++---- src/utils/scroller.rs | 44 +++++++++++++++++++++--------- wire/wl_pointer.txt | 5 ++++ 10 files changed, 111 insertions(+), 80 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index a53829b6..b618fcbd 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -148,6 +148,8 @@ pub enum AxisSource { Continuous = CONTINUOUS as _, } +pub const AXIS_120: i32 = 120; + #[derive(Debug)] pub enum InputEvent { Key { @@ -174,7 +176,7 @@ pub enum InputEvent { state: KeyState, }, - Axis { + AxisSmooth { dist: Fixed, axis: ScrollAxis, }, @@ -184,7 +186,7 @@ pub enum InputEvent { AxisStop { axis: ScrollAxis, }, - AxisDiscrete { + Axis120 { dist: i32, axis: ScrollAxis, }, diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index e59fbcc7..86fd82f3 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -3,7 +3,6 @@ use { backend::{AxisSource, InputEvent, KeyState, ScrollAxis}, backends::metal::MetalBackend, fixed::Fixed, - ifs::wl_seat::PX_PER_SCROLL, libinput::{ consts::{ LIBINPUT_BUTTON_STATE_PRESSED, LIBINPUT_KEY_STATE_PRESSED, @@ -127,7 +126,6 @@ impl MetalBackend { } fn handle_pointer_axis(self: &Rc, event: LibInputEvent, source: AxisSource) { - const ONE_TWENTRY: f64 = 120.0; let (event, dev) = unpack!(self, event, pointer_event); let axes = [ ( @@ -137,30 +135,28 @@ impl MetalBackend { (LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical), ]; dev.event(InputEvent::AxisSource { source }); - for (axis, sa) in axes { - if !event.has_axis(axis) { + for (pointer_axis, axis) in axes { + if !event.has_axis(pointer_axis) { continue; } - let mut scroll = match source { - AxisSource::Wheel => event.scroll_value_v120(axis), - _ => event.scroll_value(axis), + let scroll = match source { + AxisSource::Wheel => event.scroll_value_v120(pointer_axis), + _ => event.scroll_value(pointer_axis), }; - if scroll == 0.0 { - dev.event(InputEvent::AxisStop { axis: sa }); - } else { - if source == AxisSource::Wheel { - let scroll_discrete = scroll / ONE_TWENTRY; - dev.event(InputEvent::AxisDiscrete { - dist: scroll_discrete as _, - axis: sa, - }); - scroll = PX_PER_SCROLL * scroll_discrete; + let ie = if scroll == 0.0 { + InputEvent::AxisStop { axis } + } else if source == AxisSource::Wheel { + InputEvent::Axis120 { + dist: scroll as _, + axis, } - dev.event(InputEvent::Axis { + } else { + InputEvent::AxisSmooth { dist: Fixed::from_f64(scroll), - axis: sa, - }); - } + axis, + } + }; + dev.event(ie); } dev.event(InputEvent::AxisFrame { time_usec: event.time_usec(), diff --git a/src/backends/x.rs b/src/backends/x.rs index 86966b6b..574027de 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -5,11 +5,10 @@ use { AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, DrmDeviceId, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, - ScrollAxis, TransformMatrix, + ScrollAxis, TransformMatrix, AXIS_120, }, fixed::Fixed, format::XRGB8888, - ifs::wl_seat::PX_PER_SCROLL, render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture}, state::State, time::now_usec, @@ -765,9 +764,8 @@ impl XBackend { seat.mouse_event(InputEvent::AxisSource { source: AxisSource::Wheel, }); - seat.mouse_event(InputEvent::AxisDiscrete { dist: val, axis }); - seat.mouse_event(InputEvent::Axis { - dist: Fixed::from_f64(val as f64 * PX_PER_SCROLL), + seat.mouse_event(InputEvent::Axis120 { + dist: val * AXIS_120, axis, }); seat.mouse_event(InputEvent::AxisFrame { diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 0daf49c8..1ba0d716 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -729,7 +729,7 @@ impl Global for WlSeatGlobal { } fn version(&self) -> u32 { - 7 + 8 } fn break_loops(&self) { diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index 6808ca0f..38447ecc 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -1,6 +1,6 @@ use { crate::{ - backend::{ConnectorId, InputEvent, KeyState}, + backend::{ConnectorId, InputEvent, KeyState, AXIS_120}, client::{Client, ClientId}, fixed::Fixed, ifs::{ @@ -16,10 +16,11 @@ use { wl_pointer::{ self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION, AXIS_SOURCE_SINCE_VERSION, AXIS_STOP_SINCE_VERSION, - POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, WHEEL_TILT_SINCE_VERSION, + AXIS_VALUE120_SINCE_VERSION, POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, + WHEEL_TILT_SINCE_VERSION, }, zwp_relative_pointer_v1::ZwpRelativePointerV1, - Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, + Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, PX_PER_SCROLL, }, wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface}, }, @@ -192,8 +193,8 @@ impl WlSeatGlobal { } => self.pointer_owner.button(self, time_usec, button, state), InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source), - InputEvent::AxisDiscrete { dist, axis } => self.pointer_owner.axis_discrete(dist, axis), - InputEvent::Axis { dist, axis } => self.pointer_owner.axis(dist, axis), + InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis), + InputEvent::AxisSmooth { dist, axis } => self.pointer_owner.axis_smooth(dist, axis), InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis), InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec), } @@ -546,22 +547,28 @@ impl WlSeatGlobal { self.surface_pointer_event(since, surface, |p| p.send_axis_source(source)); } let time = (event.time_usec.get() / 1000) as _; - for i in 0..1 { - if let Some(delta) = event.discrete[i].get() { - self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| { - p.send_axis_discrete(i as _, delta) - }); + self.for_each_pointer(0, surface.client.id, |p| { + for i in 0..1 { + let axis = i as _; + if let Some(delta) = event.v120[i].get() { + if p.seat.version >= AXIS_VALUE120_SINCE_VERSION { + p.send_axis_value120(axis, delta); + } else if p.seat.version >= AXIS_DISCRETE_SINCE_VERSION { + p.send_axis_discrete(axis, delta / AXIS_120); + } + let px = (delta as f64 / AXIS_120 as f64) * PX_PER_SCROLL; + p.send_axis(time, axis, Fixed::from_f64(px)); + } else if let Some(delta) = event.smooth[i].get() { + p.send_axis(time, axis, delta); + } + if p.seat.version >= AXIS_STOP_SINCE_VERSION && event.stop[i].get() { + p.send_axis_stop(time, axis); + } } - if let Some(delta) = event.axis[i].get() { - self.surface_pointer_event(0, surface, |p| p.send_axis(time, i as _, delta)); + if p.seat.version >= POINTER_FRAME_SINCE_VERSION { + p.send_frame(); } - if event.stop[i].get() { - self.surface_pointer_event(AXIS_STOP_SINCE_VERSION, surface, |p| { - p.send_axis_stop(time, i as _) - }); - } - } - self.surface_pointer_frame(surface); + }); } } diff --git a/src/ifs/wl_seat/pointer_owner.rs b/src/ifs/wl_seat/pointer_owner.rs index bc283150..fad71137 100644 --- a/src/ifs/wl_seat/pointer_owner.rs +++ b/src/ifs/wl_seat/pointer_owner.rs @@ -39,12 +39,12 @@ impl PointerOwnerHolder { self.pending_scroll.source.set(Some(axis_source as _)); } - pub fn axis_discrete(&self, delta: i32, axis: ScrollAxis) { - self.pending_scroll.discrete[axis as usize].set(Some(delta)); + pub fn axis_120(&self, delta: i32, axis: ScrollAxis) { + self.pending_scroll.v120[axis as usize].set(Some(delta)); } - pub fn axis(&self, delta: Fixed, axis: ScrollAxis) { - self.pending_scroll.axis[axis as usize].set(Some(delta)); + pub fn axis_smooth(&self, delta: Fixed, axis: ScrollAxis) { + self.pending_scroll.smooth[axis as usize].set(Some(delta)); } pub fn axis_stop(&self, axis: ScrollAxis) { diff --git a/src/ifs/wl_seat/wl_pointer.rs b/src/ifs/wl_seat/wl_pointer.rs index 28b5de79..ca33efb9 100644 --- a/src/ifs/wl_seat/wl_pointer.rs +++ b/src/ifs/wl_seat/wl_pointer.rs @@ -33,11 +33,12 @@ pub const AXIS_SOURCE_SINCE_VERSION: u32 = 5; pub const AXIS_DISCRETE_SINCE_VERSION: u32 = 5; pub const AXIS_STOP_SINCE_VERSION: u32 = 5; pub const WHEEL_TILT_SINCE_VERSION: u32 = 6; +pub const AXIS_VALUE120_SINCE_VERSION: u32 = 8; #[derive(Default, Debug)] pub struct PendingScroll { - pub discrete: [Cell>; 2], - pub axis: [Cell>; 2], + pub v120: [Cell>; 2], + pub smooth: [Cell>; 2], pub stop: [Cell; 2], pub source: Cell>, pub time_usec: Cell, @@ -46,13 +47,13 @@ pub struct PendingScroll { impl PendingScroll { pub fn take(&self) -> Self { Self { - discrete: [ - Cell::new(self.discrete[0].take()), - Cell::new(self.discrete[1].take()), + v120: [ + Cell::new(self.v120[0].take()), + Cell::new(self.v120[1].take()), ], - axis: [ - Cell::new(self.axis[0].take()), - Cell::new(self.axis[1].take()), + smooth: [ + Cell::new(self.smooth[0].take()), + Cell::new(self.smooth[1].take()), ], stop: [ Cell::new(self.stop[0].take()), @@ -156,6 +157,14 @@ impl WlPointer { }) } + pub fn send_axis_value120(&self, axis: u32, value120: i32) { + self.seat.client.event(AxisValue120 { + self_id: self.id, + axis, + value120, + }) + } + fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), WlPointerError> { let req: SetCursor = self.seat.client.parse(self, parser)?; if !self.seat.client.valid_serial(req.serial) { diff --git a/src/it/test_backend.rs b/src/it/test_backend.rs index 62c9a823..089c91ce 100644 --- a/src/it/test_backend.rs +++ b/src/it/test_backend.rs @@ -307,12 +307,8 @@ impl TestBackendMouse { self.common.event(InputEvent::AxisSource { source: AxisSource::Wheel, }); - self.common.event(InputEvent::AxisDiscrete { - dist: dy, - axis: ScrollAxis::Vertical, - }); - self.common.event(InputEvent::Axis { - dist: Fixed::from_int(dy * 15), + self.common.event(InputEvent::Axis120 { + dist: dy * 120, axis: ScrollAxis::Vertical, }); self.common.event(InputEvent::AxisFrame { @@ -324,7 +320,7 @@ impl TestBackendMouse { self.common.event(InputEvent::AxisSource { source: AxisSource::Wheel, }); - self.common.event(InputEvent::Axis { + self.common.event(InputEvent::AxisSmooth { dist: Fixed::from_int(dy), axis: ScrollAxis::Vertical, }); diff --git a/src/utils/scroller.rs b/src/utils/scroller.rs index db75eb99..85f6080c 100644 --- a/src/utils/scroller.rs +++ b/src/utils/scroller.rs @@ -1,27 +1,45 @@ use { - crate::ifs::wl_seat::{ - wl_pointer::{PendingScroll, VERTICAL_SCROLL}, - PX_PER_SCROLL, + crate::{ + backend::AXIS_120, + ifs::wl_seat::{ + wl_pointer::{PendingScroll, VERTICAL_SCROLL}, + PX_PER_SCROLL, + }, }, std::cell::Cell, }; #[derive(Default)] pub struct Scroller { - scroll: Cell, + v120: Cell, + smooth: Cell, } impl Scroller { pub fn handle(&self, scroll: &PendingScroll) -> Option { - if let Some(d) = scroll.discrete[VERTICAL_SCROLL as usize].get() { - self.scroll.set(0.0); - Some(d) - } else if let Some(scroll) = scroll.axis[VERTICAL_SCROLL as usize].get() { - let mut scroll = self.scroll.get() + scroll.to_f64(); - let discrete = (scroll / PX_PER_SCROLL).trunc(); - scroll -= discrete * PX_PER_SCROLL; - self.scroll.set(scroll); - Some(discrete as i32) + let n = if let Some(d) = scroll.v120[VERTICAL_SCROLL as usize].get() { + self.smooth.set(0.0); + let mut v120 = self.v120.get() + d; + let discrete = v120 / AXIS_120; + v120 -= discrete * AXIS_120; + self.v120.set(v120); + discrete + } else if let Some(smooth) = scroll.smooth[VERTICAL_SCROLL as usize].get() { + self.v120.set(0); + let mut smooth = self.smooth.get() + smooth.to_f64(); + let discrete = (smooth / PX_PER_SCROLL).trunc(); + smooth -= discrete * PX_PER_SCROLL; + self.smooth.set(smooth); + discrete as _ + } else { + 0 + }; + if scroll.stop[VERTICAL_SCROLL as usize].get() { + self.v120.set(0); + self.smooth.set(0.0); + } + if n != 0 { + Some(n) } else { None } diff --git a/wire/wl_pointer.txt b/wire/wl_pointer.txt index 598db62b..a9cdd155 100644 --- a/wire/wl_pointer.txt +++ b/wire/wl_pointer.txt @@ -61,3 +61,8 @@ msg axis_discrete = 8 { axis: u32, discrete: i32, } + +msg axis_value120 = 9 { + axis: u32, + value120: i32, +}