Repository navigation
input: fix touchpad_scroll_speed and apply it to all scroll methods - #3184
Open
italopaesano wants to merge 2 commits into
Open
italopaesano wants to merge 2 commits into
italopaesano wants to merge 2 commits into
Conversation
touchpad_scroll_speed had no effect at all. get_scroll_speed() required a WLR_INPUT_DEVICE_TABLET_PAD to apply it, but its only caller passes &ev->pointer->base, which wlroots guarantees to be of type WLR_INPUT_DEVICE_POINTER -- it asserts so in wlr_pointer_from_input_device(). The condition was therefore always true for finger scrolling and the function returned 1.0. Tablet pads, the only devices that would have passed the check, do not emit pointer axis events; for them the cast of base.data to pointing_device_t would not have been valid either. Deciding this from the axis source alone is not enough: libinput reports button scrolling as WL_POINTER_AXIS_SOURCE_CONTINUOUS, and on-button-down is one of the touchpad scroll methods Wayfire offers, so a touchpad configured that way kept using mouse_scroll_speed. The source is still needed, though, for pointers which do not come from libinput, such as events forwarded by a parent compositor in a nested session. Use the touchpad speed when either the device is a touchpad or the event is finger scrolling, and take the device type from the same libinput check which update_options() already uses for every other touchpad option, so that the compositor has a single definition of what a touchpad is. The check moves to the constructor since the capability does not change at runtime. The device type is no longer passed in, as it was only used by a condition which could never be true. Users who compensated for this by setting mouse_scroll_speed for a touchpad in on-button-down mode will need to move the value to touchpad_scroll_speed. Fixes WayfireWM#3148 Co-Authored-By: Claude <noreply@anthropic.com>
Add a headless test which announces two dummy pointer devices, sends axis events through the pointer input path and checks the resulting delta against the configured multiplier: finger and wheel scrolling, and button scrolling on a touchpad and on another device. Neither backend available to CI can produce touchpad input -- the X11 backend only emits WL_POINTER_AXIS_SOURCE_WHEEL and the headless backend has no input devices -- so the test drives pointer_t::handle_pointer_axis() through the existing harness, in the same way pointer_button() already does, and marks the dummy device as a touchpad the way libinput would report a real one. The test includes wlr/interfaces/wlr_pointer.h in an extern "C" block of its own, the way plugins/ipc/stipc.cpp does, since that header has no guard of its own and carries no stability guarantees. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
input/touchpad_scroll_speedcurrently has no effect at all, and buttonscrolling on a touchpad has never used it.
The option never applies
get_scroll_speed()required aWLR_INPUT_DEVICE_TABLET_PADto returntouchpad_scroll_speed:Its only caller is
pointer_t::handle_pointer_axis(), which passes&ev->pointer->base. wlroots guarantees that device to be of typeWLR_INPUT_DEVICE_POINTER—wlr_pointer_from_input_device()asserts it. Thefirst branch is therefore always true for finger scrolling and the function
returns
1.0. Tablet pads, the only devices which would have passed thecheck, do not emit pointer axis events; for them
base.datawould not point toa
pointing_device_teither.This is a regression from 1a93066: before that commit
handle_pointer_axis()applied
config.touchpad_scroll_speeddirectly toWL_POINTER_AXIS_SOURCE_FINGERevents.The axis source alone is not enough
libinput reports button scrolling as
WL_POINTER_AXIS_SOURCE_CONTINUOUS, andon-button-downis one of the touchpad scroll methods Wayfire offers, so atouchpad configured that way kept using
mouse_scroll_speed. That case neverworked, not even before the regression, because the old code used the same
source-based test.
The source is still needed, though: pointers which do not come from libinput —
for example when a parent compositor forwards finger scrolling to a nested
session — cannot be recognised as touchpads.
The change
Use the touchpad speed when either the device is a touchpad or the event is
finger scrolling:
is_touchpadcomes fromlibinput_device_config_tap_get_finger_count(dev) > 0,the check
update_options()already uses for every other touchpad option. Itis computed once in the constructor, since the capability does not change at
runtime, and reused in both places, so the compositor has a single definition
of what a touchpad is. Every other touchpad option — natural scroll, tap to
click, acceleration profile, cursor speed — has always been device-based; the
scroll speed was the exception.
The device is no longer passed in, as it was only used by a condition which
could never be true.
Tests
The second commit adds a headless test which announces two dummy pointer
devices and checks the delta an axis event comes out with: finger scrolling,
wheel scrolling, and button scrolling on a touchpad and on another device. One
device is marked as a touchpad the way libinput would report a real one,
because a dummy device is not a libinput device.
pointer_axis()is added tothe test harness alongside the existing
pointer_button().The test includes
wlr/interfaces/wlr_pointer.hin anextern "C"block ofits own, the way
plugins/ipc/stipc.cppdoes, rather than adding it to theinstalled
wlroots-full.hpp: the interfaces header declares itself unstable,and no plugin needs it.
Verification:
ninja -C build test: 35/35, and 33/33 with-Dxwayland=disabled, which iswhat CI builds;
CHECK( 10 == Approx( 1 ) );is_touchpadterm removed, exactly the button scrolling caseon a touchpad fails with
CHECK( 5 == Approx( 1 ) ), so both terms of thecondition are covered by the test;
What the tests do not cover: that a physical touchpad produces these axis
sources, which follows from the libinput backend mapping in wlroots
(
backend/libinput/pointer.c) and from the report in the issue, and thelibinput side of
is_touchpad, since a dummy device is not a libinput device.One user-visible consequence of the second part: users who compensated for this
by setting
mouse_scroll_speedfor a touchpad inon-button-downmode willneed to move the value to
touchpad_scroll_speed.The first part of the fix is the one suggested in #3148 by the reporter.
Fixes #3148