From 3f72efebc10b128985040bed40c2f2659ca1b996 Mon Sep 17 00:00:00 2001 From: Rongrong Date: Mon, 25 May 2026 17:50:18 +0800 Subject: [PATCH] rules: uinput: Only sleep if two events are really close to each other Several sleep points exist to serialize keyboard and mouse events. However, these unconditional sleeps hurt the performance as they block the main thread. Postpone sleep until the next event, and skip it if enough time has elapsed. Signed-off-by: Rongrong --- lib/logitech_receiver/diversion.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/logitech_receiver/diversion.py b/lib/logitech_receiver/diversion.py index 7060d6c7..a5d2d358 100644 --- a/lib/logitech_receiver/diversion.py +++ b/lib/logitech_receiver/diversion.py @@ -257,6 +257,22 @@ else: class UInput: def __init__(self): self.udevice = None + self.barrier_until = None + + def _wait_barrier(self): + if self.barrier_until is None: + return + + remainder = self.barrier_until - time.monotonic() + if remainder > 0: + if logger.isEnabledFor(logging.DEBUG): + logger.debug("wait %.3fs due to barrier", remainder) + time.sleep(remainder) + + self.barrier_until = None + + def barrier(self, margin: float): + self.barrier_until = time.monotonic() + margin def setup(self): if self.udevice is not None: @@ -285,8 +301,10 @@ class UInput: logger.warning("uinput write failed: %s", e) def key(self, code, event): # X11 keycode but Solaar event code - if evdev and self.simulate(evdev.ecodes.EV_KEY, code - 8, event): - return True + if evdev: + self._wait_barrier() + if self.simulate(evdev.ecodes.EV_KEY, code - 8, event): + return True logger.warning("no way to simulate key input") def _click(self, button, count): @@ -306,12 +324,14 @@ class UInput: return True def click(self, button, count): + self._wait_barrier() if self._click(button, count): return True logger.warning("no way to simulate mouse click") return False def scroll(self, dx, dy): + self._wait_barrier() success = True if dx: success = self.simulate(evdev.ecodes.EV_REL, evdev.ecodes.REL_HWHEEL, dx) @@ -1210,7 +1230,7 @@ class KeyPress(Action): self.keyDown(self.key_symbols, current) if self.action != DEPRESS: self.keyUp(reversed(self.key_symbols), current) - time.sleep(0.01) + uinput.barrier(0.01) else: logger.warning("no keymap so cannot determine which keycode to send") return None @@ -1249,7 +1269,7 @@ class MouseScroll(Action): logger.info("MouseScroll action: %s %s %s", self.amounts, last_result, amounts) dx, dy = amounts uinput.scroll(dx, dy) - time.sleep(0.01) + uinput.barrier(0.01) return None def data(self): @@ -1288,7 +1308,7 @@ class MouseClick(Action): logger.info(f"MouseClick action: {str(self.count)} {self.button}") if self.button and self.count: uinput.click(buttons[self.button], self.count) - time.sleep(0.01) + uinput.barrier(0.01) return None def data(self):