Fix virtual touchpad scroll events.
1. Correctly configure the uinput device to pass REL_*WHEEL events.
2. Configure the virtual touchpad as a 'rotary encoder', which is
an inputflinger device class originally provided for the G1 scroll
ball. This provides two advantages over the default mouse-wheel
interpretation:
- It works without an associated mouse pointer to determine the
event target.
- It allows for higher resolution through a scale factor (the
scaling here is chosen by experiment to feel no worse than wheel
mode, but might benefit from future adjustment).
There is one accompanying disadvantage: inputflinger only handles
vertical scrolling (REL_WHEEL) and ignores the horizontal axis
(REL_HWHEEL).
Bug: 62632827
Test: manual on sailfish
Change-Id: Ic8edad01796d75e8c94fa20f05a5badb0727a948
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
index ae56bf6..251ed0e 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
@@ -28,20 +28,10 @@
static constexpr int32_t kHeight = 0x10000;
static constexpr int32_t kSlots = 2;
+static constexpr float kScrollScale = 100.0f;
+
int32_t scale_relative_scroll(float x) {
- // Guilty with an explanation, your honor.
- // Ideally we should be able to communicate the full incoming precision
- // to InputFlinger, through the evdev int32_t value, by scaling by a
- // large factor, i.e. 2²³ for IEEE single precision floating point.
- // However, although InputFlinger has |wheelVelocityControlParameters|,
- // those parameters are currently hard coded, with a scale factor of 1.0.
- // The observed evdev value for a physical mouse scroll wheel is usually
- // ±1, with higher values up to ±4 for a very fast spin. So we imitate
- // that. If the incoming value is not actually 0, the resulting magnitude
- // should be at least 1, so that small movements are not lost.
- // Adding IDC configurability of |VelocityControlParameters| may be
- // desirable in the future.
- return copysignf(ceilf(fabs(4.0f * x)), x);
+ return kScrollScale * x;
}
} // anonymous namespace
@@ -82,6 +72,8 @@
touchpad.injector->ConfigureInputProperty(INPUT_PROP_DIRECT);
touchpad.injector->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1);
touchpad.injector->ConfigureAbsSlots(kSlots);
+ touchpad.injector->ConfigureRel(REL_WHEEL);
+ touchpad.injector->ConfigureRel(REL_HWHEEL);
touchpad.injector->ConfigureKey(BTN_TOUCH);
touchpad.injector->ConfigureKey(BTN_BACK);
touchpad.injector->ConfigureEnd();
@@ -192,6 +184,7 @@
touchpad.injector->ResetError();
const int32_t scaled_x = scale_relative_scroll(x);
const int32_t scaled_y = scale_relative_scroll(y);
+ ALOGV("(%f,%f) -> (%" PRId32 ",%" PRId32 ")", x, y, scaled_x, scaled_y);
if (scaled_x) {
touchpad.injector->SendRel(REL_HWHEEL, scaled_x);
}