Read the horizontal wheel click angle property if available

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@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Peter Hutterer 2016-08-16 14:48:47 +10:00
parent 3cb60130c1
commit b02acd346b
6 changed files with 56 additions and 26 deletions

View file

@ -334,7 +334,7 @@ normalize_wheel(struct tablet_dispatch *tablet,
{ {
struct evdev_device *device = tablet->device; struct evdev_device *device = tablet->device;
return value * device->scroll.wheel_click_angle; return value * device->scroll.wheel_click_angle.x;
} }
static inline void static inline void

View file

@ -805,7 +805,7 @@ fallback_process_relative(struct fallback_dispatch *dispatch,
case REL_WHEEL: case REL_WHEEL:
fallback_flush_pending_event(dispatch, device, time); fallback_flush_pending_event(dispatch, device, time);
wheel_degrees.y = -1 * e->value * wheel_degrees.y = -1 * e->value *
device->scroll.wheel_click_angle; device->scroll.wheel_click_angle.x;
discrete.y = -1 * e->value; discrete.y = -1 * e->value;
evdev_notify_axis( evdev_notify_axis(
device, device,
@ -817,7 +817,8 @@ fallback_process_relative(struct fallback_dispatch *dispatch,
break; break;
case REL_HWHEEL: case REL_HWHEEL:
fallback_flush_pending_event(dispatch, device, time); 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; discrete.x = e->value;
evdev_notify_axis( evdev_notify_axis(
device, device,
@ -1815,27 +1816,47 @@ evdev_device_init_pointer_acceleration(struct evdev_device *device,
} }
} }
static inline int static inline bool
evdev_read_wheel_click_prop(struct evdev_device *device) evdev_read_wheel_click_prop(struct evdev_device *device,
const char *prop,
int *angle)
{ {
const char *prop; int val;
int angle = DEFAULT_WHEEL_CLICK_ANGLE;
prop = udev_device_get_property_value(device->udev_device, *angle = DEFAULT_WHEEL_CLICK_ANGLE;
"MOUSE_WHEEL_CLICK_ANGLE"); prop = udev_device_get_property_value(device->udev_device, prop);
if (prop) { if (!prop)
angle = parse_mouse_wheel_click_angle_property(prop); return false;
if (!angle) {
log_error(evdev_libinput_context(device), val = parse_mouse_wheel_click_angle_property(prop);
"Mouse wheel click angle '%s' is present but invalid," if (angle) {
"using %d degrees instead\n", *angle = val;
device->devname, return true;
DEFAULT_WHEEL_CLICK_ANGLE);
angle = DEFAULT_WHEEL_CLICK_ANGLE;
}
} }
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 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_lock_threshold = 5.0; /* Default may be overridden */
device->scroll.direction = 0; device->scroll.direction = 0;
device->scroll.wheel_click_angle = 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->model_flags = evdev_read_model_flags(device);
device->dpi = DEFAULT_MOUSE_DPI; device->dpi = DEFAULT_MOUSE_DPI;

View file

@ -187,7 +187,7 @@ struct evdev_device {
bool natural_scrolling_enabled; bool natural_scrolling_enabled;
/* angle per REL_WHEEL click in degrees */ /* angle per REL_WHEEL click in degrees */
int wheel_click_angle; struct wheel_angle wheel_click_angle;
} scroll; } scroll;
struct { struct {

View file

@ -71,6 +71,11 @@ struct normalized_range_coords {
double x, y; double x, y;
}; };
/* A pair of angles in degrees */
struct wheel_angle {
int x, y;
};
/* A pair of angles in degrees */ /* A pair of angles in degrees */
struct tilt_degrees { struct tilt_degrees {
double x, y; double x, y;

View file

@ -56,6 +56,7 @@ static const char udev_rule[] =
"\n" "\n"
"ATTRS{name}==\"litest Wheel Click Angle Mouse*\",\\\n" "ATTRS{name}==\"litest Wheel Click Angle Mouse*\",\\\n"
" ENV{MOUSE_WHEEL_CLICK_ANGLE}=\"-7\"\n" " ENV{MOUSE_WHEEL_CLICK_ANGLE}=\"-7\"\n"
" ENV{MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL}=\"13\"\n"
"\n" "\n"
"LABEL=\"wheel_click_angle_end\""; "LABEL=\"wheel_click_angle_end\"";

View file

@ -474,17 +474,20 @@ START_TEST(pointer_button_auto_release)
END_TEST END_TEST
static inline int static inline int
wheel_click_angle(struct litest_device *dev) wheel_click_angle(struct litest_device *dev, int which)
{ {
struct udev_device *d; struct udev_device *d;
const char *prop; const char *prop = NULL;
const int default_angle = 15; const int default_angle = 15;
int angle = default_angle; int angle = default_angle;
d = libinput_device_get_udev_device(dev->libinput_device); d = libinput_device_get_udev_device(dev->libinput_device);
litest_assert_ptr_notnull(d); 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) if (!prop)
goto out; goto out;
@ -507,7 +510,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount)
int scroll_step, expected, discrete;; int scroll_step, expected, discrete;;
scroll_step = wheel_click_angle(dev); scroll_step = wheel_click_angle(dev, which);
expected = amount * scroll_step; expected = amount * scroll_step;
discrete = amount; discrete = amount;