diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-08-17 09:41:11 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-08-18 13:07:13 +1000 |
commit | 2e5f68754fd5bc4e6b7fa5b95bdd30e2bb4e57fb (patch) | |
tree | f47cc3e630eb791465486c91469baa7d583b4b17 | |
parent | 8fdb2abb6fe0426cbbfeead2c187092a56792557 (diff) |
Restrict wheel emulation to a single axis at a time.
Wheel emulation works for both horizontal and vertical axes. Thus, if a
device doesn't move in perfect straight line, scroll events build up on the
respective other axis.
In some clients, scroll wheel events have specific meanings other than
scrolling (e.g. mplayer). In these clients, erroneous scrolling events come
at a high cost.
Thus, if a scroll wheel event is generated for one axis, reset the inertia
of the other axis to 0, avoiding the buildup of these erroneous scrolling
events.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | src/emuWheel.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/emuWheel.c b/src/emuWheel.c index 421477e..cc23f1d 100644 --- a/src/emuWheel.c +++ b/src/emuWheel.c @@ -54,7 +54,7 @@ static Atom prop_wheel_button = 0; /* Local Funciton Prototypes */ static BOOL EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char *axis_name); -static void EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value); +static int EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value); /* Filter mouse button events */ BOOL @@ -98,7 +98,7 @@ BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv) { EvdevPtr pEvdev = (EvdevPtr)pInfo->private; - WheelAxisPtr pAxis = NULL; + WheelAxisPtr pAxis = NULL, pOtherAxis = NULL; int value = pEv->value; int ms; @@ -117,19 +117,28 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv) switch(pEv->code) { case REL_X: pAxis = &(pEvdev->emulateWheel.X); + pOtherAxis = &(pEvdev->emulateWheel.Y); break; case REL_Y: pAxis = &(pEvdev->emulateWheel.Y); + pOtherAxis = &(pEvdev->emulateWheel.X); break; default: break; } - /* If we found REL_X or REL_Y, emulate a mouse wheel */ + /* If we found REL_X or REL_Y, emulate a mouse wheel. + Reset the inertia of the other axis when a scroll event was sent + to avoid the buildup of erroneous scroll events if the user + doesn't move in a perfectly straight line. + */ if (pAxis) - EvdevWheelEmuInertia(pInfo, pAxis, value); + { + if (EvdevWheelEmuInertia(pInfo, pAxis, value)) + pOtherAxis->traveled_distance = 0; + } /* Eat motion events while emulateWheel button pressed. */ return TRUE; @@ -138,17 +147,20 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv) return FALSE; } -/* Simulate inertia for our emulated mouse wheel */ -static void +/* Simulate inertia for our emulated mouse wheel. + Returns the number of wheel events generated. + */ +static int EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value) { EvdevPtr pEvdev = (EvdevPtr)pInfo->private; int button; int inertia; + int rc = 0; /* if this axis has not been configured, just eat the motion */ if (!axis->up_button) - return; + return rc; axis->traveled_distance += value; @@ -164,7 +176,9 @@ EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value) while(abs(axis->traveled_distance) > pEvdev->emulateWheel.inertia) { axis->traveled_distance -= inertia; EvdevQueueButtonClicks(pInfo, button, 1); + rc++; } + return rc; } /* Handle button mapping here to avoid code duplication, |