refactor(flake): user registry, multi-user hosts, and portable home outputs (#49)
CI / flake (push) Successful in 3m26s
CI / flake (push) Successful in 3m26s
## Summary Separates user identity (data) from the reusable Nix modules and lets a host declare any number of users, replacing the previous one-user-per-host structure. Also restructures the tree and exposes the home config for use off these hosts. ## Changes - **User registry** (`users/registry.nix`): per-user identity (name, email, groups, authorized + signing keys) as the single source of truth; no user data hardcoded in modules. - **Multi-user `mkHost`**: a host declares a `users` set keyed by username; per-user identity is injected into each home config via the `identity` module arg. - **Restructured layout**: `users/`, `home/`, `modules/`, `hosts/`, `lib/` replace the former `lyrathorpe/` and `system/` trees. - **Portable outputs**: standalone `homeConfigurations."<user>@<system>"` (the portable subset — shell, git, editor, claude) plus an exported `homeModules` for use on machines not managed by this flake, or as an input to other flakes. - Docs (`README.md`, `home/README.md`) and `.gitignore` updated for the new paths. ## Fixes - Closes #46 — shared user module authorized one user's SSH key for every account. - Closes #47 — git committer identity hardcoded as defaults instead of per-user. - Closes #48 — EDaaS systemd linger hardcoded to a literal username. ## Verification - `nix flake check` passes: treefmt, deadnix, statix, pre-commit, and evaluation of all NixOS hosts + Darwin + homeConfigurations. - Derivation-path comparison vs `main`: `lyrathorpe-mbp` and `emmathorpe-edaas` are byte-identical; `lyrathorpe-t400`, `lyrathorpe-macpro31` and `lyrathorpe-rpi5` differ only by de-duplicating a repeated `authorized_keys` entry (confirmed with nix-diff — no other change). - Standalone `homeConfigurations."lyrathorpe@x86_64-linux".activationPackage` builds. ## Notes - `emmathorpe` has no personal authorized key yet (it previously inherited Lyra's key via the bug in #46); the registry entry is intentionally empty — add a real key if SSH login as `emmathorpe` is wanted (moot on the WSL host). - A two-repo (public dotfiles / private systems) split is deferred by design; this internal restructure is the prerequisite for it. --------- Co-authored-by: Emma Thorpe <emma.thorpe@citrix.com> Reviewed-on: #49
This commit was merged in pull request #49.
This commit is contained in:
+525
@@ -0,0 +1,525 @@
|
||||
# Declarative Sway window manager, status bar, lock, idle and notifications.
|
||||
# Imported via ./desktop.nix, so only graphical hosts get it.
|
||||
#
|
||||
# The compositor binary, PAM and the polkit *daemon* come from the system-level
|
||||
# programs.sway (see ../modules/sway.nix); package = null below reuses it instead of
|
||||
# pulling a second Sway. The polkit authentication *agent* (the thing that draws
|
||||
# the GUI auth dialog) is a user service started here. home-manager owns the user
|
||||
# config (~/.config/sway) and wires the systemd user session (sway-session.target),
|
||||
# which is what lets the agent/swayidle/dunst/kanshi user services start with the
|
||||
# desktop.
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
# Threaded from mkHost (flake.nix). Desktop hosts set this false to drop
|
||||
# mobile components (battery block, screen-brightness keys).
|
||||
portable ? true,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# Catppuccin Mocha (shared with the ReGreet greeter). Raw hex; prefix "#"
|
||||
# where a consumer needs it -- Sway/i3status/dunst want "#", foot/swaylock do
|
||||
# not.
|
||||
ctp = import ../lib/catppuccin-mocha.nix;
|
||||
|
||||
# Focused-window screenshot -> swappy editor (the dotfiles' grimshot.sh logic).
|
||||
# Full store paths so it needs nothing on PATH.
|
||||
screenshotWindow = pkgs.writeShellScript "screenshot-window" ''
|
||||
${pkgs.grim}/bin/grim -g "$(${pkgs.sway}/bin/swaymsg -t get_tree \
|
||||
| ${pkgs.jq}/bin/jq -r '.. | select(.focused?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"')" \
|
||||
- | ${pkgs.swappy}/bin/swappy -f -
|
||||
'';
|
||||
|
||||
# Binding-mode names. The string is both the `modes` attr key and what the
|
||||
# bar's mode indicator shows, so the keys are spelled out in the label.
|
||||
layoutMode = "layout: [s]tacking [w]tabbed [e]split";
|
||||
systemMode = "system: [l]ock [e]xit [s]leep [r]eboot [Shift+s]shutdown";
|
||||
in
|
||||
{
|
||||
wayland.windowManager.sway = {
|
||||
enable = true;
|
||||
package = null;
|
||||
# `sway --validate` needs a real package; skip it since package = null.
|
||||
checkConfig = false;
|
||||
config = rec {
|
||||
modifier = "Mod4";
|
||||
terminal = "${pkgs.foot}/bin/foot";
|
||||
# Launcher: sway-launcher-desktop running inside a floating foot window.
|
||||
menu = "${pkgs.foot}/bin/foot --app-id=launcher ${pkgs.sway-launcher-desktop}/bin/sway-launcher-desktop";
|
||||
|
||||
# Dvorak is a variant of the "us" layout, not a standalone layout --
|
||||
# `xkb_layout = "dvorak"` fails to compile (no symbols/dvorak) and wlroots
|
||||
# silently falls back to QWERTY. Use the variant.
|
||||
input."type:keyboard" = {
|
||||
xkb_layout = "us";
|
||||
xkb_variant = "dvorak";
|
||||
};
|
||||
# Touchpads (laptops): tap-to-click and natural scrolling. Inert on the
|
||||
# desktop hosts, which have no touchpad.
|
||||
input."type:touchpad" = {
|
||||
tap = "enabled";
|
||||
natural_scroll = "enabled";
|
||||
};
|
||||
|
||||
# Solid Catppuccin Mocha base as the wallpaper (no image dependency).
|
||||
output."*".bg = "#${ctp.base} solid_color";
|
||||
|
||||
# Window borders -- Catppuccin Mocha (blue accent on the focused window).
|
||||
colors = {
|
||||
focused = {
|
||||
border = "#${ctp.blue}";
|
||||
background = "#${ctp.base}";
|
||||
text = "#${ctp.text}";
|
||||
indicator = "#${ctp.blue}";
|
||||
childBorder = "#${ctp.blue}";
|
||||
};
|
||||
focusedInactive = {
|
||||
border = "#${ctp.surface0}";
|
||||
background = "#${ctp.base}";
|
||||
text = "#${ctp.subtext0}";
|
||||
indicator = "#${ctp.surface0}";
|
||||
childBorder = "#${ctp.surface0}";
|
||||
};
|
||||
unfocused = {
|
||||
border = "#${ctp.surface0}";
|
||||
background = "#${ctp.base}";
|
||||
text = "#${ctp.subtext0}";
|
||||
indicator = "#${ctp.surface0}";
|
||||
childBorder = "#${ctp.surface0}";
|
||||
};
|
||||
urgent = {
|
||||
border = "#${ctp.red}";
|
||||
background = "#${ctp.base}";
|
||||
text = "#${ctp.text}";
|
||||
indicator = "#${ctp.red}";
|
||||
childBorder = "#${ctp.red}";
|
||||
};
|
||||
};
|
||||
|
||||
window.commands = [
|
||||
{
|
||||
criteria.app_id = "launcher";
|
||||
command = "floating enable, resize set 800 500";
|
||||
}
|
||||
# Don't let swayidle blank/lock during fullscreen video. Two rules cover
|
||||
# native Wayland (app_id) and XWayland (class) clients.
|
||||
{
|
||||
criteria.app_id = ".*";
|
||||
command = "inhibit_idle fullscreen";
|
||||
}
|
||||
{
|
||||
criteria.class = ".*";
|
||||
command = "inhibit_idle fullscreen";
|
||||
}
|
||||
];
|
||||
|
||||
# Binding modes (submenus). Entered from keybindings below; each action
|
||||
# returns to the default mode. mkOptionDefault-merged with the module's
|
||||
# built-in "resize" mode.
|
||||
modes = {
|
||||
# Layout submenu (Mod+y). Mirrors Sway's default s/w/e layout keys --
|
||||
# notably it restores split-toggle, which moved off Mod+e when that
|
||||
# became the nemo launcher.
|
||||
${layoutMode} = {
|
||||
"s" = "layout stacking, mode default";
|
||||
"w" = "layout tabbed, mode default";
|
||||
"e" = "layout toggle split, mode default";
|
||||
"Return" = "mode default";
|
||||
"Escape" = "mode default";
|
||||
};
|
||||
# Power menu (Mod+Shift+x). Lock reuses the themed swaylock; the rest go
|
||||
# through systemd/logind (allowed for the active local session).
|
||||
${systemMode} = {
|
||||
"l" = "exec ${pkgs.swaylock}/bin/swaylock -f, mode default";
|
||||
"e" = "exec ${pkgs.sway}/bin/swaymsg exit, mode default";
|
||||
"s" = "exec systemctl suspend, mode default";
|
||||
"r" = "exec systemctl reboot, mode default";
|
||||
"Shift+s" = "exec systemctl poweroff, mode default";
|
||||
"Return" = "mode default";
|
||||
"Escape" = "mode default";
|
||||
};
|
||||
};
|
||||
|
||||
bars = [
|
||||
{
|
||||
position = "top";
|
||||
statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ~/.config/i3status-rust/config-default.toml";
|
||||
fonts = {
|
||||
names = [
|
||||
"Noto Sans"
|
||||
"Font Awesome 6 Free"
|
||||
];
|
||||
size = 11.0;
|
||||
};
|
||||
# Bar background + workspace buttons -- Catppuccin Mocha. The mantle
|
||||
# background matches i3status-rust's idle_bg below for a uniform strip.
|
||||
colors = {
|
||||
background = "#${ctp.mantle}";
|
||||
statusline = "#${ctp.text}";
|
||||
separator = "#${ctp.surface0}";
|
||||
focusedWorkspace = {
|
||||
border = "#${ctp.blue}";
|
||||
background = "#${ctp.blue}";
|
||||
text = "#${ctp.base}";
|
||||
};
|
||||
activeWorkspace = {
|
||||
border = "#${ctp.surface0}";
|
||||
background = "#${ctp.surface0}";
|
||||
text = "#${ctp.text}";
|
||||
};
|
||||
inactiveWorkspace = {
|
||||
border = "#${ctp.mantle}";
|
||||
background = "#${ctp.mantle}";
|
||||
text = "#${ctp.subtext0}";
|
||||
};
|
||||
urgentWorkspace = {
|
||||
border = "#${ctp.red}";
|
||||
background = "#${ctp.red}";
|
||||
text = "#${ctp.base}";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
# NB: this whole set is wrapped in mkOptionDefault so it MERGES with the
|
||||
# home-manager module's default keybindings (same priority) rather than
|
||||
# replacing them. Do not wrap it in mkMerge with a normal-priority attr --
|
||||
# that makes the normal-priority def win and silently drops every default
|
||||
# bind (terminal, movement, workspaces, ...).
|
||||
keybindings = lib.mkOptionDefault (
|
||||
{
|
||||
# Launcher on Mod+Space. mkForce overrides the module's own default
|
||||
# Mod+Space (focus mode_toggle); a plain value would conflict with it
|
||||
# at equal priority. Mod+d also still runs the launcher (module default).
|
||||
"${modifier}+space" = lib.mkForce "exec ${menu}";
|
||||
# File manager. mkForce overrides the module default (layout toggle split).
|
||||
"${modifier}+e" = lib.mkForce "exec ${pkgs.nemo}/bin/nemo";
|
||||
"${modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock -f";
|
||||
|
||||
# Cycle workspaces.
|
||||
"${modifier}+z" = "workspace prev";
|
||||
"${modifier}+x" = "workspace next";
|
||||
|
||||
# focus mode_toggle (tiling <-> floating focus) -- re-homed off
|
||||
# Mod+Space, which is now the launcher.
|
||||
"${modifier}+Mod1+space" = "focus mode_toggle";
|
||||
|
||||
# Enter the binding-mode submenus defined above.
|
||||
"${modifier}+y" = "mode \"${layoutMode}\"";
|
||||
"${modifier}+Shift+x" = "mode \"${systemMode}\"";
|
||||
|
||||
# Clipboard history: pick a past entry through fuzzel (clipman stores
|
||||
# it -- see services.clipman below).
|
||||
"${modifier}+c" =
|
||||
"exec ${pkgs.clipman}/bin/clipman pick -t CUSTOM --tool-args=\"${pkgs.fuzzel}/bin/fuzzel --dmenu\"";
|
||||
|
||||
# Screenshots -> swappy editor: Print = drag a region, Shift+Print =
|
||||
# the focused window.
|
||||
"Print" =
|
||||
"exec ${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp)\" - | ${pkgs.swappy}/bin/swappy -f -";
|
||||
"Shift+Print" = "exec ${screenshotWindow}";
|
||||
|
||||
"XF86AudioRaiseVolume" = "exec ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
|
||||
"XF86AudioLowerVolume" = "exec ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
|
||||
"XF86AudioMute" = "exec ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
||||
"XF86AudioMicMute" = "exec ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
|
||||
|
||||
# Media keys (MPRIS via playerctl).
|
||||
"XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
|
||||
"XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next";
|
||||
"XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl previous";
|
||||
}
|
||||
# Screen backlight: laptops only (no internal backlight on a desktop).
|
||||
// lib.optionalAttrs portable {
|
||||
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%+";
|
||||
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
# Terminal: Catppuccin Mocha. foot reads ~/.config/foot/foot.ini; the Sway
|
||||
# `terminal` above still launches the same binary, now themed.
|
||||
programs.foot = {
|
||||
enable = true;
|
||||
# foot 1.27: the bare [colors] section is deprecated in favour of
|
||||
# [colors-dark] (the default theme), and the cursor colour moved out of
|
||||
# [cursor] (where `color` is now rejected) into a `cursor` key here, written
|
||||
# "<text> <cursor>" (man foot.ini(5): "ff0000 00ff00" => green cursor, red
|
||||
# text). Only colors-dark is needed; we never set initial-color-theme=light.
|
||||
settings = {
|
||||
main = {
|
||||
# Nerd Font: monospace plus the powerline/Nerd glyphs the tmux
|
||||
# statusline uses (otherwise they render as blank/"?").
|
||||
font = "JetBrainsMono Nerd Font:size=11";
|
||||
# Advertise as xterm-256color so remote hosts without foot's terminfo
|
||||
# still behave (tmux re-adds foot's RGB/sync/etc. features -- see
|
||||
# shell.nix). The [main] section is the unheadered top of foot.ini.
|
||||
term = "xterm-256color";
|
||||
};
|
||||
scrollback.lines = 100000;
|
||||
"colors-dark" = {
|
||||
background = ctp.base;
|
||||
foreground = ctp.text;
|
||||
regular0 = ctp.surface1;
|
||||
regular1 = ctp.red;
|
||||
regular2 = ctp.green;
|
||||
regular3 = ctp.yellow;
|
||||
regular4 = ctp.blue;
|
||||
regular5 = ctp.pink;
|
||||
regular6 = ctp.teal;
|
||||
regular7 = ctp.subtext1;
|
||||
bright0 = ctp.surface2;
|
||||
bright1 = ctp.red;
|
||||
bright2 = ctp.green;
|
||||
bright3 = ctp.yellow;
|
||||
bright4 = ctp.blue;
|
||||
bright5 = ctp.pink;
|
||||
bright6 = ctp.teal;
|
||||
bright7 = ctp.subtext0;
|
||||
"selection-foreground" = ctp.base;
|
||||
"selection-background" = ctp.rosewater;
|
||||
cursor = "${ctp.base} ${ctp.rosewater}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Clipboard history: a user service runs `wl-paste --watch clipman store`,
|
||||
# bound to the Wayland session, so copies persist and Mod+c (above) can pick
|
||||
# an old entry through fuzzel.
|
||||
services.clipman.enable = true;
|
||||
|
||||
# Polkit authentication agent. programs.sway (system) enables the polkit
|
||||
# daemon but no agent, so GUI privilege prompts (nemo mounting a disk,
|
||||
# NetworkManager/blueman editing a system resource) would otherwise fail
|
||||
# silently. lxqt-policykit is a small, toolkit-light agent; bind it to the
|
||||
# Sway session so it starts and stops with the desktop.
|
||||
systemd.user.services.polkit-lxqt = {
|
||||
Unit = {
|
||||
Description = "lxqt-policykit polkit authentication agent";
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
After = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.lxqt.lxqt-policykit}/bin/lxqt-policykit-agent";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
Install.WantedBy = [ "sway-session.target" ];
|
||||
};
|
||||
|
||||
# Output/display management. Reacts to hotplug and applies per-display
|
||||
# mode/scale/position. Profiles are hardware-specific: the safe default below
|
||||
# just enables the internal laptop panel; add docked/desktop profiles with the
|
||||
# real identifiers from `swaymsg -t get_outputs` (e.g. the Mac Pro's Apple
|
||||
# Cinema Display with its scale, or a docked laptop + external monitor).
|
||||
services.kanshi = {
|
||||
enable = true;
|
||||
settings = [
|
||||
{
|
||||
profile.name = "undocked";
|
||||
profile.outputs = [
|
||||
{
|
||||
criteria = "eDP-1";
|
||||
status = "enable";
|
||||
}
|
||||
];
|
||||
}
|
||||
# Example to copy per host (fill in real criteria/mode/scale/position):
|
||||
# {
|
||||
# profile.name = "desktop";
|
||||
# profile.outputs = [
|
||||
# { criteria = "Apple Computer Inc Cinema HD ..."; mode = "2560x1600"; scale = 1.0; position = "0,0"; status = "enable"; }
|
||||
# ];
|
||||
# }
|
||||
];
|
||||
};
|
||||
|
||||
# Night light. Manual location (no geoclue dependency); warmer at night,
|
||||
# neutral by day. Coordinates come from the per-user module (e.g.
|
||||
# users/lyrathorpe/home.nix), not this shared module.
|
||||
services.gammastep = {
|
||||
enable = true;
|
||||
provider = "manual";
|
||||
temperature = {
|
||||
day = 6500;
|
||||
night = 3700;
|
||||
};
|
||||
};
|
||||
|
||||
# fuzzel: the dmenu picker used by clipman, themed Catppuccin Mocha to match
|
||||
# (fuzzel colours are RRGGBBAA -- 8 hex digits).
|
||||
programs.fuzzel = {
|
||||
enable = true;
|
||||
settings = {
|
||||
main = {
|
||||
font = "Noto Sans:size=12";
|
||||
prompt = "\"clipboard \"";
|
||||
};
|
||||
border = {
|
||||
width = 2;
|
||||
radius = 8;
|
||||
};
|
||||
colors = {
|
||||
background = "${ctp.base}f0";
|
||||
text = "${ctp.text}ff";
|
||||
prompt = "${ctp.subtext0}ff";
|
||||
input = "${ctp.text}ff";
|
||||
match = "${ctp.blue}ff";
|
||||
selection = "${ctp.surface1}ff";
|
||||
selection-text = "${ctp.text}ff";
|
||||
selection-match = "${ctp.blue}ff";
|
||||
border = "${ctp.blue}ff";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.swaylock = {
|
||||
enable = true;
|
||||
# Catppuccin Mocha (swaylock colours are hex without "#").
|
||||
settings = {
|
||||
color = ctp.base;
|
||||
indicator-radius = 100;
|
||||
indicator-thickness = 7;
|
||||
show-failed-attempts = true;
|
||||
font = "Noto Sans";
|
||||
|
||||
inside-color = ctp.base;
|
||||
inside-clear-color = ctp.base;
|
||||
inside-ver-color = ctp.base;
|
||||
inside-wrong-color = ctp.base;
|
||||
|
||||
ring-color = ctp.surface1;
|
||||
ring-clear-color = ctp.yellow;
|
||||
ring-ver-color = ctp.blue;
|
||||
ring-wrong-color = ctp.red;
|
||||
|
||||
key-hl-color = ctp.blue;
|
||||
bs-hl-color = ctp.red;
|
||||
|
||||
line-color = ctp.base;
|
||||
line-clear-color = ctp.base;
|
||||
line-ver-color = ctp.base;
|
||||
line-wrong-color = ctp.base;
|
||||
separator-color = "00000000";
|
||||
|
||||
text-color = ctp.text;
|
||||
text-clear-color = ctp.text;
|
||||
text-ver-color = ctp.text;
|
||||
text-wrong-color = ctp.text;
|
||||
};
|
||||
};
|
||||
|
||||
# Lock on idle, turn screens off shortly after, and lock before sleep.
|
||||
services.swayidle = {
|
||||
enable = true;
|
||||
timeouts = [
|
||||
{
|
||||
timeout = 300;
|
||||
command = "${pkgs.swaylock}/bin/swaylock -f";
|
||||
}
|
||||
{
|
||||
timeout = 600;
|
||||
command = "${pkgs.sway}/bin/swaymsg 'output * power off'";
|
||||
resumeCommand = "${pkgs.sway}/bin/swaymsg 'output * power on'";
|
||||
}
|
||||
];
|
||||
events = {
|
||||
before-sleep = "${pkgs.swaylock}/bin/swaylock -f";
|
||||
lock = "${pkgs.swaylock}/bin/swaylock -f";
|
||||
};
|
||||
};
|
||||
|
||||
services.dunst = {
|
||||
enable = true;
|
||||
# Catppuccin Mocha notifications (dunst colours need a leading "#").
|
||||
settings = {
|
||||
global = {
|
||||
font = "Noto Sans 11";
|
||||
frame_color = "#${ctp.blue}";
|
||||
frame_width = 2;
|
||||
separator_color = "frame";
|
||||
offset = "10x10";
|
||||
corner_radius = 5;
|
||||
};
|
||||
urgency_low = {
|
||||
background = "#${ctp.base}";
|
||||
foreground = "#${ctp.text}";
|
||||
frame_color = "#${ctp.surface1}";
|
||||
};
|
||||
urgency_normal = {
|
||||
background = "#${ctp.base}";
|
||||
foreground = "#${ctp.text}";
|
||||
frame_color = "#${ctp.blue}";
|
||||
};
|
||||
urgency_critical = {
|
||||
background = "#${ctp.base}";
|
||||
foreground = "#${ctp.text}";
|
||||
frame_color = "#${ctp.peach}";
|
||||
timeout = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.i3status-rust = {
|
||||
enable = true;
|
||||
bars.default = {
|
||||
# Catppuccin Mocha: a flat "plain" base recoloured via overrides. Idle
|
||||
# blocks sit on mantle (matching the Sway bar background) with light text;
|
||||
# only warning/critical states get a loud tinted background. The `theme`
|
||||
# bar option is shallow-merged away by `settings.theme`, so set the base
|
||||
# theme and its overrides together here.
|
||||
icons = "awesome6";
|
||||
settings.theme = {
|
||||
theme = "plain";
|
||||
overrides = {
|
||||
idle_bg = "#${ctp.mantle}";
|
||||
idle_fg = "#${ctp.text}";
|
||||
info_bg = "#${ctp.mantle}";
|
||||
info_fg = "#${ctp.blue}";
|
||||
good_bg = "#${ctp.mantle}";
|
||||
good_fg = "#${ctp.green}";
|
||||
warning_bg = "#${ctp.peach}";
|
||||
warning_fg = "#${ctp.base}";
|
||||
critical_bg = "#${ctp.red}";
|
||||
critical_fg = "#${ctp.base}";
|
||||
separator_bg = "#${ctp.mantle}";
|
||||
separator_fg = "#${ctp.surface1}";
|
||||
};
|
||||
};
|
||||
blocks = [
|
||||
{
|
||||
block = "disk_space";
|
||||
path = "/";
|
||||
format = " $icon $available ";
|
||||
}
|
||||
{
|
||||
block = "memory";
|
||||
format = " $icon $mem_used_percents ";
|
||||
}
|
||||
{
|
||||
block = "cpu";
|
||||
interval = 2;
|
||||
}
|
||||
]
|
||||
# Desktop-only: CPU temperature and wired network throughput, in place
|
||||
# of the laptop's battery readout.
|
||||
++ lib.optionals (!portable) [
|
||||
{
|
||||
block = "temperature";
|
||||
interval = 5;
|
||||
format = " $icon $average avg, $max max ";
|
||||
}
|
||||
{ block = "net"; }
|
||||
]
|
||||
++ [ { block = "sound"; } ]
|
||||
++ lib.optional portable { block = "battery"; }
|
||||
++ [
|
||||
{
|
||||
block = "time";
|
||||
interval = 5;
|
||||
format = " $timestamp.datetime(f:'%a %d/%m %R') ";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user