diff options
| author | Andrew Guschin <saintruler@gmail.com> | 2021-05-10 14:44:07 +0400 |
|---|---|---|
| committer | Andrew Guschin <saintruler@gmail.com> | 2021-05-10 14:44:07 +0400 |
| commit | 40ce35bd2f379f2c30e51173752926f8c620ffd6 (patch) | |
| tree | d8bb4e1651758edd2af52e4b0a4b40c3c0f13c0e /.local/bin | |
| parent | 2f6db370d4086eca956279ea41cd305b474f9caf (diff) | |
Changed window manager to bspwm and added custom config for lemonbar
Diffstat (limited to '.local/bin')
| -rw-r--r-- | .local/bin/lemonbar/bargen.py | 72 | ||||
| -rw-r--r-- | .local/bin/lemonbar/bspc.py | 55 | ||||
| -rw-r--r-- | .local/bin/lemonbar/chain.py | 59 | ||||
| -rw-r--r-- | .local/bin/lemonbar/modules/battery.py | 11 | ||||
| -rw-r--r-- | .local/bin/lemonbar/modules/clock.py | 6 | ||||
| -rw-r--r-- | .local/bin/lemonbar/modules/language.py | 10 | ||||
| -rw-r--r-- | .local/bin/lemonbar/modules/updates.py | 48 | ||||
| -rw-r--r-- | .local/bin/lemonbar/modules/volume.py | 93 | ||||
| -rw-r--r-- | .local/bin/lemonbar/run_lemonbar.sh | 10 |
9 files changed, 364 insertions, 0 deletions
diff --git a/.local/bin/lemonbar/bargen.py b/.local/bin/lemonbar/bargen.py new file mode 100644 index 0000000..a9d3c4d --- /dev/null +++ b/.local/bin/lemonbar/bargen.py @@ -0,0 +1,72 @@ +from chain import ArrowModuleChain +from modules import volume, battery, updates, language, clock +import bspc + + +def get_desktops_bar(): + bar = [] + focused_bg = idle_fg = urgent_fg = occupied_fg = "#ebdbb2" + focused_fg = idle_bg = "#282828" + urgent_bg = "#cc241d" + occupied_bg = "#928374" + + for i, desktop in enumerate(bspc.get_desktops(), 1): + if desktop.focused: + fg = focused_fg + bg = focused_bg + elif desktop.urgent: + fg = urgent_fg + bg = urgent_bg + elif desktop.occupied: + fg = occupied_fg + bg = occupied_bg + else: + fg = idle_fg + bg = idle_bg + + bar.append({ + "callback": lambda idx=i: str(idx), + "foreground": fg, + "background": bg, + }) + + return bar + + +status_modules = [ + { + "callback": updates.callback, + "foreground": "#ebdbb2", + "background": "#689d6a", + }, + { + "callback": volume.callback, + "foreground": "#ebdbb2", + "background": "#458588", + }, + { + "callback": battery.callback, + "foreground": "#ebdbb2", + "background": "#b16286", + }, + { + "callback": language.callback, + "foreground": "#ebdbb2", + "background": "#98971a", + }, + { + "callback": clock.callback, + "foreground": "#ebdbb2", + "background": "#cc241d", + }, +] + +desktops = ArrowModuleChain(right=True, capped_left=True, capped_right=False) +desktops.extend(*get_desktops_bar()) + +focused_window = bspc.get_focused_window_name() + +status = ArrowModuleChain(right=False, capped_left=False, capped_right=True) +status.extend(*status_modules) + +print(f"%{{l}}{desktops} %{{F#ebdbb2}}{focused_window} %{{r}}{status}%{{B#000000}}") diff --git a/.local/bin/lemonbar/bspc.py b/.local/bin/lemonbar/bspc.py new file mode 100644 index 0000000..f2b3cb2 --- /dev/null +++ b/.local/bin/lemonbar/bspc.py @@ -0,0 +1,55 @@ +from subprocess import run as _run + + +class Desktop: + def __init__(self): + self.id = None + self.name = None + self.focused = False + self.occupied = False + self.urgent = False + + +def run(command): + return _run(command.split(), capture_output=True).stdout.decode().strip() + + +def get_desktops(): + focused = run("bspc query -D -d .focused") + occupied = run("bspc query -D -d .occupied").split("\n") + urgent = run("bspc query -D -d .urgent").split("\n") + + desktops = [] + for desktop_id in run("bspc query -D").split("\n"): + desktop = Desktop() + desktop.id = desktop_id + desktop.name = run(f"bspc query -D -d {desktop.id} --names") + desktop.focused = desktop.id == focused + desktop.occupied = desktop.id in occupied + desktop.urgent = desktop.id in urgent + + desktops.append(desktop) + + return desktops + + +def get_focused_window(): + return run("bspc query -N -n") + + +def cut_name(name): + if len(name) > 70: + return name[:65] + "..." + else: + return name + + +def get_focused_window_name(): + focused = get_focused_window().lower() + for window in run("wmctrl -l").split("\n"): + wid, _, _, name = window.split(maxsplit=3) + if wid.lower() == focused: + return cut_name(name) + return '' + + diff --git a/.local/bin/lemonbar/chain.py b/.local/bin/lemonbar/chain.py new file mode 100644 index 0000000..c825501 --- /dev/null +++ b/.local/bin/lemonbar/chain.py @@ -0,0 +1,59 @@ +class ArrowModuleChain: + def __init__(self, right, background="#000000", capped_left=False, capped_right=False): + self.sep = "\uE0B0" if right else "\uE0B2" + + self.bg = background + self.right = right + + self.chain = [] + self.modules = [] + + self.capped_left = capped_left + self.capped_right = capped_right + + def append(self, module): + if len(self.modules) > 0: + self.chain.pop() + fg = module["background"] + bg = self.modules[-1]["background"] + else: + bg = module["background"] if self.capped_left else self.bg + fg = module["background"] + + if not self.right: + bg, fg = fg, bg + self.chain.append(self.get_sep(bg, fg)) + + bg = module["background"] if self.capped_right else self.bg + fg = module["background"] + + if not self.right: + bg, fg = fg, bg + + self.chain.append(self.get_sep(fg, bg)) + + self.modules.append(module) + + def extend(self, *modules): + for module in modules: + self.append(module) + + def get_sep(self, fg, bg): + return f"%{{F{fg}}}%{{B{bg}}}{self.sep}" + + def __str__(self): + result = [] + for i in range(len(self.modules)): + result.append(self.chain[i]) + + bg = self.modules[i]["background"] + fg = self.modules[i]["foreground"] + text = self.modules[i]["callback"]() + text = f"%{{F{fg}}}%{{B{bg}}} {text} " + result.append(text) + + if len(self.chain) > 0: + result.append(self.chain[-1]) + + return "".join(result) + diff --git a/.local/bin/lemonbar/modules/battery.py b/.local/bin/lemonbar/modules/battery.py new file mode 100644 index 0000000..cb93f03 --- /dev/null +++ b/.local/bin/lemonbar/modules/battery.py @@ -0,0 +1,11 @@ +def read_file(filename): + with open(filename) as f: + return f.read().strip() + +def callback(): + battery = "BAT0" + now = int(read_file(f"/sys/class/power_supply/{battery}/energy_now")) + full = int(read_file(f"/sys/class/power_supply/{battery}/energy_full")) + percent = round(now / full * 100) + return f"BAT: {percent}%" + diff --git a/.local/bin/lemonbar/modules/clock.py b/.local/bin/lemonbar/modules/clock.py new file mode 100644 index 0000000..c4dc713 --- /dev/null +++ b/.local/bin/lemonbar/modules/clock.py @@ -0,0 +1,6 @@ +from time import strftime + + +def callback(): + clock = strftime("%d %b (%a) %H:%M") + return f"CLK: {clock}" diff --git a/.local/bin/lemonbar/modules/language.py b/.local/bin/lemonbar/modules/language.py new file mode 100644 index 0000000..50058c8 --- /dev/null +++ b/.local/bin/lemonbar/modules/language.py @@ -0,0 +1,10 @@ +from subprocess import run as _run + + +def run(command): + return _run(command.split(), capture_output=True).stdout.decode().strip() + + +def callback(): + name = run('xkblayout-state print "%s"').strip('"') + return f"LNG: {name.upper()}" diff --git a/.local/bin/lemonbar/modules/updates.py b/.local/bin/lemonbar/modules/updates.py new file mode 100644 index 0000000..67c8e93 --- /dev/null +++ b/.local/bin/lemonbar/modules/updates.py @@ -0,0 +1,48 @@ +from subprocess import run as _run +from time import time + + +def run(command): + return _run(command.split(), capture_output=True).stdout.decode().strip() + + +def pacman_count(): + cnt = 0 + for line in run('pacman -Qu').split("\n"): + if "[ignored]" not in line: + cnt += 1 + return cnt + + +def yay_count(): + cnt = 0 + for line in run('yay -Qau').split("\n"): + if "[ignored]" not in line: + cnt += 1 + return cnt + + +def callback(): + tmp_file = "/tmp/lemonbar/updates" + try: + with open(tmp_file) as f: + data = f.read().split() + except FileNotFoundError: + data = '' + + try: + timestamp = float(data[0]) + except (ValueError, IndexError): + timestamp = 0 + + if time() - timestamp > 900: + pacman = pacman_count() + aur = yay_count() + with open(tmp_file, "w") as f: + f.write(f"{time()} {pacman} {aur}") + else: + pacman = data[1] + aur = data[2] + + return f"UPD: {pacman}+{aur}" + diff --git a/.local/bin/lemonbar/modules/volume.py b/.local/bin/lemonbar/modules/volume.py new file mode 100644 index 0000000..f911571 --- /dev/null +++ b/.local/bin/lemonbar/modules/volume.py @@ -0,0 +1,93 @@ +from subprocess import run as _run +import re + + +def run(command): + return _run(command.split(), capture_output=True).stdout.decode().strip() + + +def get_default_sink(): + default_name = None + for line in run("pactl info").split("\n"): + key, val = line.split(": ") + if key == "Default Sink": + default_name = val + break + + if default_name is None: + return None + + for sid, sink in get_sinks().items(): + if sink["Name"] == default_name: + return sink + return None + + +def get_sinks(): + SINK, PARAMS, PARAM = 0, 1, 2 + parsing = SINK + + re_param_str = re.compile("(.+?): (.*)") + re_param_list = re.compile("(.+?):") + + current_sink = None + current_param = None + + sinks = {} + for line in run("pactl list sinks").split("\n"): + indent = line.count("\t") + line = line.strip() + + if parsing == SINK: + if line.startswith("Sink"): + n = line.split()[1] + sinks[n] = {} + current_sink = sinks[n] + + parsing = PARAMS + + elif parsing == PARAMS: + if line == '': + parsing = SINK + continue + + match = re_param_str.match(line) + if indent == 1 and match is not None: + name, value = match.groups() + current_param = name + current_sink[name] = value + continue + + match = re_param_list.match(line) + if indent == 1 and match is not None: + name = match.group(1) + current_param = name + current_sink[name] = [] + continue + + value = current_sink[name] + if isinstance(value, str): + current_sink[name] = [value] + + current_sink[name].append(line) + + return sinks + + +def get_sink_volume(sink): + if sink is None: + return "None" + if sink["Mute"] == "yes": + return "Muted" + + match = re.search(r"(\d+?)%", sink["Volume"][0]) + if match is not None: + return f"{match.groups()[0]}%" + + +def callback(): + def_sink = get_default_sink() + vol = get_sink_volume(def_sink) + + return f"VOL: {vol}" + diff --git a/.local/bin/lemonbar/run_lemonbar.sh b/.local/bin/lemonbar/run_lemonbar.sh new file mode 100644 index 0000000..3212fbf --- /dev/null +++ b/.local/bin/lemonbar/run_lemonbar.sh @@ -0,0 +1,10 @@ +fontsize="16" +font="DejaVu Sans Mono:style=Bold,size=${fontsize}" +iconsfont="xos4 Terminess Powerline:size=${fontsize}" + +rm -rf /tmp/lemonbar +mkdir /tmp/lemonbar +while :; do + printf "%s\n" "$(python3 bargen.py)" + sleep 0.5 +done | lemonbar -f "${font}" -f "${iconsfont}" -p |