WestonTouchScreenIssues

From Qt Wiki
Jump to navigation Jump to search

Issues with Touch Screen Input when using Weston

Prior to version 1.7 of the Weston compositor touch screen events are incorrectly dispatched in some configurations, rendering Qt unresponsive to touch events.

Workaround

For situations where using a recent version of Weston or switching to the libinput backend is not possible, we provide a patch for Weston's evdev backend. The patch is included in Qt For Device Creation in releases made after 2015-08-20, but for convenience also provided separately below.

Problem Description

Qt relies on touch frame events that indicate discrete sampling windows of touch devices to implement reliable multi touch support. Unfortunately several releases of the Weston reference compositor fail to send out these events correctly.

The issue is present in the Weston evdev input backend until its removal in Weston 1.7. In the libinput backend the same issue is fixed in Weston 1.5. The table below summarizes the situation.

Weston Release Weston Input Backend Incorrect Touch Frame Delivery
Weston 1.4 evdev yes
libinput Backend not available
Weston 1.5 evdev yes
libinput
Weston 1.6 evdev yes
libinput
Weston 1.7 evdev Backend not available
libinput
Weston 1.8 evdev Backend not available
libinput

Patch

From c4633014fff25d32926129a8b028124c6338bb2b Mon Sep 17 00:00:00 2001
From: Louai Al-Khanji <louai.al-khanji@theqtcompany.com>
Date: Wed, 19 Aug 2015 09:04:46 +0300
Subject: [PATCH 1/1] Adapt changes made in libinput/src/evdev.c for touch
 frame emission.

---
 src/evdev.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/evdev.c b/src/evdev.c
index 888dfbd..daa5d72 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -359,12 +359,36 @@ evdev_process_absolute(struct evdev_device *device,
 	}
 }
 
+static inline int
+evdev_need_touch_frame(struct evdev_device *device)
+{
+	if (!(device->seat_caps & EVDEV_SEAT_TOUCH))
+		return 0;
+
+	switch (device->pending_event) {
+	case EVDEV_NONE:
+	case EVDEV_RELATIVE_MOTION:
+		break;
+	case EVDEV_ABSOLUTE_MT_DOWN:
+	case EVDEV_ABSOLUTE_MT_MOTION:
+	case EVDEV_ABSOLUTE_MT_UP:
+	case EVDEV_ABSOLUTE_TOUCH_DOWN:
+	case EVDEV_ABSOLUTE_TOUCH_UP:
+	case EVDEV_ABSOLUTE_MOTION:
+		return 1;
+	}
+
+	return 0;
+}
+
 static void
 fallback_process(struct evdev_dispatch *dispatch,
 		 struct evdev_device *device,
 		 struct input_event *event,
 		 uint32_t time)
 {
+	int need_frame = 0;
+
 	switch (event->type) {
 	case EV_REL:
 		evdev_process_relative(device, event, time);
@@ -376,7 +400,10 @@ fallback_process(struct evdev_dispatch *dispatch,
 		evdev_process_key(device, event, time);
 		break;
 	case EV_SYN:
+		need_frame = evdev_need_touch_frame(device);
 		evdev_flush_pending_event(device, time);
+		if (need_frame)
+			notify_touch_frame(device->seat);
 		break;
 	}
 }
-- 
2.1.4