[PATCH xf86-input-libinput] Post a motion event after proximity events

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 22 01:46:11 UTC 2017

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.


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
 src/xf86libinput.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 888c8f2..f09f57e 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -1776,8 +1776,8 @@ xf86libinput_apply_area(InputInfoPtr pInfo, double *x, double *y)
 	*y = sy;
-static enum event_handling
-xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
+static void
+xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
 				struct libinput_event_tablet_tool *event)
 	DeviceIntPtr dev = pInfo->dev;
@@ -1787,9 +1787,6 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
 	double value;
 	double x, y;
-	if (xf86libinput_tool_queue_event(event))
-		return EVENT_QUEUED;
 	x = libinput_event_tablet_tool_get_x_transformed(event,
 	y = libinput_event_tablet_tool_get_y_transformed(event,
@@ -1839,13 +1836,23 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
 			xf86IDrvMsg(pInfo, X_ERROR,
 				    "Invalid rotation axis on tool\n");
-			return EVENT_HANDLED;
+			return;
 		valuator_mask_set_double(mask, valuator, value);
 	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);
@@ -1977,6 +1984,13 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
 	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);

More information about the xorg-devel mailing list