From 9f89e3a657abfe26d664387723ca112749a2e33e Mon Sep 17 00:00:00 2001 From: tobi-wan-kenobi Date: Sat, 13 Mar 2021 14:09:42 +0100 Subject: [PATCH] [core] make bumblebee more reactive - set default delay to 0 - split input reading into 2 threads - get rid of polling --- bumblebee-status | 80 +++++++++++++++++----------------- bumblebee_status/core/event.py | 7 +++ bumblebee_status/core/input.py | 4 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/bumblebee-status b/bumblebee-status index a0f2fad3..698bcf81 100755 --- a/bumblebee-status +++ b/bumblebee-status @@ -6,7 +6,6 @@ import json import time import signal import socket -import select import logging import threading @@ -39,45 +38,40 @@ class CommandSocket(object): self.__socket.close() os.unlink(self.__name) - -def handle_input(output, config, update_lock): +def process_event(event_line, config, update_lock): + modules = {} + try: + event = json.loads(event_line) + core.input.trigger(event) + if "name" in event: + modules[event["name"]] = True + except ValueError: + pass + + delay = float(config.get("engine.input_delay", 0.0)) + if delay > 0: + time.sleep(delay) + if update_lock.acquire(blocking=False) == True: + core.event.trigger("update", modules.keys(), force=True) + core.event.trigger("draw") + update_lock.release() + +def handle_commands(config, update_lock): with CommandSocket() as cmdsocket: - poll = select.poll() - poll.register(sys.stdin.fileno(), select.POLLIN) - poll.register(cmdsocket, select.POLLIN) - while True: - events = poll.poll() - - modules = {} - for fileno, event in events: - if fileno == cmdsocket.fileno(): - tmp, _ = cmdsocket.accept() - line = tmp.recv(4096).decode() - tmp.close() - logging.debug("socket event {}".format(line)) - else: - line = "[" - while line.startswith("["): - line = sys.stdin.readline().strip(",").strip() - logging.info("input event: {}".format(line)) - try: - event = json.loads(line) - core.input.trigger(event) - if "name" in event: - modules[event["name"]] = True - except ValueError: - pass - - delay = float(config.get("engine.input_delay", 0.2)) - if delay > 0: - time.sleep(delay) - if update_lock.acquire(blocking=False) == True: - core.event.trigger("update", modules.keys(), force=True) - core.event.trigger("draw") - update_lock.release() - - poll.unregister(sys.stdin.fileno()) + tmp, _ = cmdsocket.accept() + line = tmp.recv(4096).decode() + tmp.close() + logging.debug("socket event {}".format(line)) + process_event(line, config, update_lock) + + +def handle_events(config, update_lock): + while True: + line = sys.stdin.readline().strip(",").strip() + if line == "[": continue + logging.info("input event: {}".format(line)) + process_event(line, config, update_lock) def main(): @@ -104,9 +98,13 @@ def main(): core.input.register(None, core.input.WHEEL_DOWN, "i3-msg workspace next_on_output") update_lock = threading.Lock() - input_thread = threading.Thread(target=handle_input, args=(output, config, update_lock, )) - input_thread.daemon = True - input_thread.start() + event_thread = threading.Thread(target=handle_events, args=(config, update_lock, )) + event_thread.daemon = True + event_thread.start() + + cmd_thread = threading.Thread(target=handle_commands, args=(config, update_lock, )) + cmd_thread.daemon = True + cmd_thread.start() def sig_USR1_handler(signum,stack): if update_lock.acquire(blocking=False) == True: diff --git a/bumblebee_status/core/event.py b/bumblebee_status/core/event.py index 8e969f0b..70b6b0c0 100644 --- a/bumblebee_status/core/event.py +++ b/bumblebee_status/core/event.py @@ -8,6 +8,13 @@ def register(event, callback, *args, **kwargs): __callbacks.setdefault(event, []).append(cb) +def register_exclusive(event, callback, *args, **kwargs): + cb = callback + if args or kwargs: + cb = lambda: callback(*args, **kwargs) + + __callbacks[event] = [cb] + def unregister(event): if event in __callbacks: del __callbacks[event] diff --git a/bumblebee_status/core/input.py b/bumblebee_status/core/input.py index 9dbc2a6f..b0d9f232 100644 --- a/bumblebee_status/core/input.py +++ b/bumblebee_status/core/input.py @@ -52,9 +52,9 @@ def register(obj, button=None, cmd=None, wait=False): logging.debug("registering callback {}".format(event_id)) core.event.unregister(event_id) # make sure there's always only one input event if callable(cmd): - core.event.register(event_id, cmd) + core.event.register_exclusive(event_id, cmd) else: - core.event.register(event_id, lambda event: __execute(event, cmd, wait)) + core.event.register_exclusive(event_id, lambda event: __execute(event, cmd, wait)) def trigger(event):