Separate user identity (data) from the reusable modules, and let a host declare any number of users instead of exactly one. - users/registry.nix: per-user identity (name, email, groups, authorized and signing keys) as the single source of identity; no user data is hardcoded in the modules. - mkHost takes a `users` set keyed by username; per-user identity is injected into each home config via the `identity` module arg (extraSpecialArgs is per-host, so it cannot carry per-user data). - modules/users.nix builds accounts from the registry; modules/ssh.nix no longer defines authorized keys (the registry owns them); home/git.nix and home/desktop.nix read `identity`; users/emmathorpe/work.nix drops its now-redundant git identity override. - Restructure the tree: users/, home/, modules/, hosts/, lib/ replace the former lyrathorpe/ and system/ layout. - Add standalone homeConfigurations (the portable subset: shell, git, editor, claude) and an exported homeModules output for use on machines not managed by this flake, or as an input to other flakes. Behaviour-preserving for existing hosts: lyrathorpe-mbp and emmathorpe-edaas evaluate to identical derivations; lyrathorpe-t400, lyrathorpe-macpro31 and lyrathorpe-rpi5 differ only by de-duplicating a repeated authorized_keys entry. Fixes the SSH authorized-key leak (one user's key was applied to every account), the hardcoded default git identity, and the hardcoded EDaaS linger setting.
162 lines
5.6 KiB
Nix
162 lines
5.6 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.features.swayDesktop;
|
|
# Catppuccin Mocha (shared with the Sway desktop, see home/sway.nix).
|
|
ctp = import ../lib/catppuccin-mocha.nix;
|
|
in
|
|
{
|
|
# The features.swayDesktop.enable option is declared in
|
|
# system/modules/features.nix (so headless hosts can read/set it without
|
|
# importing this module). This module only provides its implementation.
|
|
config = lib.mkIf cfg.enable {
|
|
programs.sway = {
|
|
enable = true;
|
|
wrapperFeatures.gtk = true;
|
|
extraSessionCommands = ''
|
|
# QT
|
|
export QT_QPA_PLATFORM="wayland;xcb"
|
|
export QT_QPA_PLATFORMTHEME=qt5ct
|
|
# SDL
|
|
export SDL_VIDEODRIVER=wayland
|
|
# Java
|
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
|
# Misc
|
|
export CLUTTER_BACKEND=wayland
|
|
export WINIT_UNIX_BACKEND=wayland
|
|
export MOZ_ENABLE_WAYLAND=1
|
|
'';
|
|
# Core Wayland utilities. The lock screen, idle daemon, status bar and
|
|
# notification daemon are configured per-user in home/sway.nix.
|
|
extraPackages = with pkgs; [
|
|
brightnessctl
|
|
foot
|
|
grim
|
|
slurp # region selection for screenshots
|
|
swappy # screenshot annotation/save
|
|
jq # used by the focused-window screenshot bind
|
|
playerctl # MPRIS media keys
|
|
sway-launcher-desktop
|
|
pavucontrol
|
|
];
|
|
};
|
|
fonts.packages = with pkgs; [
|
|
noto-fonts
|
|
noto-fonts-color-emoji
|
|
font-awesome
|
|
];
|
|
|
|
# Wayland login screen (replaces console/getty login on every Sway host).
|
|
# greetd runs ReGreet inside the cage kiosk compositor; the Sway session is
|
|
# offered automatically because programs.sway registers itself via
|
|
# services.displayManager.sessionPackages. Hosts that turn off
|
|
# features.swayDesktop (e.g. EDaaS) keep plain TTY login.
|
|
programs.regreet.enable = true;
|
|
# Theme the greeter to match the Sway desktop (Catppuccin Mocha). ReGreet is
|
|
# GTK; recolour via CSS (covering both libadwaita named colours and plain
|
|
# GTK node selectors) and use the same Noto Sans as the bar/notifications.
|
|
programs.regreet.font = {
|
|
name = "Noto Sans";
|
|
package = pkgs.noto-fonts;
|
|
size = 16;
|
|
};
|
|
programs.regreet.extraCss = ''
|
|
/* GTK4 Adwaita legacy names (what plain GTK4 actually references). */
|
|
@define-color theme_bg_color #${ctp.base};
|
|
@define-color theme_fg_color #${ctp.text};
|
|
@define-color theme_base_color #${ctp.mantle};
|
|
@define-color theme_text_color #${ctp.text};
|
|
@define-color theme_selected_bg_color #${ctp.blue};
|
|
@define-color theme_selected_fg_color #${ctp.base};
|
|
@define-color insensitive_bg_color #${ctp.mantle};
|
|
@define-color insensitive_fg_color #${ctp.overlay0};
|
|
@define-color borders #${ctp.surface1};
|
|
@define-color warning_color #${ctp.peach};
|
|
@define-color error_color #${ctp.red};
|
|
@define-color success_color #${ctp.green};
|
|
|
|
/* libadwaita names (inert on plain GTK4, kept for forward-compat). */
|
|
@define-color window_bg_color #${ctp.base};
|
|
@define-color window_fg_color #${ctp.text};
|
|
@define-color view_bg_color #${ctp.mantle};
|
|
@define-color view_fg_color #${ctp.text};
|
|
@define-color card_bg_color #${ctp.surface0};
|
|
@define-color card_fg_color #${ctp.text};
|
|
@define-color accent_bg_color #${ctp.blue};
|
|
@define-color accent_fg_color #${ctp.base};
|
|
@define-color accent_color #${ctp.blue};
|
|
@define-color destructive_bg_color #${ctp.red};
|
|
@define-color destructive_fg_color #${ctp.base};
|
|
|
|
window {
|
|
background-color: #${ctp.base};
|
|
color: #${ctp.text};
|
|
}
|
|
|
|
label {
|
|
color: #${ctp.text};
|
|
}
|
|
|
|
entry {
|
|
background-color: #${ctp.surface0};
|
|
color: #${ctp.text};
|
|
border: 1px solid #${ctp.surface1};
|
|
}
|
|
|
|
entry:focus-within {
|
|
border-color: #${ctp.blue};
|
|
}
|
|
|
|
button,
|
|
combobox button {
|
|
background-color: #${ctp.surface0};
|
|
color: #${ctp.text};
|
|
border: 1px solid #${ctp.surface1};
|
|
}
|
|
|
|
button:hover {
|
|
background-color: #${ctp.surface1};
|
|
}
|
|
|
|
button:active,
|
|
button:checked {
|
|
background-color: #${ctp.blue};
|
|
color: #${ctp.base};
|
|
}
|
|
'';
|
|
# cage reads the XKB_* environment at startup, so force the greeter onto the
|
|
# same Dvorak layout as the Sway session (home/sway.nix) -- otherwise the
|
|
# password field would be QWERTY. Dvorak is the "us" layout's variant, NOT a
|
|
# layout of its own: "dvorak" alone has no symbols/ file, so the keymap
|
|
# fails to compile and the greeter ends up with no keyboard at all (the
|
|
# greeter has no fallback, unlike a running Sway session). This overrides the
|
|
# greetd command regreet sets with mkDefault.
|
|
services.greetd.settings.default_session.command =
|
|
let
|
|
greeter = pkgs.writeShellScript "regreet-cage" ''
|
|
export XKB_DEFAULT_LAYOUT=us
|
|
export XKB_DEFAULT_VARIANT=dvorak
|
|
# ReGreet is plain GTK4 (no libadwaita); force the dark Adwaita variant
|
|
# so the extraCss accents sit on a dark base instead of light Adwaita.
|
|
export GTK_THEME=Adwaita:dark
|
|
exec ${pkgs.dbus}/bin/dbus-run-session ${lib.getExe pkgs.cage} -s -- ${lib.getExe config.programs.regreet.package}
|
|
'';
|
|
in
|
|
"${greeter}";
|
|
|
|
# Desktop portals: enables screen sharing (wlroots) and native file pickers
|
|
# for Wayland apps such as Element and Firefox.
|
|
xdg.portal = {
|
|
enable = true;
|
|
wlr.enable = true;
|
|
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
|
|
config.common.default = "*";
|
|
};
|
|
};
|
|
}
|