ScalingFilterInterpreter: Special-case small mice moves
When using mice, it's frustrating when moving one device pixel moves
the cursor > 1 pixels on the screen. This CL avoids this problem by
looking for the special case of exactly 1 device pixel move, then
reducing the motion to just 1 pixel of motion.
We actually go a little under 1 pixel because it will be increased on
external displays later in the stack.
BUG=chromium:412864
TEST=logitech-t620/low_dpi_move regression test
Change-Id: I822237cb4acec30dd7e1e78d6e15e5cc9b8e2543
Reviewed-on: https://chromium-review.googlesource.com/217496
Reviewed-by: Charles Mooney <charliemooney@chromium.org>
Tested-by: Andrew de los Reyes <adlr@chromium.org>
Commit-Queue: Andrew de los Reyes <adlr@chromium.org>
diff --git a/src/scaling_filter_interpreter.cc b/src/scaling_filter_interpreter.cc
index e5ace57..e24cdfb 100755
--- a/src/scaling_filter_interpreter.cc
+++ b/src/scaling_filter_interpreter.cc
@@ -201,12 +201,38 @@
void ScalingFilterInterpreter::ConsumeGesture(const Gesture& gs) {
Gesture copy = gs;
switch (copy.type) {
- case kGestureTypeMove:
+ case kGestureTypeMove: {
+ int original_rel_x =
+ copy.details.move.ordinal_dx * mouse_cpi_.val_ / 25.4;
+ int original_rel_y =
+ copy.details.move.ordinal_dy * mouse_cpi_.val_ / 25.4;
copy.details.move.dx *= screen_x_scale_;
copy.details.move.dy *= screen_y_scale_;
copy.details.move.ordinal_dx *= screen_x_scale_;
copy.details.move.ordinal_dy *= screen_y_scale_;
+ // Special case of motion: if a mouse move of 1 device unit
+ // (rel_[xy] == 1) would move the cursor on the screen > 1
+ // pixel, force it to just one pixel. This prevents low-DPI mice
+ // from jumping 2 pixels at a time when doing slow moves.
+ // Note, we use 1 / 1.2 = 0.8333 instead of 1 for the number of
+ // screen pixels, as external monitors get a 20% distance boost.
+ // Mice are most commonly used w/ external displays.
+ if (device_mouse_.val_ &&
+ ((original_rel_x == 0) != (original_rel_y == 0))) {
+ const double kMinPixels = 1.0 / 1.2;
+ if (fabs(copy.details.move.dx) > kMinPixels &&
+ abs(original_rel_x) == 1) {
+ copy.details.move.dx = copy.details.move.ordinal_dx =
+ copy.details.move.dx > 0.0 ? kMinPixels : -kMinPixels;
+ }
+ if (fabs(copy.details.move.dy) > kMinPixels &&
+ abs(original_rel_y) == 1) {
+ copy.details.move.dy = copy.details.move.ordinal_dy =
+ copy.details.move.dy > 0.0 ? kMinPixels : -kMinPixels;
+ }
+ }
break;
+ }
case kGestureTypeScroll:
if (devclass_ != GESTURES_DEVCLASS_MOUSE) {
copy.details.scroll.dx *= screen_x_scale_;