nixos-config/users/simon/modules/sway/waybar.nix

318 lines
10 KiB
Nix
Raw Normal View History

{ config, lib, nixosConfig, pkgs, ... }:
let
inherit ((import ../common.nix).colorschemes) solarized;
watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" ''
${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \
| ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \
| ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end'
'';
toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" ''
if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then
${pkgs.systemd}/bin/systemctl --user stop ${unit}
else
${pkgs.systemd}/bin/systemctl --user start ${unit}
fi
'';
# for fine-grained control over spacing
thinsp = " ";
in
{
# home-managers waybar module performs additional checks that are overly strict
xdg.configFile."waybar/config".text = lib.generators.toJSON { } {
layer = "top";
position = "top";
height = 24;
modules-center = [ ];
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-right = [
"tray"
"custom/screencast"
"custom/redshift"
"idle_inhibitor"
"backlight"
"mpd"
"pulseaudio"
"network"
"custom/vpn"
"memory"
"cpu"
"temperature"
"battery"
"clock"
2021-07-17 16:13:45 +02:00
"custom/calendar"
"custom/notification"
];
"sway/workspaces" = {
disable-scroll = true;
};
"sway/mode" = {
format = "{}";
};
tray = {
spacing = 5;
};
"custom/redshift" = {
exec = watchUserUnitState
"gammastep"
{ class = "active"; }
{ class = "inactive"; };
on-click = toggleUserUnitState "gammastep";
return-type = "json";
2023-05-30 14:03:12 +02:00
format = "󰌵";
tooltip = false;
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
2023-05-30 14:03:12 +02:00
activated = "󰈈 ";
deactivated = "󰈉 ";
};
};
"custom/screencast" = {
exec = pkgs.writeScript "screencast-monitor" /* python */ ''
#!${pkgs.python3}/bin/python3
import subprocess
import sys
active_outputs = 0
with subprocess.Popen(
["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"],
stdout=subprocess.PIPE,
text=True,
) as proc:
for line in proc.stdout:
action = line.split(" ")[0]
if action == "=" or action == "+":
active_outputs += 1
elif action == "-":
active_outputs -= 1
else:
print(f"Invalid action {action} (in line {line})", file=sys.stderr)
if active_outputs > 0:
2023-05-30 14:03:12 +02:00
print("󰄘 ")
else:
print()
sys.stdout.flush()
'';
format = "{}";
tooltip = false;
};
backlight = {
format = "{percent}% {icon}";
2023-05-30 14:03:12 +02:00
format-icons = [ "󰃚 " "󰃛 " "󰃜 " "󰃝 " "󰃞 " "󰃟 " "󰃠 " ];
on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +5%";
on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 5%-";
};
mpd = {
server = config.services.mpd.network.listenAddress;
2023-05-30 14:03:12 +02:00
format = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 󰎈";
format-disconnected = "Disconnected 󰎊";
format-stopped = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 󰓛";
unknown-tag = "N/A";
interval = 2;
tooltip-format = "MPD (connected)";
tooltip-format-disconnected = "MPD (disconnected)";
# FIXME remove this once waybar fixes the regression (https://github.com/Alexays/Waybar/issues/1778)
on-click = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} toggle";
on-click-right = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} stop";
on-scroll-up = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume -2";
title-len = 48;
artist-len = 24;
consume-icons = {
2023-05-30 14:03:12 +02:00
on = "󰆐 ";
};
random-icons = {
2023-05-30 14:03:12 +02:00
off = "󰒞 ";
on = "󰒝 ";
};
repeat-icons = {
2023-05-30 14:03:12 +02:00
on = "󰑖 ";
};
single-icons = {
2023-05-30 14:03:12 +02:00
on = "󰑘 ";
};
state-icons = {
2023-05-30 14:03:12 +02:00
paused = "󰏤";
playing = "󰐊";
};
};
pulseaudio = {
format = "{volume}% {icon} {format_source}";
2023-05-30 14:03:12 +02:00
format-bluetooth = "{volume}% {icon}󰂯 {format_source}";
format-bluetooth-muted = "󰝟 {icon}󰂯 {format_source}";
format-muted = "󰝟 {format_source}";
format-source = "{volume}% 󰍬${thinsp}";
format-source-muted = "󰍭${thinsp}";
format-icons = {
2023-05-30 14:03:12 +02:00
car = "󰄋 ";
default = [ "󰕿" "󰖀" "󰕾" ];
hands-free = "󰋎 ";
headphone = "󰋋 ";
headset = "󰋎 ";
phone = "󰏲 ";
portable = "󰏲 ";
};
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
on-click-right = "${pkgs.unstable.helvum}/bin/helvum";
};
network = {
2023-05-30 14:03:12 +02:00
format-wifi = "{essid} ({signalStrength}%) 󰖩 ";
format-ethernet = "{ipaddr}/{cidr} 󰈀 ";
format-linked = "{ifname} (No IP) 󰈀 ";
format-disconnected = "Disconnected 󰌙 ";
format-alt = "{ifname}: {ipaddr}/{cidr}";
tooltip = false;
on-click-right = "foot -e ${pkgs.networkmanager}/bin/nmtui";
};
"custom/vpn" = {
interval = 10;
exec = pkgs.writeShellScript "vpn-state" ''
${pkgs.iproute}/bin/ip -j link \
| ${pkgs.jq}/bin/jq --unbuffered --compact-output '
2023-05-30 14:03:12 +02:00
[[.[].ifname | select(. | startswith("mlv"))][] | sub("mlv-"; "") + " 󰌾${thinsp}"] as $conns
| { text: ($conns[0] // ""), class: (if $conns | length > 0 then "connected" else "disconnected" end) }'
'';
return-type = "json";
format = "{}";
tooltip = false;
};
memory = {
interval = 2;
2023-05-30 14:03:12 +02:00
format = "{:2}% 󰍛 ";
};
cpu = {
interval = 2;
2023-05-30 14:03:12 +02:00
format = "{usage:2}% 󰘚 ";
tooltip = false;
};
temperature = {
critical-threshold = 80;
format = "{temperatureC}°C {icon}";
format-icons = [ "" "" "" "" "" ];
};
battery = {
interval = 5;
format = "{capacity}% {icon}";
2023-05-30 14:03:12 +02:00
format-charging = "{capacity}% 󰂄";
format-plugged = "{capacity}% 󰚥";
format-alt = "{time} {icon}";
2023-05-30 14:03:12 +02:00
format-icons = [ "󱃍" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ];
states = {
critical = 15;
good = 95;
warning = 30;
};
};
clock = {
format = "{:%H:%M %Z}";
format-alt = "{:%Y-%m-%d (%a)}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
2021-07-17 16:13:45 +02:00
"custom/calendar" = {
interval = 300;
exec = pkgs.writeScript "calendar" /* python */ ''
2021-07-17 16:13:45 +02:00
#!${pkgs.python3}/bin/python3
import html
2021-07-17 16:13:45 +02:00
import json
import subprocess
def khal(args):
completed = subprocess.run(["${pkgs.khal}/bin/khal"] + args, capture_output=True)
2021-07-17 16:13:45 +02:00
assert completed.returncode == 0
return completed.stdout.decode("utf-8")
events_today = khal(["list", "today", "today", "-df", "", "-f", "{title}"]).rstrip().split("\n")
events_2d = (
html.escape(
khal(
[
"list",
"today",
"tomorrow",
"-df",
"WAYBARSTARTKHAL{name}, {date}WAYBARENDKHAL",
]
).rstrip()
)
.replace("WAYBARSTARTKHAL", "<b>")
.replace("WAYBARENDKHAL", "</b>")
)
2021-07-17 16:13:45 +02:00
if events_today == [""]:
events_today = []
2021-07-17 16:13:45 +02:00
if len(events_today) == 0:
2023-05-30 14:03:12 +02:00
text = "󰃮 "
2021-07-17 16:13:45 +02:00
else:
2023-05-30 14:03:12 +02:00
text = f"{len(events_today)} 󰃭 "
2021-07-17 16:13:45 +02:00
print(
json.dumps(
{
"class": "active" if len(events_today) > 0 else "",
"text": text,
"tooltip": events_2d,
}
)
)
'';
return-type = "json";
format = "{}";
};
"custom/notification" = {
tooltip = false;
format = "{icon}";
format-icons = {
2023-05-30 14:03:12 +02:00
notification = "󱅫${thinsp}";
none = "󰂚${thinsp}";
dnd-notification = "󰂛${thinsp}";
dnd-none = "󰂛${thinsp}";
};
return-type = "json";
exec = "${pkgs.swaynotificationcenter}/bin/swaync-client -swb";
on-click = "${pkgs.swaynotificationcenter}/bin/swaync-client -t -sw";
on-click-right = "${pkgs.swaynotificationcenter}/bin/swaync-client -d -sw";
escape = true;
};
};
xdg.configFile."waybar/style.css".source = pkgs.substituteAll ({
src = ./waybar.css;
} // solarized);
systemd.user.services.waybar = {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki/";
PartOf = [ "sway-session.target" ];
};
Install.WantedBy = [ "sway-session.target" ];
Service = {
# ensure sway is already started, otherwise workspaces will not work
ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg";
ExecStart = "${pkgs.waybar}/bin/waybar";
ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID";
Restart = "on-failure";
RestartSec = "1s";
};
};
2021-08-28 16:39:37 +02:00
services.blueman-applet.enable = lib.mkIf nixosConfig.sbruder.full true;
}