From 4c82cbd4d0bb6ca51c648256b357a8578450b7ac Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 17 May 2021 16:09:35 +1000 Subject: [PATCH] tools/replay: do not replay key repeat events 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 --- tools/libinput-replay.man | 3 +++ tools/libinput-replay.py | 34 ++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/tools/libinput-replay.man b/tools/libinput-replay.man index 7bca5180..dcae907c 100644 --- a/tools/libinput-replay.man +++ b/tools/libinput-replay.man @@ -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 diff --git a/tools/libinput-replay.py b/tools/libinput-replay.py index 527b9d05..63f662fa 100755 --- a/tools/libinput-replay.py +++ b/tools/libinput-replay.py @@ -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)