[GH-ISSUE #318] slow scrolling chrome with emulation=wlroots capture=layer-shell #167

Closed
opened 2026-05-05 22:12:19 -06:00 by gitea-mirror · 3 comments
Owner

Originally created by @selckin on GitHub (Aug 9, 2025).
Original GitHub issue: https://github.com/feschber/lan-mouse/issues/318

Hello,

Using niri as compositor on both sides resulting in: emulation=wlroots capture=layer-shell

Mouse scrolling works fine in terminals, but only scrolls very small amount in google-chrome (in wayland mode)

Using 'wev' to show events, using the real mouse shows

[        15:      wl_pointer] axis_source: 0 (wheel)
[        15:      wl_pointer] axis_value120: axis: 0 (vertical), value120: 120
[        15:      wl_pointer] axis_relative_direction: axis: 0 (vertical), direction: 0
[        15:      wl_pointer] axis: time: 50410752; axis: 0 (vertical), value: 15.000000

Using the lan-mouse shows:

[        15:      wl_pointer] axis_source: 2 (continuous)
[        15:      wl_pointer] axis_value120: axis: 0 (vertical), value120: 1
[        15:      wl_pointer] axis_relative_direction: axis: 0 (vertical), direction: 0
[        15:      wl_pointer] axis: time: -1913142096; axis: 0 (vertical), value: 20.000000

Patching lan-mouse to pass the original value results in scrolling working for me in both terminals & google-chrome:

diff --git i/input-emulation/src/wlroots.rs w/input-emulation/src/wlroots.rs
index a36c7a1fc330..d860c0aebfd8 100644
--- i/input-emulation/src/wlroots.rs
+++ w/input-emulation/src/wlroots.rs
@@ -208,11 +208,11 @@ impl VirtualInput {
                         self.pointer.frame();
                     }
                     PointerEvent::AxisDiscrete120 { axis, value } => {
                         let axis: Axis = (axis as u32).try_into()?;
                         self.pointer
-                            .axis_discrete(now, axis, value as f64 / 6., value / 120);
+                            .axis_discrete(now, axis, value as f64 / 6., value);
                         self.pointer.frame();
                     }
                 }
                 self.pointer.frame();

Regards

Originally created by @selckin on GitHub (Aug 9, 2025). Original GitHub issue: https://github.com/feschber/lan-mouse/issues/318 Hello, Using niri as compositor on both sides resulting in: emulation=wlroots capture=layer-shell Mouse scrolling works fine in terminals, but only scrolls very small amount in google-chrome (in wayland mode) Using 'wev' to show events, using the real mouse shows ``` [ 15: wl_pointer] axis_source: 0 (wheel) [ 15: wl_pointer] axis_value120: axis: 0 (vertical), value120: 120 [ 15: wl_pointer] axis_relative_direction: axis: 0 (vertical), direction: 0 [ 15: wl_pointer] axis: time: 50410752; axis: 0 (vertical), value: 15.000000 ``` Using the lan-mouse shows: ``` [ 15: wl_pointer] axis_source: 2 (continuous) [ 15: wl_pointer] axis_value120: axis: 0 (vertical), value120: 1 [ 15: wl_pointer] axis_relative_direction: axis: 0 (vertical), direction: 0 [ 15: wl_pointer] axis: time: -1913142096; axis: 0 (vertical), value: 20.000000 ``` Patching lan-mouse to pass the original value results in scrolling working for me in both terminals & google-chrome: ``` diff --git i/input-emulation/src/wlroots.rs w/input-emulation/src/wlroots.rs index a36c7a1fc330..d860c0aebfd8 100644 --- i/input-emulation/src/wlroots.rs +++ w/input-emulation/src/wlroots.rs @@ -208,11 +208,11 @@ impl VirtualInput { self.pointer.frame(); } PointerEvent::AxisDiscrete120 { axis, value } => { let axis: Axis = (axis as u32).try_into()?; self.pointer - .axis_discrete(now, axis, value as f64 / 6., value / 120); + .axis_discrete(now, axis, value as f64 / 6., value); self.pointer.frame(); } } self.pointer.frame(); ``` Regards
Author
Owner

@selckin commented on GitHub (Aug 15, 2025):

Also need Wheel axis source, else scrolling over chrome (pinned) tabs will skip every other one

diff --git a/input-emulation/src/wlroots.rs b/input-emulation/src/wlroots.rs
index a36c7a1fc330..f5960425a5bd 100644
--- a/input-emulation/src/wlroots.rs
+++ b/input-emulation/src/wlroots.rs
@@ -10,11 +10,11 @@ use std::sync::{Arc, Mutex};
 use std::time::{SystemTime, UNIX_EPOCH};
 use wayland_client::backend::WaylandError;
 use wayland_client::WEnum;

 use wayland_client::protocol::wl_keyboard::{self, WlKeyboard};
-use wayland_client::protocol::wl_pointer::{Axis, ButtonState};
+use wayland_client::protocol::wl_pointer::{Axis, AxisSource, ButtonState};
 use wayland_client::protocol::wl_seat::WlSeat;
 use wayland_protocols_wlr::virtual_pointer::v1::client::{
     zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1 as VpManager,
     zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1 as Vp,
 };
@@ -208,11 +208,12 @@ impl VirtualInput {
                         self.pointer.frame();
                     }
                     PointerEvent::AxisDiscrete120 { axis, value } => {
                         let axis: Axis = (axis as u32).try_into()?;
                         self.pointer
-                            .axis_discrete(now, axis, value as f64 / 6., value / 120);
+                            .axis_discrete(now, axis, value as f64 / 8., value);
+                        self.pointer.axis_source(AxisSource::Wheel);;
                         self.pointer.frame();
                     }
                 }
                 self.pointer.frame();
             }
<!-- gh-comment-id:3192474754 --> @selckin commented on GitHub (Aug 15, 2025): Also need Wheel axis source, else scrolling over chrome (pinned) tabs will skip every other one ```patch diff --git a/input-emulation/src/wlroots.rs b/input-emulation/src/wlroots.rs index a36c7a1fc330..f5960425a5bd 100644 --- a/input-emulation/src/wlroots.rs +++ b/input-emulation/src/wlroots.rs @@ -10,11 +10,11 @@ use std::sync::{Arc, Mutex}; use std::time::{SystemTime, UNIX_EPOCH}; use wayland_client::backend::WaylandError; use wayland_client::WEnum; use wayland_client::protocol::wl_keyboard::{self, WlKeyboard}; -use wayland_client::protocol::wl_pointer::{Axis, ButtonState}; +use wayland_client::protocol::wl_pointer::{Axis, AxisSource, ButtonState}; use wayland_client::protocol::wl_seat::WlSeat; use wayland_protocols_wlr::virtual_pointer::v1::client::{ zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1 as VpManager, zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1 as Vp, }; @@ -208,11 +208,12 @@ impl VirtualInput { self.pointer.frame(); } PointerEvent::AxisDiscrete120 { axis, value } => { let axis: Axis = (axis as u32).try_into()?; self.pointer - .axis_discrete(now, axis, value as f64 / 6., value / 120); + .axis_discrete(now, axis, value as f64 / 8., value); + self.pointer.axis_source(AxisSource::Wheel);; self.pointer.frame(); } } self.pointer.frame(); } ```
Author
Owner

@feschber commented on GitHub (Oct 7, 2025):

I would gladly accept a PR for this! :)

<!-- gh-comment-id:3378719915 --> @feschber commented on GitHub (Oct 7, 2025): I would gladly accept a PR for this! :)
Author
Owner

@feschber commented on GitHub (Oct 9, 2025):

Closed #325

<!-- gh-comment-id:3384718707 --> @feschber commented on GitHub (Oct 9, 2025): Closed #325
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/lan-mouse#167
No description provided.