Post a motion event after proximity events

This patch splits the meat of xf86libinput_handle_tablet_axis into a helper
function xf86libinput_post_tablet_motion(), to be called right after we send
the proximity in event.

Clients that don't handle proximity (e.g. all XI2 clients) don't see the
coordinates we send along with the proximity events. And, for historical
reasons, they may not look at the coordinates in button events. So a device
that comes into proximity and immediately sends a tip down button event
doesn't send a motion event, causing the client to think the tip down was at
whatever the last known position was (before previous prox-out).

The practical effect is that when a user tries to draw a few dots, they end up
being connected to each other.

https://bugzilla.redhat.com/show_bug.cgi?id=1433755

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2017-03-21 13:13:43 +10:00
parent 153a7fc62f
commit 8bc694595d

View File

@@ -1776,8 +1776,8 @@ xf86libinput_apply_area(InputInfoPtr pInfo, double *x, double *y)
*y = sy; *y = sy;
} }
static enum event_handling static void
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo, xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event) struct libinput_event_tablet_tool *event)
{ {
DeviceIntPtr dev = pInfo->dev; DeviceIntPtr dev = pInfo->dev;
@@ -1787,9 +1787,6 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
double value; double value;
double x, y; double x, y;
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
x = libinput_event_tablet_tool_get_x_transformed(event, x = libinput_event_tablet_tool_get_x_transformed(event,
TABLET_AXIS_MAX); TABLET_AXIS_MAX);
y = libinput_event_tablet_tool_get_y_transformed(event, y = libinput_event_tablet_tool_get_y_transformed(event,
@@ -1839,13 +1836,23 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
default: default:
xf86IDrvMsg(pInfo, X_ERROR, xf86IDrvMsg(pInfo, X_ERROR,
"Invalid rotation axis on tool\n"); "Invalid rotation axis on tool\n");
return EVENT_HANDLED; return;
} }
valuator_mask_set_double(mask, valuator, value); valuator_mask_set_double(mask, valuator, value);
} }
xf86PostMotionEventM(dev, Absolute, mask); xf86PostMotionEventM(dev, Absolute, mask);
}
static enum event_handling
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event)
{
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
xf86libinput_post_tablet_motion(pInfo, event);
return EVENT_HANDLED; return EVENT_HANDLED;
} }
@@ -1977,6 +1984,13 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
xf86PostProximityEventM(pDev, in_prox, mask); xf86PostProximityEventM(pDev, in_prox, mask);
/* We have to send an extra motion event after proximity to make
* sure the client got the updated x/y coordinates, especially if
* they don't handle proximity events (XI2).
*/
if (in_prox)
xf86libinput_post_tablet_motion(pDev->public.devicePrivate, event);
return EVENT_HANDLED; return EVENT_HANDLED;
} }