From e825fe389ebd63470028abd828019840c1170a03 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Tue, 8 Dec 2020 13:08:24 +0200 Subject: [PATCH] libweston/libinput-device: Enable/Set pointer capabilities only on pointer movement Some panels advertise both pointer/touch capabilities but without having real capability of driving a cursor (they're basically touch panels) and use USB as a communication tunnel to transfer/send out input events. As we can't really tell if they're fake or not, only advertise to clients pointer capabilities if we detect movement on the cursor/pointer. We handle it at lower level as that allows to handle the case where removal of a real pointer should also remove the cursor from being displayed on the screen. Signed-off-by: Marius Vlad --- libweston/libinput-device.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/libweston/libinput-device.c b/libweston/libinput-device.c index 9a084cbf..3fd27e91 100644 --- a/libweston/libinput-device.c +++ b/libweston/libinput-device.c @@ -60,6 +60,21 @@ evdev_led_update(struct evdev_device *device, enum weston_led weston_leds) libinput_device_led_update(device->device, leds); } +static void +ensure_pointer_capability(struct libinput_device *libinput_device) +{ + struct evdev_device *device = libinput_device_get_user_data(libinput_device); + struct weston_seat *seat = device->seat; + + if (!libinput_device_has_capability(libinput_device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + if (!(device->seat_caps & EVDEV_SEAT_POINTER)) { + weston_seat_init_pointer(seat); + device->seat_caps |= EVDEV_SEAT_POINTER; + } +} + static void handle_keyboard_key(struct libinput_device *libinput_device, struct libinput_event_keyboard *keyboard_event) @@ -97,6 +112,8 @@ handle_pointer_motion(struct libinput_device *libinput_device, struct timespec time; double dx_unaccel, dy_unaccel; + ensure_pointer_capability(libinput_device); + timespec_from_usec(&time, libinput_event_pointer_get_time_usec(pointer_event)); dx_unaccel = libinput_event_pointer_get_dx_unaccelerated(pointer_event); @@ -129,6 +146,8 @@ handle_pointer_motion_absolute( double x, y; uint32_t width, height; + ensure_pointer_capability(libinput_device); + if (!output) return false; @@ -160,6 +179,8 @@ handle_pointer_button(struct libinput_device *libinput_device, libinput_event_pointer_get_seat_button_count(pointer_event); struct timespec time; + ensure_pointer_capability(libinput_device); + /* Ignore button events that are not seat wide state changes. */ if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED && seat_button_count != 1) || @@ -239,6 +260,8 @@ handle_pointer_axis(struct libinput_device *libinput_device, bool has_vert, has_horiz; struct timespec time; + ensure_pointer_capability(libinput_device); + has_vert = libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); has_horiz = libinput_event_pointer_has_axis(pointer_event, @@ -708,11 +731,7 @@ evdev_device_create(struct libinput_device *libinput_device, weston_seat_init_keyboard(seat, NULL); device->seat_caps |= EVDEV_SEAT_KEYBOARD; } - if (libinput_device_has_capability(libinput_device, - LIBINPUT_DEVICE_CAP_POINTER)) { - weston_seat_init_pointer(seat); - device->seat_caps |= EVDEV_SEAT_POINTER; - } + if (libinput_device_has_capability(libinput_device, LIBINPUT_DEVICE_CAP_TOUCH)) { weston_seat_init_touch(seat);