diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 8f24555f..b02bf7ab 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -334,7 +334,7 @@ normalize_wheel(struct tablet_dispatch *tablet, { struct evdev_device *device = tablet->device; - return value * device->scroll.wheel_click_angle; + return value * device->scroll.wheel_click_angle.x; } static inline void diff --git a/src/evdev.c b/src/evdev.c index e906a507..f798e8e1 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -805,7 +805,7 @@ fallback_process_relative(struct fallback_dispatch *dispatch, case REL_WHEEL: fallback_flush_pending_event(dispatch, device, time); wheel_degrees.y = -1 * e->value * - device->scroll.wheel_click_angle; + device->scroll.wheel_click_angle.x; discrete.y = -1 * e->value; evdev_notify_axis( device, @@ -817,7 +817,8 @@ fallback_process_relative(struct fallback_dispatch *dispatch, break; case REL_HWHEEL: fallback_flush_pending_event(dispatch, device, time); - wheel_degrees.x = e->value * device->scroll.wheel_click_angle; + wheel_degrees.x = e->value * + device->scroll.wheel_click_angle.y; discrete.x = e->value; evdev_notify_axis( device, @@ -1815,27 +1816,47 @@ evdev_device_init_pointer_acceleration(struct evdev_device *device, } } -static inline int -evdev_read_wheel_click_prop(struct evdev_device *device) +static inline bool +evdev_read_wheel_click_prop(struct evdev_device *device, + const char *prop, + int *angle) { - const char *prop; - int angle = DEFAULT_WHEEL_CLICK_ANGLE; + int val; - prop = udev_device_get_property_value(device->udev_device, - "MOUSE_WHEEL_CLICK_ANGLE"); - if (prop) { - angle = parse_mouse_wheel_click_angle_property(prop); - if (!angle) { - log_error(evdev_libinput_context(device), - "Mouse wheel click angle '%s' is present but invalid," - "using %d degrees instead\n", - device->devname, - DEFAULT_WHEEL_CLICK_ANGLE); - angle = DEFAULT_WHEEL_CLICK_ANGLE; - } + *angle = DEFAULT_WHEEL_CLICK_ANGLE; + prop = udev_device_get_property_value(device->udev_device, prop); + if (!prop) + return false; + + val = parse_mouse_wheel_click_angle_property(prop); + if (angle) { + *angle = val; + return true; } - return angle; + log_error(evdev_libinput_context(device), + "Mouse wheel click angle '%s' is present but invalid," + "using %d degrees instead\n", + device->devname, + DEFAULT_WHEEL_CLICK_ANGLE); + + return false; +} + +static inline struct wheel_angle +evdev_read_wheel_click_props(struct evdev_device *device) +{ + struct wheel_angle angles; + + evdev_read_wheel_click_prop(device, + "MOUSE_WHEEL_CLICK_ANGLE", + &angles.x); + if (!evdev_read_wheel_click_prop(device, + "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL", + &angles.y)) + angles.y = angles.x; + + return angles; } static inline int @@ -2550,7 +2571,7 @@ evdev_device_create(struct libinput_seat *seat, device->scroll.direction_lock_threshold = 5.0; /* Default may be overridden */ device->scroll.direction = 0; device->scroll.wheel_click_angle = - evdev_read_wheel_click_prop(device); + evdev_read_wheel_click_props(device); device->model_flags = evdev_read_model_flags(device); device->dpi = DEFAULT_MOUSE_DPI; diff --git a/src/evdev.h b/src/evdev.h index 1a2f1ff6..9564e772 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -187,7 +187,7 @@ struct evdev_device { bool natural_scrolling_enabled; /* angle per REL_WHEEL click in degrees */ - int wheel_click_angle; + struct wheel_angle wheel_click_angle; } scroll; struct { diff --git a/src/libinput-private.h b/src/libinput-private.h index 479da756..28656e07 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -71,6 +71,11 @@ struct normalized_range_coords { double x, y; }; +/* A pair of angles in degrees */ +struct wheel_angle { + int x, y; +}; + /* A pair of angles in degrees */ struct tilt_degrees { double x, y; diff --git a/test/litest-device-mouse-wheel-click-angle.c b/test/litest-device-mouse-wheel-click-angle.c index 1460ee31..fd2e2257 100644 --- a/test/litest-device-mouse-wheel-click-angle.c +++ b/test/litest-device-mouse-wheel-click-angle.c @@ -56,6 +56,7 @@ static const char udev_rule[] = "\n" "ATTRS{name}==\"litest Wheel Click Angle Mouse*\",\\\n" " ENV{MOUSE_WHEEL_CLICK_ANGLE}=\"-7\"\n" +" ENV{MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL}=\"13\"\n" "\n" "LABEL=\"wheel_click_angle_end\""; diff --git a/test/pointer.c b/test/pointer.c index ac67ab9e..175cb3b1 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -474,17 +474,20 @@ START_TEST(pointer_button_auto_release) END_TEST static inline int -wheel_click_angle(struct litest_device *dev) +wheel_click_angle(struct litest_device *dev, int which) { struct udev_device *d; - const char *prop; + const char *prop = NULL; const int default_angle = 15; int angle = default_angle; d = libinput_device_get_udev_device(dev->libinput_device); litest_assert_ptr_notnull(d); - prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE"); + if (which == REL_HWHEEL) + prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL"); + if(!prop) + prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE"); if (!prop) goto out; @@ -507,7 +510,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount) int scroll_step, expected, discrete;; - scroll_step = wheel_click_angle(dev); + scroll_step = wheel_click_angle(dev, which); expected = amount * scroll_step; discrete = amount;