[PATCH libinput] Read the horizontal wheel click angle property if available

Peter Hutterer peter.hutterer at who-t.net
Tue Aug 16 05:18:34 UTC 2016


The Logitech MX master has different click angles for the two wheels.

https://github.com/systemd/systemd/issues/3947

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-tablet.c                           |  2 +-
 src/evdev.c                                  | 61 +++++++++++++++++++---------
 src/evdev.h                                  |  2 +-
 src/libinput-private.h                       |  5 +++
 test/litest-device-mouse-wheel-click-angle.c |  1 +
 test/pointer.c                               | 11 +++--
 6 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 8f24555..b02bf7a 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 e906a50..e8db238 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_HORIZ",
+					 &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 1a2f1ff..9564e77 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 479da75..28656e0 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -72,6 +72,11 @@ struct normalized_range_coords {
 };
 
 /* 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 1460ee3..e1800cd 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_HORIZ}=\"13\"\n"
 "\n"
 "LABEL=\"wheel_click_angle_end\"";
 
diff --git a/test/pointer.c b/test/pointer.c
index ac67ab9..7d58a3c 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_HORIZ");
+	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;
 
-- 
2.7.4



More information about the wayland-devel mailing list