summaryrefslogtreecommitdiff
path: root/.local
diff options
context:
space:
mode:
authorAndrew Guschin <saintruler@gmail.com>2021-05-10 14:44:07 +0400
committerAndrew Guschin <saintruler@gmail.com>2021-05-10 14:44:07 +0400
commit40ce35bd2f379f2c30e51173752926f8c620ffd6 (patch)
treed8bb4e1651758edd2af52e4b0a4b40c3c0f13c0e /.local
parent2f6db370d4086eca956279ea41cd305b474f9caf (diff)
Changed window manager to bspwm and added custom config for lemonbar
Diffstat (limited to '.local')
-rw-r--r--.local/bin/lemonbar/bargen.py72
-rw-r--r--.local/bin/lemonbar/bspc.py55
-rw-r--r--.local/bin/lemonbar/chain.py59
-rw-r--r--.local/bin/lemonbar/modules/battery.py11
-rw-r--r--.local/bin/lemonbar/modules/clock.py6
-rw-r--r--.local/bin/lemonbar/modules/language.py10
-rw-r--r--.local/bin/lemonbar/modules/updates.py48
-rw-r--r--.local/bin/lemonbar/modules/volume.py93
-rw-r--r--.local/bin/lemonbar/run_lemonbar.sh10
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