{ config, lib, pkgs, ... }: # Waybar: a top status bar reading system state at a glance. let registeredWaybarStyles = lib.concatStringsSep "\n" ( lib.filter (style: style != "") (lib.mapAttrsToList (_name: module: module.style) hostWaybarModules) ); hostWaybarModules = lib.attrByPath [ config.networking.hostName ] { } config.registry.waybar; waybarModulesFor = position: map (module: module.name) ( lib.sort (a: b: a.order < b.order) ( lib.filter (module: module.position == position) registeredWaybarModules ) ); registeredWaybarModules = lib.mapAttrsToList ( name: module: module // { inherit name; } ) hostWaybarModules; registeredWaybarModuleSettings = lib.mapAttrs (_name: module: module.settings) hostWaybarModules; # A Nerd Font Private-Use-Area codepoint as a literal character, decoded # through JSON so the glyph survives as bytes rather than an editor paste. g = code: builtins.fromJSON ''"\u${code}"''; networkStatus = pkgs.writeShellScript "waybar-network-status" '' active=$( ${lib.getExe' pkgs.networkmanager "nmcli"} -t -f DEVICE,TYPE,STATE,CONNECTION device status \ | ${lib.getExe' pkgs.gawk "awk"} -F: '$3 == "connected" && $2 != "loopback" { print; exit }' ) if [ -z "$active" ]; then ${lib.getExe pkgs.jq} -cn \ --arg text "${g "f127"} off" \ --arg tooltip "Network disconnected" \ --arg class "disconnected" \ '{ text: $text, tooltip: $tooltip, class: $class }' exit 0 fi IFS=: read -r device type _state connection <<< "$active" case "$type" in wifi) icon="${g "f1eb"}" ;; ethernet) icon="LAN" ;; *) icon="NET" ;; esac ipaddr=$(${lib.getExe' pkgs.iproute2 "ip"} -4 -o addr show dev "$device" | ${lib.getExe' pkgs.gawk "awk"} '{ print $4; exit }') ${lib.getExe pkgs.jq} -cn \ --arg text "$icon $connection" \ --arg tooltip "$device: ''${ipaddr:-no IPv4}" \ --arg class "$type" \ '{ text: $text, tooltip: $tooltip, class: $class }' ''; in { options.modules.desktop.session.waybar.enable = lib.mkEnableOption "the Waybar status bar"; config = lib.mkIf config.modules.desktop.session.waybar.enable { # A symbols font backs the module glyphs, so pango falls back to it for the # codepoints Stylix's monospace font does not carry. fonts.packages = [ pkgs.nerd-fonts.symbols-only ]; home-manager.users.${config.user.name}.programs.waybar = { enable = true; # A user service bound to graphical-session.target, which uwsm activates, # so the bar comes up with the session and no compositor exec-once. systemd.enable = true; style = '' .modules-right { margin-right: 8px; } '' + registeredWaybarStyles; settings.mainBar = lib.mkMerge [ { layer = "top"; position = "top"; height = 30; spacing = 8; modules-left = waybarModulesFor "left"; modules-center = waybarModulesFor "center"; modules-right = waybarModulesFor "right"; } registeredWaybarModuleSettings ]; }; registry.waybar.${config.networking.hostName} = { clock = { position = "center"; order = 10; settings = { format = "{:%a %d %b %H:%M}"; tooltip-format = "{calendar}"; calendar = { mode = "month"; # Underline the current day so it stands out in the grid. format.today = "{}"; }; }; }; "custom/network" = { order = 60; settings = { return-type = "json"; exec = "${networkStatus}"; interval = 5; }; }; battery = { order = 70; settings = { format = "{icon} {capacity}%"; format-charging = "${g "f0e7"} {capacity}%"; format-icons = [ (g "f244") (g "f243") (g "f242") (g "f241") (g "f240") ]; states = { warning = 20; critical = 10; }; }; }; }; }; }