summaryrefslogtreecommitdiffstatshomepage
path: root/dot_local/lib
diff options
context:
space:
mode:
authorsommerfeld <sommerfeld@sommerfeld.dev>2026-09-17 15:05:37 +0100
committersommerfeld <sommerfeld@sommerfeld.dev>2026-09-17 15:05:37 +0100
commit9b9b7b6824cb9219f93d1a70414b2412ea7d3585 (patch)
tree96aa6c1f0ede43d6d1e63df186017847345f69fe /dot_local/lib
parentf25d094d0652e8dedff206ca56671b3548f755ff (diff)
downloaddotfiles-9b9b7b6824cb9219f93d1a70414b2412ea7d3585.tar.gz
dotfiles-9b9b7b6824cb9219f93d1a70414b2412ea7d3585.tar.bz2
dotfiles-9b9b7b6824cb9219f93d1a70414b2412ea7d3585.zip
Add GNOME panel status and corporate desktop tools
Diffstat (limited to 'dot_local/lib')
-rw-r--r--dot_local/lib/dotfiles/canonical_desktop.py40
-rw-r--r--dot_local/lib/dotfiles/canonical_panel.py109
2 files changed, 149 insertions, 0 deletions
diff --git a/dot_local/lib/dotfiles/canonical_desktop.py b/dot_local/lib/dotfiles/canonical_desktop.py
index fc9e946..cbda77f 100644
--- a/dot_local/lib/dotfiles/canonical_desktop.py
+++ b/dot_local/lib/dotfiles/canonical_desktop.py
@@ -13,6 +13,9 @@ EXTENSIONS = [
"paperwm@paperwm.github.com",
"copyous@boerdereinar.dev",
"emoji-copy@felipeftn",
+ "Vitals@CoreCoding.com",
+ "corporate-panel@dotfiles",
+ "ubuntu-appindicators@ubuntu.com",
]
@@ -75,6 +78,19 @@ def merge_key(schema: str, key: str, values: list[str], saved: dict) -> None:
def shortcuts(saved: dict) -> None:
+ display_schema = "org.gnome.mutter.keybindings"
+ display_keys = settings_object(display_schema)
+ if display_keys is not None:
+ write_key(
+ display_schema,
+ "switch-monitor",
+ [
+ key
+ for key in display_keys.get_strv("switch-monitor")
+ if key != "<Super>p"
+ ],
+ saved,
+ )
shell = shlex.quote(str(HOME / ".nix-profile/bin/zsh"))
actions = {
"terminal": ("<Super>Return", "/snap/bin/ghostty"),
@@ -138,6 +154,30 @@ def apply_settings(saved: dict) -> None:
write_key(paper, f"move-{direction}", [f"<Super><Shift>{letter}"], saved)
shortcuts(saved)
workspaces(saved)
+ panel(saved)
+
+
+def panel(saved: dict) -> None:
+ schema = "org.gnome.shell.extensions.vitals"
+ monitor = shlex.join(
+ ["/snap/bin/ghostty", "-e", str(HOME / ".nix-profile/bin/htop")]
+ )
+ for key, value in {
+ "hot-sensors": [
+ "_processor_usage_",
+ "__temperature_max__",
+ "_memory_usage_",
+ "__network-rx_max__",
+ "__network-tx_max__",
+ ],
+ "position-in-panel": 2,
+ "update-time": 5,
+ "include-public-ip": False,
+ "monitor-cmd": monitor,
+ }.items():
+ write_key(schema, key, value, saved)
+ write_key("org.gnome.desktop.interface", "show-battery-percentage", True, saved)
+ write_key("org.gnome.desktop.interface", "clock-show-weekday", True, saved)
def workspaces(saved: dict) -> None:
diff --git a/dot_local/lib/dotfiles/canonical_panel.py b/dot_local/lib/dotfiles/canonical_panel.py
new file mode 100644
index 0000000..befc3b6
--- /dev/null
+++ b/dot_local/lib/dotfiles/canonical_panel.py
@@ -0,0 +1,109 @@
+"""Read corporate panel status or open a requested desktop action."""
+
+import json
+import os
+import shlex
+import subprocess
+import sys
+from pathlib import Path
+
+
+def output(*command: str) -> str:
+ return subprocess.check_output(
+ command,
+ text=True,
+ timeout=10,
+ stderr=subprocess.PIPE,
+ env={**os.environ, "LC_ALL": "C"},
+ )
+
+
+def failed_units() -> str:
+ count = 0
+ for scope in ([], ["--user"]):
+ units = json.loads(
+ output(
+ "/usr/bin/systemctl", *scope, "--failed", "--output=json", "--no-pager"
+ )
+ )
+ count += len(units)
+ return f"FAIL {count}"
+
+
+def apt_updates() -> str:
+ lines = output("/usr/bin/apt", "list", "--upgradable").splitlines()
+ count = sum("/" in line.split()[0] for line in lines if line.strip())
+ return f"APT {count}"
+
+
+def displays(root: Path = Path("/sys/class/drm")) -> str:
+ connected = [
+ path
+ for path in root.glob("*/status")
+ if "-eDP-" not in path.parent.name
+ and "-LVDS-" not in path.parent.name
+ and path.read_text().strip() == "connected"
+ ]
+ return f"EXT {len(connected)}"
+
+
+def collect() -> dict:
+ status = {
+ "errors": "",
+ "reboot": "REBOOT" if Path("/run/reboot-required").exists() else "",
+ }
+ for name, label, read in [
+ ("displays", "EXT", displays),
+ ("updates", "APT", apt_updates),
+ ("failed", "FAIL", failed_units),
+ ]:
+ try:
+ status[name] = read()
+ except (OSError, ValueError, subprocess.SubprocessError, RuntimeError) as error:
+ status[name] = f"{label} ?"
+ status["errors"] += f"{label}: {error}\n"
+ return status
+
+
+def terminal(command: str) -> list[str]:
+ shell = str(Path.home() / ".nix-profile/bin/zsh")
+ pause = "; printf '\\nPress Enter to close'; read -r reply"
+ return ["/snap/bin/ghostty", "-e", shell, "-lc", command + pause]
+
+
+def action_command(action: str) -> list[str]:
+ if action == "update":
+ source = output(
+ str(Path.home() / ".nix-profile/bin/chezmoi"), "source-path"
+ ).strip()
+ return terminal(f"cd -- {shlex.quote(source)} && just update")
+ if action == "failed":
+ return terminal("systemctl --failed; systemctl --user --failed")
+ if action == "updates":
+ return terminal("apt list --upgradable; snap refresh --list")
+ if action == "reboot":
+ return terminal("cat /run/reboot-required /run/reboot-required.pkgs")
+ if action == "monitor":
+ return terminal("htop")
+ if action == "audio":
+ return terminal("pulsemixer")
+ if action == "mail":
+ return ["/snap/bin/thunderbird"]
+ if action == "displays":
+ return ["/usr/bin/gnome-control-center", "display"]
+ raise ValueError(f"Unknown panel action: {action}")
+
+
+def main() -> None:
+ if (Path.home() / ".config/dotfiles/role").read_text().strip() != "canonical":
+ raise SystemExit("The panel requires the canonical role.")
+ if sys.argv[1:] == ["status"]:
+ print(json.dumps(collect()))
+ elif len(sys.argv) == 3 and sys.argv[1] == "action":
+ subprocess.Popen(action_command(sys.argv[2]), start_new_session=True)
+ else:
+ raise SystemExit("Use status or action NAME.")
+
+
+if __name__ == "__main__":
+ main()