tools/replay: do not replay key repeat events
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 17 May 2021 06:09:35 +0000 (16:09 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 18 May 2021 23:14:44 +0000 (23:14 +0000)
The kernel emulates key events on its own anyway, replaying key events with
libinput replay as well just duplicates the events. Turning kernel
repeat off is not an option, it  makes the device look different (EV_REP
changes). So let's just not replay those events.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
tools/libinput-replay.man
tools/libinput-replay.py

index 7bca518065ea5263d8b74468097821f29713e62d..dcae907c5786141c9116c678b7a5310978fac494 100644 (file)
@@ -21,6 +21,9 @@ This tool replays events from a recording through the the kernel and is
 independent of libinput. In other words, updating or otherwise changing
 libinput will not alter the output from this tool. libinput itself does not
 need to be in use to replay events.
+.PP
+This tool does not replay kernel-emulated key repeat events (events of type
+\fIEV_KEY\fR with a value of 2).
 .SH LIBINPUT
 .PP
 Part of the
index 527b9d052ee803da043d2849fc4c00e5c317eb45..63f662faa366e82e04964a1543fe62c1b6054e9d 100755 (executable)
@@ -168,6 +168,27 @@ def print_events(devnode, indent, evs):
         )
 
 
+def collect_events(frame):
+    evs = []
+    events_skipped = False
+    for (sec, usec, evtype, evcode, value) in frame:
+        if evtype == libevdev.EV_KEY.value and value == 2:  # key repeat
+            events_skipped = True
+            continue
+
+        e = libevdev.InputEvent(
+            libevdev.evbit(evtype, evcode), value=value, sec=sec, usec=usec
+        )
+        evs.append(e)
+
+    # If we skipped some events and now all we have left is the
+    # SYN_REPORTs, we drop the SYN_REPORTs as well.
+    if events_skipped and all(e for e in evs if e.matches(libevdev.EV_SYN.SYN_REPORT)):
+        return []
+    else:
+        return evs
+
+
 def replay(device, verbose):
     events = fetch(device, "events")
     if events is None:
@@ -191,19 +212,16 @@ def replay(device, verbose):
         except YamlException:
             continue
 
-        (sec, usec, evtype, evcode, value) = evdev[0]
-        evtime = sec + usec / 1e6 + offset
+        evs = collect_events(evdev)
+        if not evs:
+            continue
+
+        evtime = evs[0].sec + evs[0].usec / 1e6 + offset
         now = time.time()
 
         if evtime - now > 150 / 1e6:  # 150 µs error margin
             time.sleep(evtime - now - 150 / 1e6)
 
-        evs = [
-            libevdev.InputEvent(
-                libevdev.evbit(e[2], e[3]), value=e[4], sec=e[0], usec=e[1]
-            )
-            for e in evdev
-        ]
         uinput.send_events(evs)
         if verbose:
             print_events(uinput.devnode, device["__index"], evs)