2020-10-26 08:28:55 +01:00
|
|
|
#!/usr/bin/env python3
|
2016-12-04 08:37:01 +01:00
|
|
|
|
2020-05-01 09:41:06 +02:00
|
|
|
import os
|
2016-12-04 08:37:01 +01:00
|
|
|
import sys
|
2020-02-08 13:56:52 +01:00
|
|
|
import json
|
2020-05-03 11:32:38 +02:00
|
|
|
import time
|
2020-08-11 01:45:13 +02:00
|
|
|
import signal
|
2020-05-02 09:41:41 +02:00
|
|
|
import socket
|
2020-02-08 13:56:52 +01:00
|
|
|
import logging
|
|
|
|
import threading
|
|
|
|
|
2020-05-09 21:22:00 +02:00
|
|
|
import bumblebee_status.discover
|
2020-05-14 20:36:01 +02:00
|
|
|
|
2020-05-09 21:22:00 +02:00
|
|
|
bumblebee_status.discover.discover()
|
|
|
|
|
2020-01-19 15:36:52 +01:00
|
|
|
import core.config
|
2020-01-19 13:29:34 +01:00
|
|
|
import core.output
|
2020-02-01 21:37:38 +01:00
|
|
|
import core.module
|
2020-02-08 13:56:52 +01:00
|
|
|
import core.input
|
2020-02-16 14:30:45 +01:00
|
|
|
import core.event
|
2020-02-08 13:56:52 +01:00
|
|
|
|
2020-06-23 15:51:14 +02:00
|
|
|
import util.format
|
2020-05-03 11:15:52 +02:00
|
|
|
|
2020-06-04 20:30:48 +02:00
|
|
|
started = False
|
|
|
|
|
2020-05-02 09:41:41 +02:00
|
|
|
class CommandSocket(object):
|
|
|
|
def __init__(self):
|
2020-05-03 11:15:52 +02:00
|
|
|
self.__name = "/tmp/.bumblebee-status.{}".format(os.getpid())
|
2020-05-02 09:41:41 +02:00
|
|
|
self.__socket = None
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
self.__socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
|
|
self.__socket.bind(self.__name)
|
|
|
|
self.__socket.listen(5)
|
|
|
|
return self.__socket
|
|
|
|
|
|
|
|
def __exit__(self, type, value, traceback):
|
|
|
|
self.__socket.close()
|
|
|
|
os.unlink(self.__name)
|
|
|
|
|
2021-03-13 14:09:42 +01:00
|
|
|
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):
|
2020-05-02 09:41:41 +02:00
|
|
|
with CommandSocket() as cmdsocket:
|
|
|
|
while True:
|
2021-03-13 14:09:42 +01:00
|
|
|
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:
|
2023-05-11 08:45:03 +02:00
|
|
|
try:
|
|
|
|
line = sys.stdin.readline().strip(",").strip()
|
|
|
|
if line == "[": continue
|
|
|
|
logging.info("input event: {}".format(line))
|
|
|
|
process_event(line, config, update_lock)
|
|
|
|
except Exception as e:
|
|
|
|
logging.error(e)
|
2017-09-16 12:22:20 +02:00
|
|
|
|
2020-05-03 11:15:52 +02:00
|
|
|
|
2016-12-04 08:37:01 +01:00
|
|
|
def main():
|
2022-09-09 20:58:59 +02:00
|
|
|
global started
|
|
|
|
|
2020-01-19 15:36:52 +01:00
|
|
|
config = core.config.Config(sys.argv[1:])
|
2020-05-01 09:41:06 +02:00
|
|
|
level = logging.DEBUG if config.debug() else logging.ERROR
|
|
|
|
if config.logfile():
|
|
|
|
logging.basicConfig(
|
|
|
|
level=level,
|
|
|
|
format="[%(asctime)s] %(module)-16s %(levelname)-8s %(message)s",
|
2020-05-03 11:15:52 +02:00
|
|
|
filename=os.path.abspath(os.path.expanduser(config.logfile())),
|
2020-05-01 09:41:06 +02:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
logging.basicConfig(
|
|
|
|
level=level,
|
|
|
|
format="[%(asctime)s] %(module)-16s %(levelname)-8s %(message)s",
|
2020-05-03 11:15:52 +02:00
|
|
|
stream=sys.stderr,
|
2020-05-01 09:41:06 +02:00
|
|
|
)
|
|
|
|
|
2020-02-09 13:46:56 +01:00
|
|
|
theme = core.theme.Theme(config.theme(), config.iconset())
|
2020-03-01 14:08:16 +01:00
|
|
|
output = core.output.i3(theme, config)
|
2020-01-19 13:29:34 +01:00
|
|
|
modules = []
|
2020-02-08 13:56:52 +01:00
|
|
|
|
2020-05-03 11:15:52 +02:00
|
|
|
core.input.register(None, core.input.WHEEL_UP, "i3-msg workspace prev_on_output")
|
|
|
|
core.input.register(None, core.input.WHEEL_DOWN, "i3-msg workspace next_on_output")
|
2020-05-02 13:54:45 +02:00
|
|
|
|
2022-09-09 20:58:59 +02:00
|
|
|
core.event.trigger("start")
|
2022-11-26 10:11:51 +01:00
|
|
|
started = True
|
2022-09-09 20:58:59 +02:00
|
|
|
|
2020-06-23 20:20:36 +02:00
|
|
|
update_lock = threading.Lock()
|
2021-03-13 14:09:42 +01:00
|
|
|
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()
|
2020-02-08 13:56:52 +01:00
|
|
|
|
2020-08-11 01:45:13 +02:00
|
|
|
def sig_USR1_handler(signum,stack):
|
|
|
|
if update_lock.acquire(blocking=False) == True:
|
2020-08-28 17:14:05 +02:00
|
|
|
core.event.trigger("update", force=True)
|
2020-08-11 01:45:13 +02:00
|
|
|
core.event.trigger("draw")
|
|
|
|
update_lock.release()
|
|
|
|
|
2020-05-01 09:41:06 +02:00
|
|
|
if config.debug():
|
2020-05-03 11:15:52 +02:00
|
|
|
modules.append(core.module.load("debug", config, theme))
|
2020-05-01 09:41:06 +02:00
|
|
|
|
2020-01-19 15:36:52 +01:00
|
|
|
for module in config.modules():
|
2020-04-26 16:40:48 +02:00
|
|
|
modules.append(core.module.load(module, config, theme))
|
2020-05-15 19:59:13 +02:00
|
|
|
modules[-1].register_callbacks()
|
2020-05-01 15:17:55 +02:00
|
|
|
|
|
|
|
if config.reverse():
|
|
|
|
modules.reverse()
|
|
|
|
|
2020-02-02 14:18:13 +01:00
|
|
|
output.modules(modules)
|
2020-06-23 15:51:14 +02:00
|
|
|
|
|
|
|
if util.format.asbool(config.get("engine.collapsible", True)) == True:
|
|
|
|
core.input.register(None, core.input.MIDDLE_MOUSE, output.toggle_minimize)
|
|
|
|
|
2020-08-11 01:45:13 +02:00
|
|
|
signal.signal(10, sig_USR1_handler)
|
2020-01-19 13:29:34 +01:00
|
|
|
while True:
|
2020-06-23 20:20:36 +02:00
|
|
|
if update_lock.acquire(blocking=False) == True:
|
|
|
|
core.event.trigger("update")
|
|
|
|
core.event.trigger("draw")
|
|
|
|
update_lock.release()
|
2020-01-26 13:31:20 +01:00
|
|
|
output.wait(config.interval())
|
2020-05-03 11:15:52 +02:00
|
|
|
core.event.trigger("stop")
|
|
|
|
|
2016-12-09 19:29:16 +01:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2020-02-16 13:50:15 +01:00
|
|
|
try:
|
2020-06-04 20:30:48 +02:00
|
|
|
if sys.version_info.major < 3:
|
|
|
|
raise Exception("at least Python 3.4 required (Python 2.x not supported)")
|
2020-02-16 13:50:15 +01:00
|
|
|
main()
|
|
|
|
except Exception as e:
|
2020-05-03 11:32:38 +02:00
|
|
|
# really basic errors -> make sure these are shown in the status bar by minimal config
|
2022-11-27 09:46:55 +01:00
|
|
|
logging.exception(e)
|
2020-06-04 20:30:48 +02:00
|
|
|
if not started:
|
|
|
|
print("{\"version\":1}")
|
|
|
|
print("[")
|
2020-05-03 11:32:38 +02:00
|
|
|
while True:
|
2020-05-04 20:12:02 +02:00
|
|
|
sys.stdout.write(
|
|
|
|
json.dumps(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"full_text": " {} ".format(e),
|
|
|
|
"background": "#ff0000",
|
|
|
|
"color": "#ffffff",
|
|
|
|
"name": "error",
|
|
|
|
"instance": "the-only-one",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
2020-05-03 11:32:38 +02:00
|
|
|
sys.stdout.write(",\n")
|
|
|
|
sys.stdout.flush()
|
|
|
|
time.sleep(5)
|
2016-12-04 08:37:01 +01:00
|
|
|
|
|
|
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|