Merge branch 'master' of git://github.com/tobi-wan-kenobi/bumblebee-status

This commit is contained in:
Max Pivo 2020-02-27 12:20:02 -08:00
commit 4fdba0be19
13 changed files with 167 additions and 42 deletions

View file

@ -69,6 +69,7 @@ bar {
```
# Documentation
See [the wiki](https://github.com/tobi-wan-kenobi/bumblebee-status/wiki) for documentation.
See [FAQ](https://github.com/tobi-wan-kenobi/bumblebee-status/wiki/FAQ) for, well, FAQs.
@ -79,6 +80,14 @@ Other resources:
* [How to write a theme](https://github.com/tobi-wan-kenobi/bumblebee-status/wiki/How-to-write-a-theme)
* [How to write a module](https://github.com/tobi-wan-kenobi/bumblebee-status/wiki/How-to-write-a-module)
User contributions:
[@somospocos:bumblebee-status-contrib](https://github.com/somospocos/bumblebee-status-contrib): Collected resources and useful tricks by @somospocos
[@somospocos:bumblebee-bridge-dwm](https://github.com/somospocos/bumblebee-bridge-dwm): Bridge bumblebee-status output into dwm status bar
[@somospocos:bumblebee-bridge-dzen2](https://github.com/somospocos/bumblebee-bridge-dzen2): Bridge bumblebee-status output into dzen2
# Installation
```
$ git clone git://github.com/tobi-wan-kenobi/bumblebee-status
@ -183,6 +192,25 @@ For example:
`$ bumblebee-status -p disk.left-click="nautilus {instance}"`
Advanced usage:
You can also "programmatically" trigger click events like this:
```
$ bumblebee-ctl --button <button> --id <ID of the widget> --module <name of the module>
```
For that to work, you need to know the ID of the widget - this can be configured by adding the `<name>.id` parameter - it's a comma-separated list with one entry per widget (for multi-widget modules).
Example:
```
$ bumblebee-status -m cmus -p cmus.id="prev,main,next,shuffle,repeat"
# to "simulate" a left-click on "next":
$ bumblebee-ctl --button left-mouse --module cmus --id next
```
For a full synopsis, please see `bumblebee-ctl --help`.
## Errors
If errors occur, you should see them in the i3bar itself. If that does not work, or you need more information for troubleshooting, you can activate a debug log using the `-d` or `--debug` switch:
@ -235,6 +263,8 @@ Modules and commandline utilities are only required for modules, the core itself
* zpool (for module 'zpool')
* progress (for module 'progress')
* i3exit (for module 'system')
* dunst (for module 'dunst')
* hddtemp (for module 'hddtemp')
# Examples
Here are some screenshots for all themes that currently exist:

37
bumblebee-ctl Executable file
View file

@ -0,0 +1,37 @@
#!/usr/bin/env python
import argparse
import json
import glob
import socket
button = {
'left-mouse': 1,
'middle-mouse': 2,
'right-mouse': 3,
'wheel-up': 4,
'wheel-down': 5,
}
def main():
parser = argparse.ArgumentParser(description='send commands to bumblebee-status')
parser.add_argument('-b', '--button', choices=['left-mouse', 'right-mouse', 'middle-mouse', 'wheel-up', 'wheel-down'], help='button to emulate', default='left-mouse')
parser.add_argument('-i', '--id', help='ID of widget to trigger', required=True)
parser.add_argument('-m', '--module', help='name of the module to trigger', required=True)
args = parser.parse_args()
for f in glob.glob('/tmp/.bumblebee-status.*'):
print('accessing {}'.format(f))
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(f)
s.sendall(json.dumps({
'name': args.module,
'instance': args.id,
'button': button[args.button],
}).encode('ascii'))
if __name__ == "__main__":
main()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -67,7 +67,9 @@ def main():
import time
while True:
output.begin()
error = bumblebee.modules.error.Module(engine, config)
error = bumblebee.modules.error.Module(engine, {
"config": config, "name": "error"
})
error.set("exception occurred: {} in {}".format(e, module))
widget = error.widgets()[0]
widget.link_module(error)

View file

@ -295,8 +295,15 @@ class Engine(object):
self._current_module = module
module.update_wrapper(module.widgets())
if module.error is None:
widget_ids = []
if module.parameter('id'):
widget_ids = module.parameter('id').split(',')
idx = 0
for widget in module.widgets():
widget.link_module(module)
if idx < len(widget_ids):
widget.id = widget_ids[idx]
idx = idx + 1
self._output.draw(widget=widget, module=module, engine=self)
else:
self._output.draw(widget=module.errorWidget(), module=module, engine=self)

View file

@ -1,9 +1,11 @@
"""Input classes"""
import os
import sys
import json
import uuid
import time
import socket
import select
import logging
import threading
@ -23,10 +25,28 @@ def is_terminated():
return True
return False
class CommandSocket(object):
def __init__(self):
self._name = "/tmp/.bumblebee-status.{}".format(os.getpid())
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)
def read_input(inp):
"""Read i3bar input and execute callbacks"""
with CommandSocket() as cmdsocket:
poll = select.poll()
poll.register(sys.stdin.fileno(), select.POLLIN)
poll.register(sys.stdin, select.POLLIN)
poll.register(cmdsocket, select.POLLIN)
log.debug("starting click event processing")
while inp.running:
if is_terminated():
@ -37,6 +57,12 @@ def read_input(inp):
except Exception:
continue
for fileno, event in events:
if fileno == cmdsocket.fileno():
tmp, _ = cmdsocket.accept()
line = tmp.recv(4096).decode()
tmp.close()
else:
line = "["
while line.startswith("["):
line = sys.stdin.readline().strip(",").strip()

View file

@ -240,7 +240,7 @@ class Module(bumblebee.engine.Module):
def state(self, widget):
state = []
capacity = widget.get("capacity")
capacity = widget.get("capacity", -1)
if capacity < 0:
return ["critical", "unknown"]

View file

@ -91,17 +91,16 @@ class Module(bumblebee.engine.Module):
def cpuload(self, _):
return "{}%".format(self._cpuload)
@staticmethod
def add_color(bar):
def add_color(self, bar):
"""add color as pango markup to a bar"""
if bar in ["", ""]:
color = "green"
color = self.theme().color("green", "green")
elif bar in ["", ""]:
color = "yellow"
color = self.theme().color("yellow", "yellow")
elif bar in ["", ""]:
color = "orange"
color = self.theme().color("orange", "orange")
elif bar in ["", ""]:
color = "red"
color = self.theme().color("red", "red")
colored_bar = "<span foreground='{}'>{}</span>".format(color, bar)
return colored_bar

View file

@ -142,12 +142,12 @@ class Module(bumblebee.engine.Module):
vol, bumblebee.output.hbar(float(self._left)))
return vol
else:
vol = "{}%/{}%".format(self._left, self._right)
if self._showbars:
vol = "{} {}{}".format(
vol,
bumblebee.output.hbar(float(self._left)),
bumblebee.output.hbar(float(self._right)))
vol = "{}%/{}%".format(self._left, self._right)
return vol
def update(self, widgets):

View file

@ -18,6 +18,7 @@ import logging
import bumblebee.input
import bumblebee.output
import bumblebee.engine
import bumblebee.popup_v2
import functools
class Module(bumblebee.engine.Module):
@ -76,7 +77,7 @@ class Module(bumblebee.engine.Module):
try:
bumblebee.util.execute("nmcli c up \"{vpn}\""
.format(vpn=self._connected_vpn_profile))
.format(vpn=self._selected_vpn_profile))
self._connected_vpn_profile = name
except Exception as e:
logging.exception("Couldn't establish VPN connection")

View file

@ -72,6 +72,12 @@ def scrollable(func):
if width < 0:
return text
if len(text) <= width:
# do alignment
align = module.parameter("theme.align", "left")
if align == "right":
text = "{:>{}}".format(text, width)
if align == "center":
text = "{:^{}}".format(text, width)
return text
# we need to shorten

View file

@ -186,9 +186,14 @@ class Theme(object):
result[key] = colors[field][key]
return result
def color(self, color_name, default=None):
return self._colorset.get(color_name, default)
def _load_colors(self, name):
"""Load colors for a theme"""
try:
if isinstance(name, dict):
return name
if name.lower() == "wal":
return self._load_wal_colors()
except Exception as err:
@ -285,7 +290,7 @@ class Theme(object):
if isinstance(value, (dict, list)):
return value
return self._colorset.get(value, value)
return self.color(value, value)
# algorithm copied from
# http://blog.impressiver.com/post/31434674390/deep-merge-multiple-python-dicts

View file

@ -1,13 +1,19 @@
{
"icons": [ "paxy97", "awesome-fonts" ],
"colors": [{
"fg0": "#fbf1c7",
"bg0_h": "#1d2021",
"yellow": "#d79921",
"red": "#cc241d"
}],
"defaults": {
"warning": {
"fg": "#1d2021",
"bg": "#d79921"
"fg": "bg0_h",
"bg": "yellow"
},
"critical": {
"fg": "#fbf1c7",
"bg": "#cc241d"
"fg": "fg0",
"bg": "red"
},
"default-separators": false,
"separator-block-width": 0

View file

@ -1,5 +1,11 @@
{
"icons": [ "awesome-fonts" ],
"colors": [{
"red": "#BF616A",
"orange": "#D08770",
"yellow": "#EBCB8B",
"green": "#A3BE8C"
}],
"defaults": {
"separator-block-width": 0,
"warning": {