[core] make bumblebee more reactive

- set default delay to 0
- split input reading into 2 threads
- get rid of polling
This commit is contained in:
tobi-wan-kenobi 2021-03-13 14:09:42 +01:00
parent 868502d62e
commit 9f89e3a657
3 changed files with 45 additions and 40 deletions

View file

@ -6,7 +6,6 @@ import json
import time import time
import signal import signal
import socket import socket
import select
import logging import logging
import threading import threading
@ -39,37 +38,17 @@ class CommandSocket(object):
self.__socket.close() self.__socket.close()
os.unlink(self.__name) os.unlink(self.__name)
def process_event(event_line, config, update_lock):
def handle_input(output, 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 = {} 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: try:
event = json.loads(line) event = json.loads(event_line)
core.input.trigger(event) core.input.trigger(event)
if "name" in event: if "name" in event:
modules[event["name"]] = True modules[event["name"]] = True
except ValueError: except ValueError:
pass pass
delay = float(config.get("engine.input_delay", 0.2)) delay = float(config.get("engine.input_delay", 0.0))
if delay > 0: if delay > 0:
time.sleep(delay) time.sleep(delay)
if update_lock.acquire(blocking=False) == True: if update_lock.acquire(blocking=False) == True:
@ -77,7 +56,22 @@ def handle_input(output, config, update_lock):
core.event.trigger("draw") core.event.trigger("draw")
update_lock.release() update_lock.release()
poll.unregister(sys.stdin.fileno()) def handle_commands(config, update_lock):
with CommandSocket() as cmdsocket:
while True:
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(): def main():
@ -104,9 +98,13 @@ def main():
core.input.register(None, core.input.WHEEL_DOWN, "i3-msg workspace next_on_output") core.input.register(None, core.input.WHEEL_DOWN, "i3-msg workspace next_on_output")
update_lock = threading.Lock() update_lock = threading.Lock()
input_thread = threading.Thread(target=handle_input, args=(output, config, update_lock, )) event_thread = threading.Thread(target=handle_events, args=(config, update_lock, ))
input_thread.daemon = True event_thread.daemon = True
input_thread.start() 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): def sig_USR1_handler(signum,stack):
if update_lock.acquire(blocking=False) == True: if update_lock.acquire(blocking=False) == True:

View file

@ -8,6 +8,13 @@ def register(event, callback, *args, **kwargs):
__callbacks.setdefault(event, []).append(cb) __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): def unregister(event):
if event in __callbacks: if event in __callbacks:
del __callbacks[event] del __callbacks[event]

View file

@ -52,9 +52,9 @@ def register(obj, button=None, cmd=None, wait=False):
logging.debug("registering callback {}".format(event_id)) logging.debug("registering callback {}".format(event_id))
core.event.unregister(event_id) # make sure there's always only one input event core.event.unregister(event_id) # make sure there's always only one input event
if callable(cmd): if callable(cmd):
core.event.register(event_id, cmd) core.event.register_exclusive(event_id, cmd)
else: 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): def trigger(event):