{ lib, pkgs, ... }: { config = { programs.waybar = { enable = true; systemd = { enable = true; target = "graphical-session.target"; }; settings = let windowRewrites = { "(.*) — Mozilla Firefox" = "$1"; "(.*) - Mozilla Thunderbird" = "$1"; "(.*) - mpv" = "$1"; }; iconSize = 11; in [ { layer = "top"; position = "top"; height = 14; output = [ "eDP-1" "DP-2" "DP-3" ]; modules-left = [ "niri/workspaces" ]; modules-center = [ "niri/window" ]; modules-right = [ # "custom/worktime" "custom/worktime-today" "custom/weather" # "custom/keymap" "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "clock" ]; "custom/weather" = { format = "{}"; tooltip = true; interval = 3600; exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"{ICON} {FeelsLikeC}°\""; return-type = "json"; }; "custom/keymap" = { format = "{}"; tooltip = true; return-type = "json"; exec = pkgs.writers.writePython3 "keymap" {} '' import os import socket import re import subprocess import json def output(keymap): short = keymap if keymap == "English (programmer Dvorak)": short = "dvp" elif keymap == "English (US)": short = "us" print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501 r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501 for keyboard in json.loads(r.stdout)['keyboards']: if keyboard['name'] != "at-translated-set-2-keyboard": continue output(keyboard['active_keymap']) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501 expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P.+)$') # noqa: E501 for line in sock.makefile(buffering=1, encoding='utf-8'): if match := expected.match(line): output(match.group("keymap")) ''; on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next"; }; "custom/worktime" = { interval = 60; exec = lib.getExe pkgs.worktime; tooltip = false; }; "custom/worktime-today" = { interval = 60; exec = "${lib.getExe pkgs.worktime} today"; tooltip = false; }; "niri/workspaces" = {}; "niri/window" = { separate-outputs = true; icon = true; icon-size = 14; rewrite = windowRewrites; }; clock = { interval = 1; # timezone = "Europe/Berlin"; format = "W{:%V-%u %F %H:%M:%S%Ez}"; tooltip-format = "{calendar}"; calendar = { mode = "year"; mode-mon-col = 3; weeks-pos = "left"; on-scroll = 1; format = { months = "{}"; days = "{}"; weeks = "{}"; weekdays = "{}"; today = "{}"; }; }; }; battery = { format = "{icon}"; icon-size = iconSize - 2; states = { warning = 30; critical = 15; }; format-icons = ["󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; format-charging = "󰂄"; format-plugged = "󰚥"; tooltip-format = "{capacity}% {timeTo}"; interval = 20; }; tray = { icon-size = 16; # show-passive-items = true; spacing = 1; }; privacy = { icon-spacing = 7; icon-size = iconSize; modules = [ { type = "screenshare"; } { type = "audio-in"; } ]; }; idle_inhibitor = { format = "{icon}"; icon-size = iconSize; format-icons = { activated = "󰈈"; deactivated = "󰈉"; }; timeout = 120; }; backlight = { format = "{icon}"; icon-size = iconSize; tooltip-format = "{percent}%"; format-icons = ["󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠"]; on-scroll-up = "lightctl -d -e4 -n1 up"; on-scroll-down = "lightctl -d -e4 -n1 down"; }; wireplumber = { format = "{icon}"; icon-size = iconSize; tooltip-format = "{volume}% {node_name}"; format-icons = ["󰕿" "󰖀" "󰕾"]; format-muted = "󰝟"; # ignored-sinks = ["Easy Effects Sink"]; on-scroll-up = "volumectl -d -u up"; on-scroll-down = "volumectl -d -u down"; on-click = "volumectl -d toggle-mute"; }; } { layer = "top"; position = "top"; height = 14; output = [ "!eDP-1" "!DP-2" "!DP-3" ]; modules-left = [ "niri/workspaces" ]; modules-center = [ "niri/window" ]; modules-right = [ "clock" ]; "niri/workspaces" = {}; "niri/window" = { separate-outputs = true; icon = true; icon-size = 14; rewrite = windowRewrites; }; clock = { interval = 1; # timezone = "Europe/Berlin"; format = "{:%H:%M}"; tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}"; }; } ]; style = '' @define-color white #ffffff; @define-color grey #555555; @define-color blue #1a8fff; @define-color green #23fd00; @define-color orange #f28a21; @define-color red #f2201f; * { border: none; font-family: "Fira Sans Nerd Font"; font-size: 10pt; min-height: 0; } window#waybar { background-color: rgba(0, 0, 0, 0.66); color: @white; } .modules-left { margin-left: 9px; } .modules-right { margin-right: 9px; } .module { margin: 0 5px; } #workspaces button { color: @white; padding: 2px 5px; } #workspaces button.empty { color: @grey; } #workspaces button.active { color: @green; } #workspaces button.urgent { color: @red; } #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today { color: @grey; margin: 0 5px; } #custom-weather, #custom-worktime-today { margin-right: 3px; } #custom-keymap, #custom-weather { margin-left: 3px; } #tray { margin: 0; } #battery, #idle_inhibitor, #backlight, #wireplumber { color: @grey; margin: 0 5px 0 2px; } #idle_inhibitor { margin-right: 2px; margin-left: 3px; } #battery { margin-right: 3px; } #battery.discharging { color: @white; } #battery.warning { color: @orange; } #battery.critical { color: @red; } #battery.charging { color: @white; } #idle_inhibitor.activated { color: @white; } #idle_inhibitor { padding-top: 1px; } #privacy { color: @red; margin: -1px 2px 0px 5px; } #clock { /* margin-right: 5px; */ } ''; }; }; }