If a physical button is down but releasing said button doesn't actually
release it, we loop endlessly. Detect that and log a bug instead.

Reproducible: trigger a tap-n-drag on a touchpad device, then remove it.

Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 src/evdev.c | 47 ++++++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 4ce9250..435bc52 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -2330,6 +2330,9 @@ release_pressed_keys(struct evdev_device *device)
        for (code = 0; code < KEY_CNT; code++) {
                int count = get_key_down_count(device, code);
 
+               if (count == 0)
+                       continue;
+
                if (count > 1) {
                        log_bug_libinput(libinput,
                                         "Key %d is down %d times.\n",
@@ -2337,25 +2340,31 @@ release_pressed_keys(struct evdev_device *device)
                                         count);
                }
 
-               while (get_key_down_count(device, code) > 0) {
-                       switch (get_key_type(code)) {
-                       case EVDEV_KEY_TYPE_NONE:
-                               break;
-                       case EVDEV_KEY_TYPE_KEY:
-                               evdev_keyboard_notify_key(
-                                       device,
-                                       time,
-                                       code,
-                                       LIBINPUT_KEY_STATE_RELEASED);
-                               break;
-                       case EVDEV_KEY_TYPE_BUTTON:
-                               evdev_pointer_notify_physical_button(
-                                       device,
-                                       time,
-                                       evdev_to_left_handed(device, code),
-                                       LIBINPUT_BUTTON_STATE_RELEASED);
-                               break;
-                       }
+               switch (get_key_type(code)) {
+               case EVDEV_KEY_TYPE_NONE:
+                       break;
+               case EVDEV_KEY_TYPE_KEY:
+                       evdev_keyboard_notify_key(
+                               device,
+                               time,
+                               code,
+                               LIBINPUT_KEY_STATE_RELEASED);
+                       break;
+               case EVDEV_KEY_TYPE_BUTTON:
+                       evdev_pointer_notify_physical_button(
+                               device,
+                               time,
+                               evdev_to_left_handed(device, code),
+                               LIBINPUT_BUTTON_STATE_RELEASED);
+                       break;
+               }
+
+               count = get_key_down_count(device, code);
+               if (count != 0) {
+                       log_bug_libinput(libinput,
+                                        "Releasing key %d failed.\n",
+                                        code);
+                       break;
                }
        }
 }
-- 
2.3.5

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

Reply via email to