mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 03:30:05 +01:00
evdev: if a device's rotation is around 180 degrees, flip the wheel
For a device used upside-down, make sure the wheels correspond to the new physical directions. There's a grace range of 20 degrees either way since that seems like it makes sense. For 90 degree rotation (or 270 degree) the wheel is left as-is, the heuristics to guess what angle we want in this case is not clear enough. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
64af4beb6b
commit
d3481c8807
3 changed files with 64 additions and 0 deletions
|
|
@ -173,3 +173,7 @@ allowing the device to be used e.g. sideways or upside-down. For example, a
|
|||
trackball may be used in a 90° rotated position for accessibility reasons -
|
||||
such a rotated position allows triggering the buttons with the thumb or
|
||||
the non-dominant hand.
|
||||
|
||||
Note that where a device rotation is higher than 160 but less than 200 degrees,
|
||||
the direction of wheels is also inverted. For all other angles, the wheel
|
||||
direction is left as-is.
|
||||
|
|
|
|||
|
|
@ -323,6 +323,21 @@ wheel_handle_direction_change(struct fallback_dispatch *dispatch,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_rotate_wheel(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
struct input_event *e)
|
||||
{
|
||||
/* Special case: if we're upside down (-ish),
|
||||
* swap the direction of the wheels so that user-down
|
||||
* means scroll down. This isn't done for any other angle
|
||||
* since it's not clear what the heuristics should be.*/
|
||||
if (dispatch->rotation.angle >= 160.0 &&
|
||||
dispatch->rotation.angle <= 220.0) {
|
||||
e->value *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
|
|
@ -330,6 +345,7 @@ fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
|
|||
{
|
||||
switch (e->code) {
|
||||
case REL_WHEEL:
|
||||
fallback_rotate_wheel(dispatch, device, e);
|
||||
dispatch->wheel.lo_res.y += e->value;
|
||||
if (dispatch->wheel.emulate_hi_res_wheel)
|
||||
dispatch->wheel.hi_res.y += e->value * 120;
|
||||
|
|
@ -337,6 +353,7 @@ fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
|
|||
wheel_handle_event(dispatch, WHEEL_EVENT_SCROLL, time);
|
||||
break;
|
||||
case REL_HWHEEL:
|
||||
fallback_rotate_wheel(dispatch, device, e);
|
||||
dispatch->wheel.lo_res.x += e->value;
|
||||
if (dispatch->wheel.emulate_hi_res_wheel)
|
||||
dispatch->wheel.hi_res.x += e->value * 120;
|
||||
|
|
@ -344,6 +361,7 @@ fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
|
|||
wheel_handle_event(dispatch, WHEEL_EVENT_SCROLL, time);
|
||||
break;
|
||||
case REL_WHEEL_HI_RES:
|
||||
fallback_rotate_wheel(dispatch, device, e);
|
||||
dispatch->wheel.hi_res.y += e->value;
|
||||
dispatch->wheel.hi_res_event_received = true;
|
||||
dispatch->pending_event |= EVDEV_WHEEL;
|
||||
|
|
@ -351,6 +369,7 @@ fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
|
|||
wheel_handle_event(dispatch, WHEEL_EVENT_SCROLL, time);
|
||||
break;
|
||||
case REL_HWHEEL_HI_RES:
|
||||
fallback_rotate_wheel(dispatch, device, e);
|
||||
dispatch->wheel.hi_res.x += e->value;
|
||||
dispatch->wheel.hi_res_event_received = true;
|
||||
dispatch->pending_event |= EVDEV_WHEEL;
|
||||
|
|
|
|||
|
|
@ -628,6 +628,13 @@ test_high_and_low_wheel_events_value(struct litest_device *dev,
|
|||
v120 *= -1;
|
||||
}
|
||||
|
||||
double angle = libinput_device_config_rotation_get_angle(dev->libinput_device);
|
||||
if (angle >= 160.0 && angle <= 220.0) {
|
||||
expected *= -1;
|
||||
discrete *= -1;
|
||||
v120 *= -1;
|
||||
}
|
||||
|
||||
axis = (which == REL_WHEEL || which == REL_WHEEL_HI_RES) ?
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
|
||||
|
|
@ -1060,6 +1067,38 @@ START_TEST(pointer_scroll_has_axis_invalid)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(pointer_scroll_with_rotation)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *device = dev->libinput_device;
|
||||
double angle = _i * 20; /* ranged test */
|
||||
|
||||
litest_drain_events(li);
|
||||
libinput_device_config_rotation_set_angle(device, angle);
|
||||
|
||||
/* make sure we hit at least one of the below two conditions */
|
||||
ck_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
|
||||
libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
|
||||
|
||||
if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
|
||||
test_wheel_event(dev, REL_WHEEL, -1);
|
||||
test_wheel_event(dev, REL_WHEEL, 1);
|
||||
|
||||
test_wheel_event(dev, REL_WHEEL, -5);
|
||||
test_wheel_event(dev, REL_WHEEL, 6);
|
||||
}
|
||||
|
||||
if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
|
||||
test_wheel_event(dev, REL_HWHEEL, -1);
|
||||
test_wheel_event(dev, REL_HWHEEL, 1);
|
||||
|
||||
test_wheel_event(dev, REL_HWHEEL, -5);
|
||||
test_wheel_event(dev, REL_HWHEEL, 6);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(pointer_seat_button_count)
|
||||
{
|
||||
struct litest_device *devices[4];
|
||||
|
|
@ -3713,6 +3752,7 @@ TEST_COLLECTION(pointer)
|
|||
struct range buttonorder = {0, _MB_BUTTONORDER_COUNT};
|
||||
struct range scroll_directions = {LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL + 1};
|
||||
struct range rotation_20deg = {0, 18}; /* steps of 20 degrees */
|
||||
|
||||
litest_add(pointer_motion_relative, LITEST_RELATIVE, LITEST_POINTINGSTICK);
|
||||
litest_add_for_device(pointer_motion_relative_zero, LITEST_MOUSE);
|
||||
|
|
@ -3754,6 +3794,7 @@ TEST_COLLECTION(pointer)
|
|||
litest_add(pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET);
|
||||
litest_add(pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET);
|
||||
litest_add(pointer_scroll_has_axis_invalid, LITEST_WHEEL, LITEST_TABLET);
|
||||
litest_add_ranged(pointer_scroll_with_rotation, LITEST_WHEEL, LITEST_TABLET, &rotation_20deg);
|
||||
|
||||
litest_add(pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A|LITEST_TABLET);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue