From afa628e9080a76f0b719db9f7406d3e47a2b5a64 Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Sat, 4 May 2024 02:13:13 +0200 Subject: [PATCH 1/2] add discrete120 scroll event --- src/capture/wayland.rs | 16 ++++++++++++--- src/capture/windows.rs | 5 ++--- src/emulate/libei.rs | 16 +++++++++++++-- src/emulate/macos.rs | 32 +++++++++++++++++++++++++++-- src/emulate/windows.rs | 7 ++++--- src/emulate/wlroots.rs | 5 +++++ src/emulate/x11.rs | 3 +++ src/emulate/xdg_desktop_portal.rs | 23 +++++++++++++++++---- src/event.rs | 34 +++++++++++++++++++++++++++++++ 9 files changed, 124 insertions(+), 17 deletions(-) diff --git a/src/capture/wayland.rs b/src/capture/wayland.rs index eaa15266..043db5ee 100644 --- a/src/capture/wayland.rs +++ b/src/capture/wayland.rs @@ -750,14 +750,24 @@ impl Dispatch for State { }), )); } - wl_pointer::Event::AxisValue120 { axis, value120 } => { + wl_pointer::Event::Axis { time, axis, value } => { let (_, client) = app.focused.as_ref().unwrap(); app.pending_events.push_back(( *client, Event::Pointer(PointerEvent::Axis { - time: 0, + time, + axis: u32::from(axis) as u8, + value, + }), + )); + } + wl_pointer::Event::AxisValue120 { axis, value120 } => { + let (_, client) = app.focused.as_ref().unwrap(); + app.pending_events.push_back(( + *client, + Event::Pointer(PointerEvent::AxisDiscrete120 { axis: u32::from(axis) as u8, - value: value120 as f64, + value: value120, }), )); } diff --git a/src/capture/windows.rs b/src/capture/windows.rs index ae4f9ea2..58093704 100644 --- a/src/capture/windows.rs +++ b/src/capture/windows.rs @@ -139,10 +139,9 @@ fn to_mouse_event(wparam: WPARAM, lparam: LPARAM) -> Option { relative_y: dy as f64, }) }, - WPARAM(p) if p == WM_MOUSEWHEEL as usize => Some(PointerEvent::Axis { - time: 0, + WPARAM(p) if p == WM_MOUSEWHEEL as usize => Some(PointerEvent::AxisDiscrete120 { axis: 0, - value: -(mouse_low_level.mouseData as i32) as f64, + value: -(mouse_low_level.mouseData as i32), }), WPARAM(p) if p == WM_XBUTTONDOWN as usize || p == WM_XBUTTONUP as usize => { let hb = mouse_low_level.mouseData >> 16; diff --git a/src/emulate/libei.rs b/src/emulate/libei.rs index faad14c1..7b6f1599 100644 --- a/src/emulate/libei.rs +++ b/src/emulate/libei.rs @@ -157,8 +157,20 @@ impl InputEmulation for LibeiEmulation { } if let Some((d, s)) = self.scroll.as_mut() { match axis { - 0 => s.scroll_discrete(0, value as i32), - _ => s.scroll_discrete(value as i32, 0), + 0 => s.scroll(0., value as f32), + _ => s.scroll(value as f32, 0.), + } + d.frame(self.serial, now); + } + } + crate::event::PointerEvent::AxisDiscrete120 { axis, value } => { + if !self.has_scroll { + return; + } + if let Some((d, s)) = self.scroll.as_mut() { + match axis { + 0 => s.scroll_discrete(0, value), + _ => s.scroll_discrete(value, 0), } d.frame(self.serial, now); } diff --git a/src/emulate/macos.rs b/src/emulate/macos.rs index e5b0d61d..6459a152 100644 --- a/src/emulate/macos.rs +++ b/src/emulate/macos.rs @@ -220,7 +220,7 @@ impl InputEmulation for MacOSEmulation { axis, value, } => { - let value = value as i32 / 10; // FIXME: high precision scroll events + let value = value as i32; let (count, wheel1, wheel2, wheel3) = match axis { 0 => (1, value, 0, 0), // 0 = vertical => 1 scroll wheel device (y axis) 1 => (2, 0, value, 0), // 1 = horizontal => 2 scroll wheel devices (y, x) -> (0, x) @@ -231,7 +231,35 @@ impl InputEmulation for MacOSEmulation { }; let event = match CGEvent::new_scroll_event( self.event_source.clone(), - ScrollEventUnit::LINE, + ScrollEventUnit::PIXEL, + count, + wheel1, + wheel2, + wheel3, + ) { + Ok(e) => e, + Err(()) => { + log::warn!("scroll event creation failed!"); + return; + } + }; + event.post(CGEventTapLocation::HID); + } + PointerEvent::AxisDiscrete120 { + axis, + value, + } => { + let (count, wheel1, wheel2, wheel3) = match axis { + 0 => (1, value, 0, 0), // 0 = vertical => 1 scroll wheel device (y axis) + 1 => (2, 0, value, 0), // 1 = horizontal => 2 scroll wheel devices (y, x) -> (0, x) + _ => { + log::warn!("invalid scroll event: {axis}, {value}"); + return; + } + }; + let event = match CGEvent::new_scroll_event( + self.event_source.clone(), + ScrollEventUnit::PIXEL, count, wheel1, wheel2, diff --git a/src/emulate/windows.rs b/src/emulate/windows.rs index 49e02d4c..7eeb5c5f 100644 --- a/src/emulate/windows.rs +++ b/src/emulate/windows.rs @@ -59,7 +59,8 @@ impl InputEmulation for WindowsEmulation { time: _, axis, value, - } => scroll(axis, value), + } => scroll(axis, value as i32), + PointerEvent::AxisDiscrete120 { axis, value } => scroll(axis, value), PointerEvent::Frame {} => {} }, Event::Keyboard(keyboard_event) => match keyboard_event { @@ -182,7 +183,7 @@ fn mouse_button(button: u32, state: u32) { send_mouse_input(mi); } -fn scroll(axis: u8, value: f64) { +fn scroll(axis: u8, value: i32) { let event_type = match axis { 0 => MOUSEEVENTF_WHEEL, 1 => MOUSEEVENTF_HWHEEL, @@ -191,7 +192,7 @@ fn scroll(axis: u8, value: f64) { let mi = MOUSEINPUT { dx: 0, dy: 0, - mouseData: -value as i32 as u32, + mouseData: -value as u32, dwFlags: event_type, time: 0, dwExtraInfo: 0, diff --git a/src/emulate/wlroots.rs b/src/emulate/wlroots.rs index 54a44a66..30e17249 100644 --- a/src/emulate/wlroots.rs +++ b/src/emulate/wlroots.rs @@ -180,6 +180,11 @@ impl VirtualInput { self.pointer.axis(time, axis, value); self.pointer.frame(); } + PointerEvent::AxisDiscrete120 { axis, value } => { + let axis: Axis = (axis as u32).try_into()?; + self.pointer.axis(0, axis, (value / 15) as f64); + self.pointer.frame(); + } PointerEvent::Frame {} => self.pointer.frame(), } self.pointer.frame(); diff --git a/src/emulate/x11.rs b/src/emulate/x11.rs index 8979a44e..24cdb9da 100644 --- a/src/emulate/x11.rs +++ b/src/emulate/x11.rs @@ -125,6 +125,9 @@ impl InputEmulation for X11Emulation { } => { self.emulate_scroll(axis, value); } + PointerEvent::AxisDiscrete120 { axis, value } => { + self.emulate_scroll(axis, value as f64); + } PointerEvent::Frame {} => {} }, Event::Keyboard(KeyboardEvent::Key { diff --git a/src/emulate/xdg_desktop_portal.rs b/src/emulate/xdg_desktop_portal.rs index 21a2bdf8..0560bcec 100644 --- a/src/emulate/xdg_desktop_portal.rs +++ b/src/emulate/xdg_desktop_portal.rs @@ -94,8 +94,7 @@ impl<'a> InputEmulation for DesktopPortalEmulation<'a> { log::warn!("{e}"); } } - PointerEvent::Axis { - time: _, + PointerEvent::AxisDiscrete120 { axis, value, } => { @@ -103,10 +102,26 @@ impl<'a> InputEmulation for DesktopPortalEmulation<'a> { 0 => Axis::Vertical, _ => Axis::Horizontal, }; - // TODO smooth scrolling if let Err(e) = self .proxy - .notify_pointer_axis_discrete(&self.session, axis, value as i32) + .notify_pointer_axis_discrete(&self.session, axis, value) + .await + { + log::warn!("{e}"); + } + } + PointerEvent::Axis { time: _, axis, value } => { + let axis = match axis { + 0 => Axis::Vertical, + _ => Axis::Horizontal, + }; + let (dx, dy) = match axis { + Axis::Vertical => (0., value), + Axis::Horizontal => (value, 0.), + }; + if let Err(e) = self + .proxy + .notify_pointer_axis(&self.session, dx, dy, true) .await { log::warn!("{e}"); diff --git a/src/event.rs b/src/event.rs index fea25c35..f8d512d9 100644 --- a/src/event.rs +++ b/src/event.rs @@ -29,6 +29,10 @@ pub enum PointerEvent { axis: u8, value: f64, }, + AxisDiscrete120 { + axis: u8, + value: i32, + }, Frame {}, } @@ -104,6 +108,9 @@ impl Display for PointerEvent { axis, value, } => write!(f, "scroll({axis}, {value})"), + PointerEvent::AxisDiscrete120 { axis, value } => { + write!(f, "scroll-120 ({axis}, {value})") + } PointerEvent::Frame {} => write!(f, "frame()"), } } @@ -171,6 +178,7 @@ impl PointerEvent { Self::Motion { .. } => PointerEventType::Motion, Self::Button { .. } => PointerEventType::Button, Self::Axis { .. } => PointerEventType::Axis, + Self::AxisDiscrete120 { .. } => PointerEventType::AxisDiscrete120, Self::Frame { .. } => PointerEventType::Frame, } } @@ -189,6 +197,7 @@ enum PointerEventType { Motion, Button, Axis, + AxisDiscrete120, Frame, } enum KeyboardEventType { @@ -213,6 +222,7 @@ impl TryFrom for PointerEventType { x if x == Self::Motion as u8 => Ok(Self::Motion), x if x == Self::Button as u8 => Ok(Self::Button), x if x == Self::Axis as u8 => Ok(Self::Axis), + x if x == Self::AxisDiscrete120 as u8 => Ok(Self::AxisDiscrete120), x if x == Self::Frame as u8 => Ok(Self::Frame), _ => Err(anyhow!(ProtocolError { msg: format!("invalid pointer event type {}", value), @@ -313,6 +323,11 @@ impl From<&PointerEvent> for Vec { let value = value.to_be_bytes(); [&time[..], &axis[..], &value[..]].concat() } + PointerEvent::AxisDiscrete120 { axis, value } => { + let axis = axis.to_be_bytes(); + let value = value.to_be_bytes(); + [&axis[..], &value[..]].concat() + } PointerEvent::Frame {} => { vec![] } @@ -421,6 +436,25 @@ impl TryFrom> for PointerEvent { }; Ok(Self::Axis { time, axis, value }) } + PointerEventType::AxisDiscrete120 => { + let axis = match data.get(2) { + Some(d) => *d, + None => { + return Err(anyhow!(ProtocolError { + msg: "Expected 1 Byte at index 2".into(), + })); + } + }; + let value = match data.get(3..7) { + Some(d) => i32::from_be_bytes(d.try_into()?), + None => { + return Err(anyhow!(ProtocolError { + msg: "Expected 4 Bytes at index 3".into(), + })); + } + }; + Ok(Self::AxisDiscrete120 { axis, value }) + } PointerEventType::Frame => Ok(Self::Frame {}), } } From d1d401e950e16d08b001a93f98486684c339d47c Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Sat, 4 May 2024 03:22:13 +0200 Subject: [PATCH 2/2] formatting --- src/emulate/macos.rs | 5 +- src/emulate/xdg_desktop_portal.rs | 125 +++++++++++++++--------------- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/emulate/macos.rs b/src/emulate/macos.rs index 6459a152..f69b4fc4 100644 --- a/src/emulate/macos.rs +++ b/src/emulate/macos.rs @@ -245,10 +245,7 @@ impl InputEmulation for MacOSEmulation { }; event.post(CGEventTapLocation::HID); } - PointerEvent::AxisDiscrete120 { - axis, - value, - } => { + PointerEvent::AxisDiscrete120 { axis, value } => { let (count, wheel1, wheel2, wheel3) = match axis { 0 => (1, value, 0, 0), // 0 = vertical => 1 scroll wheel device (y axis) 1 => (2, 0, value, 0), // 1 = horizontal => 2 scroll wheel devices (y, x) -> (0, x) diff --git a/src/emulate/xdg_desktop_portal.rs b/src/emulate/xdg_desktop_portal.rs index 0560bcec..e0ff6c4a 100644 --- a/src/emulate/xdg_desktop_portal.rs +++ b/src/emulate/xdg_desktop_portal.rs @@ -62,74 +62,73 @@ impl<'a> DesktopPortalEmulation<'a> { impl<'a> InputEmulation for DesktopPortalEmulation<'a> { async fn consume(&mut self, event: crate::event::Event, _client: crate::client::ClientHandle) { match event { - Pointer(p) => { - match p { - PointerEvent::Motion { - time: _, - relative_x, - relative_y, - } => { - if let Err(e) = self - .proxy - .notify_pointer_motion(&self.session, relative_x, relative_y) - .await - { - log::warn!("{e}"); - } + Pointer(p) => match p { + PointerEvent::Motion { + time: _, + relative_x, + relative_y, + } => { + if let Err(e) = self + .proxy + .notify_pointer_motion(&self.session, relative_x, relative_y) + .await + { + log::warn!("{e}"); } - PointerEvent::Button { - time: _, - button, - state, - } => { - let state = match state { - 0 => KeyState::Released, - _ => KeyState::Pressed, - }; - if let Err(e) = self - .proxy - .notify_pointer_button(&self.session, button as i32, state) - .await - { - log::warn!("{e}"); - } + } + PointerEvent::Button { + time: _, + button, + state, + } => { + let state = match state { + 0 => KeyState::Released, + _ => KeyState::Pressed, + }; + if let Err(e) = self + .proxy + .notify_pointer_button(&self.session, button as i32, state) + .await + { + log::warn!("{e}"); } - PointerEvent::AxisDiscrete120 { - axis, - value, - } => { - let axis = match axis { - 0 => Axis::Vertical, - _ => Axis::Horizontal, - }; - if let Err(e) = self - .proxy - .notify_pointer_axis_discrete(&self.session, axis, value) - .await - { - log::warn!("{e}"); - } + } + PointerEvent::AxisDiscrete120 { axis, value } => { + let axis = match axis { + 0 => Axis::Vertical, + _ => Axis::Horizontal, + }; + if let Err(e) = self + .proxy + .notify_pointer_axis_discrete(&self.session, axis, value) + .await + { + log::warn!("{e}"); } - PointerEvent::Axis { time: _, axis, value } => { - let axis = match axis { - 0 => Axis::Vertical, - _ => Axis::Horizontal, - }; - let (dx, dy) = match axis { - Axis::Vertical => (0., value), - Axis::Horizontal => (value, 0.), - }; - if let Err(e) = self - .proxy - .notify_pointer_axis(&self.session, dx, dy, true) - .await - { - log::warn!("{e}"); - } + } + PointerEvent::Axis { + time: _, + axis, + value, + } => { + let axis = match axis { + 0 => Axis::Vertical, + _ => Axis::Horizontal, + }; + let (dx, dy) = match axis { + Axis::Vertical => (0., value), + Axis::Horizontal => (value, 0.), + }; + if let Err(e) = self + .proxy + .notify_pointer_axis(&self.session, dx, dy, true) + .await + { + log::warn!("{e}"); } - PointerEvent::Frame {} => {} } - } + PointerEvent::Frame {} => {} + }, Keyboard(k) => { match k { KeyboardEvent::Key {