mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-03-24 09:44:28 +00:00
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>
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user