From: Nandor Han <nandor....@ge.com>

During libinput initialization a list of existing input devices is
retrieved from udev. This can lead to a situation where libinput can
end up processing un-configured devices because of the race generated
by udev events and libinput startup.
Sequence example:
weston - start
udev - device 1 added
weston - get a list of input devices
weston - process device 1 -- undefined behavior
udev - device 1 added - finalized

The problem was found because of incorrect touchscreen association
when in a dual monitor system the secondary touchscreen was
incorrectly associated with output one since udev didn't finish the
device initialization and WL_OUTPUT was missing.

To avoid this situation we skip un-configured devices during libinput
initialization, relying on udev to send events when devices are
fully configured.

Note: due to the peculiarities of udev_device_get_is_initialized(), the
input device is still processed if the call fails. If there are no udev
rules defined for the device, it will never be reported as initialized,
but this is not a problem, because all input devices handled by libinput
must have some udev properties set, therefore they always have rules.

Signed-off-by: Nandor Han <nandor....@ge.com>
[Pekka: change log to debug, unref device]
Signed-off-by: Pekka Paalanen <pekka.paala...@collabora.co.uk>
---
 src/udev-seat.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/udev-seat.c b/src/udev-seat.c
index 6c28b3d2..37d3dcce 100644
--- a/src/udev-seat.c
+++ b/src/udev-seat.c
@@ -150,6 +150,17 @@ udev_input_add_devices(struct udev_input *input, struct 
udev *udev)
                        continue;
                }
 
+               /* Skip unconfigured device. udev will send an event
+                * when device is fully configured  */
+               if (!udev_device_get_is_initialized(device)) {
+                       log_debug(&input->base,
+                                 "%-7s - skip unconfigured input device 
'%s'\n",
+                                 sysname,
+                                 udev_device_get_devnode(device));
+                       udev_device_unref(device);
+                       continue;
+               }
+
                if (device_added(device, input, NULL) < 0) {
                        udev_device_unref(device);
                        udev_enumerate_unref(e);
-- 
2.16.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to