Feat/t400 and macpro31 hosts #17
@@ -10,9 +10,10 @@ Defined in the host table in [`flake.nix`](./flake.nix):
|
||||
| Configuration | System | Machine |
|
||||
| ------------------- | --------------- | ---------------------------------------- |
|
||||
| `lyrathorpe-mbp` | `aarch64-linux` | MacBook Pro (Apple Silicon, Asahi) |
|
||||
| `lyrathorpe-x1c` | `x86_64-linux` | ThinkPad X1 |
|
||||
| `lyrathorpe-t400` | `x86_64-linux` | ThinkPad T400 — [install notes](./system/machine/T400/README.md) |
|
||||
| `lyrathorpe-macpro31` | `x86_64-linux` | Mac Pro 3,1, desktop — [install notes](./system/machine/MacPro31/README.md) |
|
||||
| `emmathorpe-edaas` | `x86_64-linux` | Work WSL box (NixOS-WSL) |
|
||||
| `lyrathorpe-mac` | `aarch64-darwin`| macOS (nix-darwin) |
|
||||
| `lyrathorpe-mac` | `aarch64-darwin` | macOS (nix-darwin) |
|
||||
|
||||
Shared layers: `lyrathorpe/home` (home-manager: shell, git, editor),
|
||||
`system/modules/common-nixos.nix` (all NixOS hosts), and
|
||||
@@ -27,6 +28,21 @@ sudo nixos-rebuild switch --flake .#<configuration>
|
||||
darwin-rebuild switch --flake .#lyrathorpe-mac
|
||||
```
|
||||
|
||||
## Keybindings
|
||||
|
||||
All Sway / tmux / foot / zsh keyboard shortcuts are documented in
|
||||
[`lyrathorpe/home/KEYBINDINGS.md`](./lyrathorpe/home/KEYBINDINGS.md).
|
||||
|
||||
## Login / greeter
|
||||
|
||||
Graphical (Sway) hosts log in through a Wayland greeter — `greetd` running
|
||||
ReGreet inside the `cage` kiosk compositor — configured centrally in
|
||||
[`lyrathorpe/swaywm.nix`](./lyrathorpe/swaywm.nix), gated on
|
||||
`features.swayDesktop.enable`. The greeter is forced to Dvorak to match the
|
||||
console and Sway session. Hosts with `features.swayDesktop.enable = false` (the
|
||||
WSL work box) keep plain TTY login. The target account needs a password
|
||||
(`passwd <user>`) before it can log in.
|
||||
|
||||
## MacBook (Asahi) firmware
|
||||
|
||||
The MBP host references `system/modules/firmware/` for Apple peripheral
|
||||
|
||||
Generated
+23
@@ -17,6 +17,28 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"firefox-addons": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"lastModified": 1780977789,
|
||||
"narHash": "sha256-UFJfQlvInbsVaTK5XC2lafdqWlwiNP5LuQFYfDKq6Dc=",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"rev": "0b627f105ea3baa2fa10308a6a67a8f8cbbb3e2a",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"dir": "pkgs/firefox-addons",
|
||||
"owner": "rycee",
|
||||
"repo": "nur-expressions",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"locked": {
|
||||
"lastModified": 1761640442,
|
||||
@@ -204,6 +226,7 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"firefox-addons": "firefox-addons",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"nix-darwin": "nix-darwin",
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
# Provides mkFlake: the systems/perSystem scaffolding used below.
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
# Declarative Firefox add-ons (e.g. the Catppuccin theme); see lyrathorpe/user.nix.
|
||||
firefox-addons = {
|
||||
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
@@ -192,12 +197,12 @@
|
||||
];
|
||||
};
|
||||
|
||||
lyrathorpe-x1c = {
|
||||
lyrathorpe-t400 = {
|
||||
system = "x86_64-linux";
|
||||
username = "lyrathorpe";
|
||||
fullName = "Lyra Thorpe";
|
||||
modules = [
|
||||
./system/machine/X1/configuration.nix
|
||||
./system/machine/T400/configuration.nix
|
||||
./system/modules/laptop.nix
|
||||
./lyrathorpe/swaywm.nix
|
||||
];
|
||||
@@ -207,6 +212,22 @@
|
||||
];
|
||||
};
|
||||
|
||||
lyrathorpe-macpro31 = {
|
||||
system = "x86_64-linux";
|
||||
username = "lyrathorpe";
|
||||
fullName = "Lyra Thorpe";
|
||||
portable = false;
|
||||
modules = [
|
||||
./system/machine/MacPro31/configuration.nix
|
||||
./system/modules/desktop.nix
|
||||
./lyrathorpe/swaywm.nix
|
||||
];
|
||||
homeModules = [
|
||||
./lyrathorpe/home
|
||||
./lyrathorpe/home/desktop.nix
|
||||
];
|
||||
};
|
||||
|
||||
emmathorpe-edaas = {
|
||||
system = "x86_64-linux";
|
||||
username = "emmathorpe";
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Catppuccin Mocha palette. Raw 6-digit hex (no leading "#"); consumers add a
|
||||
# "#" where their format needs it. Shared by the Sway desktop theming
|
||||
# (home/sway.nix) and the ReGreet greeter (swaywm.nix) so the two stay in sync.
|
||||
{
|
||||
base = "1e1e2e";
|
||||
mantle = "181825";
|
||||
crust = "11111b";
|
||||
surface0 = "313244";
|
||||
surface1 = "45475a";
|
||||
surface2 = "585b70";
|
||||
overlay0 = "6c7086";
|
||||
subtext0 = "a6adc8";
|
||||
subtext1 = "bac2de";
|
||||
text = "cdd6f4";
|
||||
rosewater = "f5e0dc";
|
||||
red = "f38ba8";
|
||||
maroon = "eba0ac";
|
||||
peach = "fab387";
|
||||
yellow = "f9e2af";
|
||||
green = "a6e3a1";
|
||||
teal = "94e2d5";
|
||||
sapphire = "74c7ec";
|
||||
blue = "89b4fa";
|
||||
mauve = "cba6f7";
|
||||
pink = "f5c2e7";
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
# Keybindings reference
|
||||
|
||||
Every keyboard shortcut configured across this desktop, and where it is defined.
|
||||
Everything here is managed declaratively through Nix — edit the listed file and
|
||||
rebuild, never the generated dotfiles.
|
||||
|
||||
| Area | Defined in |
|
||||
| --- | --- |
|
||||
| Sway (compositor) | [`sway.nix`](./sway.nix) `config.keybindings` + `config.modes`, plus the home-manager Sway module's built-in defaults |
|
||||
| tmux | [`shell.nix`](./shell.nix) `programs.tmux` |
|
||||
| zsh line editor | [`shell.nix`](./shell.nix) `programs.zsh.historySubstringSearch` |
|
||||
| foot (terminal) | foot package defaults — only colours are themed (in `sway.nix`) |
|
||||
|
||||
**Conventions**
|
||||
|
||||
- **Super** is the `Mod4` / logo (Windows/Command) key; **Alt** is `Mod1`.
|
||||
- Letter keys are **keysyms** (the character produced), not physical positions.
|
||||
The keyboard is **Dvorak** (`us`/`dvorak`), so e.g. "Super+s" is whatever key
|
||||
types `s` in Dvorak.
|
||||
- Shortcuts apply to every Sway host (MBP, T400, Mac Pro); brightness keys are
|
||||
laptop-only, as noted.
|
||||
|
||||
---
|
||||
|
||||
## Sway
|
||||
|
||||
### Applications & session
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`Return` | Open a terminal (foot) |
|
||||
| `Super`+`Space` | App launcher (sway-launcher-desktop in a floating foot) |
|
||||
| `Super`+`d` | App launcher (same as above; module default) |
|
||||
| `Super`+`e` | File manager (nemo) |
|
||||
| `Super`+`c` | Clipboard history picker (clipman → fuzzel) |
|
||||
| `Super`+`l` | Lock screen (swaylock) |
|
||||
| `Super`+`Shift`+`q` | Close the focused window |
|
||||
| `Super`+`Shift`+`c` | Reload the Sway config |
|
||||
| `Super`+`Shift`+`e` | Exit Sway (asks for confirmation) |
|
||||
|
||||
### Focus
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`←`/`↓`/`↑`/`→` | Move focus by direction |
|
||||
| `Super`+`h`/`j`/`k` | Move focus left / down / up (vim-style) |
|
||||
| `Super`+`a` | Focus the parent container |
|
||||
| `Super`+`Alt`+`Space` | Toggle focus between tiling and floating |
|
||||
|
||||
> Note: vim focus-right would be `Super`+`l`, but that is bound to **lock** here;
|
||||
> use `Super`+`→`.
|
||||
|
||||
### Moving windows
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`Shift`+`←`/`↓`/`↑`/`→` | Move the window by direction |
|
||||
| `Super`+`Shift`+`h`/`j`/`k`/`l` | Move the window left / down / up / right |
|
||||
| `Super`+`Shift`+`Space` | Toggle the window floating |
|
||||
|
||||
Mouse (with `Super` held): left-drag moves a window, right-drag resizes it.
|
||||
|
||||
### Layout
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`b` | Split horizontally |
|
||||
| `Super`+`v` | Split vertically |
|
||||
| `Super`+`s` | Stacking layout |
|
||||
| `Super`+`w` | Tabbed layout |
|
||||
| `Super`+`f` | Toggle fullscreen |
|
||||
| `Super`+`y` | **Layout submenu**: `s` stacking · `w` tabbed · `e` toggle split · `Return`/`Esc` exit |
|
||||
|
||||
> The layout submenu's `e` (toggle split) is the home for that action since
|
||||
> `Super`+`e` now opens the file manager.
|
||||
|
||||
### Workspaces
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`1`…`0` | Switch to workspace 1…10 |
|
||||
| `Super`+`Shift`+`1`…`0` | Move the window to workspace 1…10 |
|
||||
| `Super`+`z` | Previous workspace |
|
||||
| `Super`+`x` | Next workspace |
|
||||
|
||||
### Scratchpad
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`Shift`+`-` | Move the window to the scratchpad |
|
||||
| `Super`+`-` | Show / cycle the scratchpad |
|
||||
|
||||
### Modes (submenus)
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Super`+`r` | **Resize mode**: arrow keys resize; `Return`/`Esc` exit |
|
||||
| `Super`+`y` | **Layout mode** (see Layout above) |
|
||||
| `Super`+`Shift`+`x` | **Power menu**: `l` lock · `e` log out · `s` sleep · `r` reboot · `Shift`+`s` shutdown · `Return`/`Esc` exit |
|
||||
|
||||
### Screenshots
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Print` | Select a region → swappy (annotate/save) |
|
||||
| `Shift`+`Print` | Focused window → swappy |
|
||||
|
||||
### Audio & media
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `XF86AudioRaiseVolume` / `XF86AudioLowerVolume` | Volume ±5% (wpctl) |
|
||||
| `XF86AudioMute` | Toggle output mute |
|
||||
| `XF86AudioMicMute` | Toggle microphone mute |
|
||||
| `XF86AudioPlay` | Play/pause (playerctl) |
|
||||
| `XF86AudioNext` / `XF86AudioPrev` | Next / previous track |
|
||||
|
||||
### Brightness — laptops only
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `XF86MonBrightnessUp` / `XF86MonBrightnessDown` | Backlight ±5% (brightnessctl) |
|
||||
|
||||
Present only on portable hosts (T400, MBP); desktops have no internal backlight.
|
||||
|
||||
---
|
||||
|
||||
## tmux
|
||||
|
||||
Prefix is **`Ctrl`+`b`** (default). Copy mode uses **vi** keys.
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Ctrl`+`b` then `v` | Split into left/right panes |
|
||||
| `Ctrl`+`b` then `s` | Split into top/bottom panes |
|
||||
| `Alt`+`←`/`→`/`↑`/`↓` | Switch pane by direction (no prefix needed) |
|
||||
| `Ctrl`+`b` then `[` | Enter copy mode (then vi motions; `Space`/`Enter` to select/copy) |
|
||||
| `Ctrl`+`b` then `z` | Zoom / unzoom the focused pane |
|
||||
| `Ctrl`+`b` then `c` | New window |
|
||||
| `Ctrl`+`b` then `n` / `p` | Next / previous window |
|
||||
| `Ctrl`+`b` then `d` | Detach |
|
||||
| Mouse | Enabled — click to focus, drag borders, scroll, select |
|
||||
|
||||
> The stock split keys `%` and `"` are unbound; use `v` / `s` above. `Ctrl`+`b`
|
||||
> then `s` is therefore a split, not the session tree.
|
||||
|
||||
---
|
||||
|
||||
## foot (terminal)
|
||||
|
||||
Only colours are themed; these are foot's default key bindings.
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `Ctrl`+`Shift`+`c` / `Ctrl`+`Shift`+`v` | Copy / paste (clipboard) |
|
||||
| `Shift`+`Insert` | Paste primary selection |
|
||||
| `Ctrl`+`Shift`+`r` | Search scrollback |
|
||||
| `Ctrl`+`+` / `Ctrl`+`-` / `Ctrl`+`0` | Font larger / smaller / reset |
|
||||
| `Ctrl`+`Shift`+`u` | URL mode (jump to/open links) |
|
||||
| `Ctrl`+`Shift`+`n` | Spawn a new terminal |
|
||||
| `Shift`+`PageUp` / `Shift`+`PageDown` | Scroll back / forward |
|
||||
|
||||
---
|
||||
|
||||
## zsh
|
||||
|
||||
| Shortcut | Action |
|
||||
| --- | --- |
|
||||
| `↑` / `↓` | History **substring** search — type a fragment first, then the arrows cycle matching past commands |
|
||||
|
||||
Bound for both CSI and SS3 cursor sequences, so it works in foot, iTerm2 and
|
||||
the Linux TTY alike.
|
||||
+64
-10
@@ -1,7 +1,14 @@
|
||||
# Graphical desktop layer: GUI apps, Wayland session env, cursor theme, and the
|
||||
# tty1 Sway autostart. Imported only on hosts that run Sway (MBP, X1); never
|
||||
# pulled onto the headless WSL host.
|
||||
{ pkgs, lib, ... }:
|
||||
# Graphical desktop layer: GUI apps, Wayland session env, and cursor theme.
|
||||
# Imported only on hosts that run Sway (MBP, T400, Mac Pro); never pulled onto
|
||||
# the headless WSL host. Login (and the Sway session launch) is handled by the
|
||||
# greetd/ReGreet greeter -- see ../swaywm.nix -- so there is no tty1 autostart.
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
username,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./sway.nix
|
||||
@@ -10,6 +17,7 @@
|
||||
home.packages = [
|
||||
pkgs.element-desktop
|
||||
pkgs.legcord
|
||||
pkgs.nemo # file manager (launched via Mod+e, see ./sway.nix)
|
||||
#pkgs.plex-desktop
|
||||
#pkgs.plexamp
|
||||
];
|
||||
@@ -19,6 +27,32 @@
|
||||
XDG_CURRENT_DESKTOP = "sway";
|
||||
};
|
||||
|
||||
# Theme GTK apps (nemo, etc.) to match the Catppuccin Mocha desktop. Under
|
||||
# Sway there is no XSettings daemon, so GTK reads these from the generated
|
||||
# ~/.config/gtk-{3,4}.0/settings.ini directly. The Mocha theme is dark by
|
||||
# design, so no separate prefer-dark hint is needed.
|
||||
gtk = {
|
||||
enable = true;
|
||||
# Theme GTK4 apps too (for any added later). GTK4 ignores gtk-theme-name,
|
||||
# but home-manager turns this into an `@import` of the theme's
|
||||
# gtk-4.0/gtk.css into ~/.config/gtk-4.0/gtk.css -- which even libadwaita
|
||||
# honours, since that file overrides the named colours it uses
|
||||
# (window_bg_color, accent_bg_color, ...). Set explicitly (same value as the
|
||||
# legacy default) so it also silences the stateVersion<26.05 warning.
|
||||
gtk4.theme = config.gtk.theme;
|
||||
theme = {
|
||||
name = "catppuccin-mocha-blue-standard";
|
||||
package = pkgs.catppuccin-gtk.override {
|
||||
accents = [ "blue" ];
|
||||
variant = "mocha";
|
||||
};
|
||||
};
|
||||
iconTheme = {
|
||||
name = "Adwaita";
|
||||
package = pkgs.adwaita-icon-theme;
|
||||
};
|
||||
};
|
||||
|
||||
home.pointerCursor = {
|
||||
gtk.enable = true;
|
||||
x11 = {
|
||||
@@ -30,10 +64,30 @@
|
||||
size = 24;
|
||||
};
|
||||
|
||||
# Start Sway automatically on the first virtual terminal.
|
||||
programs.zsh.initContent = lib.mkOrder 1500 ''
|
||||
if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then
|
||||
exec sway
|
||||
fi
|
||||
'';
|
||||
# Firefox is themed at the browser level (it does not follow the GTK theme).
|
||||
# The system installs the binary (programs.firefox in ../user.nix); here
|
||||
# home-manager owns only the profile, hence package = null. Apply the
|
||||
# Catppuccin Mocha theme add-on (only the mauve accent is packaged upstream;
|
||||
# the rest of the desktop uses blue) and make content + UI dark.
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
package = null;
|
||||
profiles.${username} = {
|
||||
id = 0;
|
||||
isDefault = true;
|
||||
extensions = {
|
||||
force = true;
|
||||
packages = [
|
||||
inputs.firefox-addons.packages.${pkgs.system}.catppuccin-mocha-mauve
|
||||
];
|
||||
};
|
||||
settings = {
|
||||
# Enable bundled add-ons automatically so the theme applies on first run.
|
||||
"extensions.autoDisableScopes" = 0;
|
||||
# Dark chrome + dark page content.
|
||||
"ui.systemUsesDarkTheme" = 1;
|
||||
"layout.css.prefers-color-scheme.content-override" = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,21 @@
|
||||
enableCompletion = true;
|
||||
enableVteIntegration = true;
|
||||
autosuggestion.enable = true;
|
||||
historySubstringSearch.enable = true;
|
||||
# Bind Up/Down for history-substring-search in BOTH cursor-key modes: CSI
|
||||
# (^[[A/^[[B -- normal mode, and what the Linux TTY sends) and SS3
|
||||
# (^[OA/^[OB -- application mode, used by foot, tmux and iTerm2). Binding
|
||||
# only the default CSI form leaves it dead at the prompt in foot/iTerm2.
|
||||
historySubstringSearch = {
|
||||
enable = true;
|
||||
searchUpKey = [
|
||||
"^[[A"
|
||||
"^[OA"
|
||||
];
|
||||
searchDownKey = [
|
||||
"^[[B"
|
||||
"^[OB"
|
||||
];
|
||||
};
|
||||
history.append = true;
|
||||
oh-my-zsh = {
|
||||
enable = true;
|
||||
@@ -17,9 +31,7 @@
|
||||
theme = "robbyrussell";
|
||||
};
|
||||
syntaxHighlighting.enable = true;
|
||||
# Prefix the prompt with the hostname over SSH. The graphical autostart
|
||||
# (exec sway on tty1) lives in ./desktop.nix so it never runs on headless
|
||||
# hosts.
|
||||
# Prefix the prompt with the hostname over SSH.
|
||||
initContent = lib.mkOrder 1500 ''
|
||||
if [ "$SSH_CLIENT" ] || [ "$SSH_TTY" ]; then
|
||||
export PS1="%M $PS1"
|
||||
@@ -36,14 +48,33 @@
|
||||
terminal = "tmux-direct";
|
||||
newSession = true;
|
||||
keyMode = "vi";
|
||||
historyLimit = 50000;
|
||||
historyLimit = 500000;
|
||||
mouse = true;
|
||||
# `reverseSplit = true` already binds s -> vertical and v -> horizontal
|
||||
# split (the dotfiles' vim-style splits).
|
||||
extraConfig = ''
|
||||
# Run a non-login shell in new panes/windows.
|
||||
set -g default-command "''${SHELL}"
|
||||
|
||||
# Drop the stock split keys in favour of the s/v binds above.
|
||||
unbind %
|
||||
unbind '"'
|
||||
|
||||
# Alt+Arrow pane navigation
|
||||
bind -n M-Left select-pane -L
|
||||
bind -n M-Right select-pane -R
|
||||
bind -n M-Up select-pane -U
|
||||
bind -n M-Down select-pane -D
|
||||
|
||||
# Tell tmux which capabilities the foot terminal supports, so truecolor,
|
||||
# synchronised output, the system clipboard (OSC 52), window titles and
|
||||
# cursor styling all pass through.
|
||||
set -as terminal-features ",foot*:RGB"
|
||||
set -as terminal-features ",foot*:sync"
|
||||
set -as terminal-features ",foot*:clipboard"
|
||||
set -as terminal-features ",foot*:title"
|
||||
set -as terminal-features ",foot*:ccolour"
|
||||
set -as terminal-features ",foot*:cstyle"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
+303
-7
@@ -14,6 +14,25 @@
|
||||
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 ../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;
|
||||
@@ -26,7 +45,54 @@
|
||||
# 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";
|
||||
|
||||
input."type:keyboard".xkb_layout = "dvorak";
|
||||
# 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 = [
|
||||
{
|
||||
@@ -35,6 +101,33 @@
|
||||
}
|
||||
];
|
||||
|
||||
# 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";
|
||||
@@ -46,16 +139,83 @@
|
||||
];
|
||||
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";
|
||||
"Print" = "exec ${pkgs.grim}/bin/grim ~/screenshot-$(date +%F-%H%M%S).png";
|
||||
|
||||
# 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 {
|
||||
@@ -66,13 +226,114 @@
|
||||
};
|
||||
};
|
||||
|
||||
programs.swaylock = {
|
||||
# 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 = {
|
||||
# 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;
|
||||
|
||||
# fuzzel: the dmenu picker used by clipman, themed Catppuccin Mocha to match
|
||||
# (fuzzel colours are RRGGBBAA -- 8 hex digits).
|
||||
programs.fuzzel = {
|
||||
enable = true;
|
||||
settings = {
|
||||
color = "1e1e2e";
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -98,16 +359,30 @@
|
||||
|
||||
services.dunst = {
|
||||
enable = true;
|
||||
# Catppuccin Mocha notifications (dunst colours need a leading "#").
|
||||
settings = {
|
||||
global = {
|
||||
font = "Noto Sans 11";
|
||||
frame_color = "#89b4fa";
|
||||
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 = {
|
||||
frame_color = "#fab387";
|
||||
background = "#${ctp.base}";
|
||||
foreground = "#${ctp.text}";
|
||||
frame_color = "#${ctp.peach}";
|
||||
timeout = 0;
|
||||
};
|
||||
};
|
||||
@@ -116,8 +391,29 @@
|
||||
programs.i3status-rust = {
|
||||
enable = true;
|
||||
bars.default = {
|
||||
theme = "gruvbox-dark";
|
||||
# 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";
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
let
|
||||
cfg = config.features.swayDesktop;
|
||||
# Catppuccin Mocha (shared with the Sway desktop, see lyrathorpe/home/sway.nix).
|
||||
ctp = import ./catppuccin-mocha.nix;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@@ -35,6 +37,10 @@ in
|
||||
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
|
||||
];
|
||||
@@ -45,6 +51,104 @@ in
|
||||
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 = {
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
# Asahi manages the EFI vars from macOS; do not touch them from NixOS.
|
||||
# UEFI boot via systemd-boot. Asahi manages the EFI vars from macOS, so do not
|
||||
# touch them from NixOS.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
|
||||
networking.hostName = "Emma-Asahi";
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Mac Pro 3,1 (Early 2008) — install notes
|
||||
|
||||
Flake host: `lyrathorpe-macpro31`. Desktop (`portable = false`, imports
|
||||
`../../modules/desktop.nix`). Files: `configuration.nix`,
|
||||
`hardware-configuration.nix`.
|
||||
|
||||
## Hardware configuration
|
||||
|
||||
`hardware-configuration.nix` here is a hand-written **placeholder**. On the real
|
||||
machine, run `nixos-generate-config`, replace the file, and commit it. It assumes
|
||||
by-label partitions — ESP `ESP` (vfat, mounted at `/boot`), root `nixos` (ext4),
|
||||
and `swap` — so either label them at install time or swap in the generated UUIDs.
|
||||
|
||||
## Bootloader
|
||||
|
||||
The Mac Pro 3,1 has **64-bit EFI**, so it uses **systemd-boot** (no GRUB/CSM
|
||||
shim). `canTouchEfiVariables = false` because Apple's firmware does not reliably
|
||||
accept `efibootmgr` NVRAM writes.
|
||||
|
||||
Apple-EFI quirk: if the firmware boot picker does not show NixOS after install,
|
||||
either
|
||||
|
||||
- uncomment `boot.loader.efi.efiInstallAsRemovable = true;` in
|
||||
`configuration.nix` (installs the fallback `\EFI\BOOT\BOOTX64.EFI`), and/or
|
||||
- "bless" the ESP from macOS.
|
||||
|
||||
Partition the disk GPT with an ESP (vfat).
|
||||
|
||||
## Graphics
|
||||
|
||||
The stock card varies between units — **ATI Radeon HD 2600 XT** or **NVIDIA
|
||||
GeForce 8800 GT**. No proprietary driver is hardcoded; Sway relies on in-tree KMS:
|
||||
|
||||
- ATI Radeon HD 2600 XT → `radeon` (or `amdgpu`) KMS
|
||||
- NVIDIA GeForce 8800 GT → `nouveau` KMS
|
||||
|
||||
These come up automatically. If a card needs forcing, set
|
||||
`services.xserver.videoDrivers` and/or add the module to
|
||||
`boot.initrd.kernelModules` for early KMS (see the comment in
|
||||
`configuration.nix`).
|
||||
|
||||
## Networking
|
||||
|
||||
Wired Ethernet via NetworkManager (from `desktop.nix`) — the Mac Pro has two
|
||||
gigabit ports.
|
||||
|
||||
## Login
|
||||
|
||||
Graphical login via a Wayland greeter — `greetd` running ReGreet inside the
|
||||
`cage` kiosk compositor — configured centrally in `lyrathorpe/swaywm.nix` for
|
||||
every Sway host (gated on `features.swayDesktop.enable`). The greeter is forced
|
||||
to the Dvorak layout to match the console and Sway session. Set the user
|
||||
password (`passwd lyrathorpe`) after install, or the greeter cannot
|
||||
authenticate. Requires working KMS (radeon/nouveau — see Graphics).
|
||||
|
||||
## Apply
|
||||
|
||||
```sh
|
||||
sudo nixos-rebuild switch --flake .#lyrathorpe-macpro31
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
# Apple Mac Pro 3,1 (Early 2008, dual Xeon Harpertown, x86_64). Desktop host:
|
||||
# shared graphical/wired options live in ../../modules/desktop.nix; only
|
||||
# host-specific settings are here. Install notes (EFI booting, GPU, partitions):
|
||||
# see ./README.md.
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
# The Mac Pro 3,1 has 64-bit EFI (confirmed by the owner), so boot via
|
||||
# systemd-boot like the MBP -- no GRUB/BIOS shim needed.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
# Apple's EFI does not reliably support efibootmgr NVRAM writes; leave the
|
||||
# firmware vars untouched.
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
# Apple-EFI quirk: if the Mac does not pick up the bootloader at the boot
|
||||
# picker, install it to the fallback path \EFI\BOOT\BOOTX64.EFI and/or
|
||||
# "bless" the ESP from macOS. Uncomment to write the removable fallback path:
|
||||
# boot.loader.efi.efiInstallAsRemovable = true;
|
||||
|
||||
networking.hostName = "MacPro31-NixOS";
|
||||
|
||||
# This host accepts SSH, so open 22 (the firewall itself is enabled in
|
||||
# workstation.nix with a default-deny policy).
|
||||
services.openssh.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
pulse.enable = true;
|
||||
};
|
||||
|
||||
# No fingerprint hardware; empty service still lets swaylock authenticate via
|
||||
# password.
|
||||
security.pam.services.swaylock = { };
|
||||
|
||||
# Dual Harpertown Xeon microcode + redistributable firmware (e.g. GPU/NIC
|
||||
# blobs).
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
# GPU note: the stock card varies between units -- ATI Radeon HD 2600 XT or
|
||||
# NVIDIA GeForce 8800 GT. Sway needs a working KMS/modesetting driver; do NOT
|
||||
# install a proprietary blob here. Depending on the installed card, rely on
|
||||
# the open kernel driver:
|
||||
# - ATI Radeon HD 2600 XT -> "radeon" (older) or "amdgpu" KMS
|
||||
# - NVIDIA GeForce 8800 GT -> "nouveau" KMS
|
||||
# These come up automatically via the in-tree drivers + KMS, and the graphics
|
||||
# stack itself is enabled by swaywm.nix. If a card needs to be forced, add it
|
||||
# here, e.g. `services.xserver.videoDrivers = [ "radeon" ];` (or "nouveau"),
|
||||
# and/or `boot.initrd.kernelModules = [ "radeon" ];` in
|
||||
# hardware-configuration.nix for early KMS.
|
||||
|
||||
# See `man configuration.nix` / the stateVersion docs before changing.
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "ahci" "firewire_ohci" "usb_storage" "usbhid" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/mapper/MacPro-Root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/0E9C-C099";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/dec138b4-320f-4b69-acbc-3014a1032cbd"; }
|
||||
];
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
# ThinkPad T400 — install notes
|
||||
|
||||
Flake host: `lyrathorpe-t400`. Files: `configuration.nix`, the `boot-*.nix`
|
||||
variants, and `hardware-configuration.nix`.
|
||||
|
||||
## Hardware configuration
|
||||
|
||||
`hardware-configuration.nix` here is a hand-written **placeholder**. On the real
|
||||
machine, run `nixos-generate-config`, replace the file, and commit it. It assumes
|
||||
by-label partitions — root `nixos` (ext4) and `swap` — so either label them at
|
||||
install time or swap in the generated UUIDs.
|
||||
|
||||
## Bootloader — import the module matching the flashed firmware
|
||||
|
||||
`configuration.nix` imports exactly one boot module. Default is `boot-bios.nix`;
|
||||
switch by commenting it out and uncommenting the relevant alternative.
|
||||
|
||||
| Firmware | Module | Notes |
|
||||
| --- | --- | --- |
|
||||
| Stock Lenovo BIOS, or coreboot + **SeaBIOS** payload | `boot-bios.nix` | GRUB on the MBR. Set `device` to the real install disk (`/dev/sda` by default). MBR/legacy layout. |
|
||||
| coreboot + **GRUB** payload | `boot-coreboot-grub.nix` | GRUB is config-only (`device = "nodev"`); NixOS does **not** write to a disk. Your coreboot `grub.cfg` (in the flash chip) must `search` for and `configfile` the on-disk `/boot/grub/grub.cfg`, or chainload the disk's GRUB. |
|
||||
| coreboot + **Tianocore/edk2 (UEFI)** payload | `boot-coreboot-uefi.nix` | systemd-boot. `canTouchEfiVariables = true` (coreboot honours NVRAM writes). The module **declares its own ESP** (`/boot` vfat, label `ESP`) — when you regenerate `hardware-configuration.nix`, do **not** let it also define `/boot`. Create + label an `ESP` vfat partition (GPT). |
|
||||
|
||||
## Graphics
|
||||
|
||||
This unit has the optional **discrete ATI Mobility Radeon HD 3470 (RV620)**. The
|
||||
open `radeon` KMS driver is loaded in the initrd for early modesetting; firmware
|
||||
comes from `enableRedistributableFirmware`.
|
||||
|
||||
The T400 has switchable graphics (discrete ATI + Intel GMA 4500MHD). Select
|
||||
**Discrete** in the firmware's graphics setting so only the ATI is live. If you
|
||||
run **Integrated** instead, the Intel `i915` driver takes over with no config
|
||||
change and `radeon` stays idle.
|
||||
|
||||
## Login
|
||||
|
||||
Graphical login via a Wayland greeter — `greetd` running ReGreet inside the
|
||||
`cage` kiosk compositor — configured centrally in `lyrathorpe/swaywm.nix` for
|
||||
every Sway host (gated on `features.swayDesktop.enable`). The greeter is forced
|
||||
to the Dvorak layout to match the console and Sway session. Set the user
|
||||
password (`passwd lyrathorpe`) after install, or the greeter cannot
|
||||
authenticate. Requires working radeon/i915 KMS (see Graphics).
|
||||
|
||||
## Apply
|
||||
|
||||
```sh
|
||||
sudo nixos-rebuild switch --flake .#lyrathorpe-t400
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
# Boot via legacy BIOS -- the stock Lenovo BIOS, or coreboot with the SeaBIOS
|
||||
# payload (both present a legacy BIOS interface). GRUB is installed to the MBR of
|
||||
# the boot disk. This is the default.
|
||||
{ ... }:
|
||||
{
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
# Must point at the actual install disk -- adjust if it is not /dev/sda.
|
||||
device = "/dev/sda";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Boot via coreboot's GRUB payload (e.g. libreboot default). The GRUB in the
|
||||
# flash chip reads the grub.cfg that NixOS generates on disk, so GRUB here is
|
||||
# config-only -- it is NOT installed to any disk MBR (`device = "nodev"`).
|
||||
#
|
||||
# Your coreboot grub.cfg must locate and load the on-disk config, e.g. search
|
||||
# for and `configfile` /boot/grub/grub.cfg (or chainload the disk's GRUB).
|
||||
{ ... }:
|
||||
{
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
device = "nodev";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Boot via coreboot's Tianocore/edk2 (UEFI) payload. This turns the T400 into a
|
||||
# real UEFI machine, so use systemd-boot. Unlike Apple's firmware, coreboot's
|
||||
# UEFI honours EFI variable writes, so canTouchEfiVariables is on.
|
||||
#
|
||||
# Requires an EFI System Partition. It is declared here so it travels with this
|
||||
# boot mode; the generated hardware-configuration.nix should NOT also define
|
||||
# /boot. Label the ESP `ESP` at install, or replace with the generated UUID.
|
||||
{ ... }:
|
||||
{
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-label/ESP";
|
||||
fsType = "vfat";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
# ThinkPad T400 (NixOS). Shared laptop options live in ../../modules/laptop.nix;
|
||||
# only host-specific settings are here. Install notes (boot variants, GPU,
|
||||
# partitions): see ./README.md.
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
# Boot: import exactly ONE, matching the firmware currently flashed.
|
||||
# Stock Lenovo BIOS and coreboot+SeaBIOS both use boot-bios.nix.
|
||||
./boot-bios.nix
|
||||
# ./boot-coreboot-grub.nix # coreboot with the GRUB payload (config-only GRUB)
|
||||
# ./boot-coreboot-uefi.nix # coreboot with the Tianocore/edk2 UEFI payload
|
||||
# # (systemd-boot; carries its own ESP mount)
|
||||
];
|
||||
|
||||
networking.hostName = "T400-NixOS";
|
||||
|
||||
console.font = "Lat2-Terminus16";
|
||||
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
pulse.enable = true;
|
||||
};
|
||||
|
||||
# This host accepts SSH, so open 22 (the firewall itself is enabled in
|
||||
# laptop.nix with a default-deny policy).
|
||||
services.openssh.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||
|
||||
# The T400's fingerprint reader differs/may be absent; empty service still
|
||||
# lets swaylock authenticate via password.
|
||||
security.pam.services.swaylock = { };
|
||||
|
||||
# Intel Core 2 (Penryn) microcode + redistributable firmware. The latter also
|
||||
# supplies the iwlwifi blobs (Intel WiFi Link 5100/5300) and the radeon
|
||||
# firmware needed by the discrete GPU below.
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
# This T400 has the optional discrete GPU fitted: an ATI Mobility Radeon HD
|
||||
# 3470 (RV620), driven by the open `radeon` KMS driver. Load it in the initrd
|
||||
# for early modesetting (clean Sway/Wayland start); firmware comes from
|
||||
# enableRedistributableFirmware above.
|
||||
#
|
||||
# The T400 has switchable graphics (this discrete GPU + the Intel GMA
|
||||
# 4500MHD). Select "Discrete" in the firmware's graphics setting so only the
|
||||
# ATI is live; if you instead run "Integrated", the Intel i915 driver takes
|
||||
# over with no extra config and `radeon` simply stays idle.
|
||||
boot.initrd.kernelModules = [ "radeon" ];
|
||||
|
||||
# See `man configuration.nix` / the stateVersion docs before changing.
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# PLACEHOLDER -- hand-written, not machine-generated. Regenerate on the real
|
||||
# T400 with `nixos-generate-config` and commit the result. The device labels
|
||||
# below are guesses; replace them with the generated UUIDs (or label the
|
||||
# partitions accordingly at install time).
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ahci"
|
||||
"ata_piix"
|
||||
"ehci_pci"
|
||||
"uhci_hcd"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# Label your root partition `nixos` at install, or replace with the generated UUID.
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-label/nixos";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{ device = "/dev/disk/by-label/swap"; }
|
||||
];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# ThinkPad X1 (NixOS). Shared laptop options live in ../../modules/laptop.nix;
|
||||
# only host-specific settings are here.
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
networking.hostName = "X1-NixOS";
|
||||
networking.domain = "client.cbg.emmaisvery.gay";
|
||||
|
||||
console.font = "Lat2-Terminus16";
|
||||
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
pulse.enable = true;
|
||||
};
|
||||
|
||||
# This host accepts SSH, so open 22 (the firewall itself is enabled in
|
||||
# laptop.nix with a default-deny policy).
|
||||
services.openssh.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||
|
||||
# Fingerprint reader: allow swaylock to authenticate via fprintd.
|
||||
services.fprintd.enable = true;
|
||||
security.pam.services.swaylock.fprintAuth = true;
|
||||
|
||||
# See `man configuration.nix` / the stateVersion docs before changing.
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/a7145534-b122-4899-a75a-3d2e78474d6b";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/1338-3D4F";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/e553c8dc-9d5a-48ec-87bc-9c86ce5932a4"; }
|
||||
];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wwan0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
# Form-factor-agnostic base for the physical graphical NixOS machines. Imported
|
||||
# by both ./laptop.nix and ./desktop.nix; those add only the bits that differ
|
||||
# between portable and desktop hosts (chiefly the networking backend).
|
||||
#
|
||||
# The bootloader is NOT set here -- it is firmware-specific, not form-factor:
|
||||
# UEFI hosts (MBP, Mac Pro 3,1) use systemd-boot, the BIOS-only T400 uses GRUB.
|
||||
# Each machine config declares its own.
|
||||
{ ... }:
|
||||
{
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
||||
features.swayDesktop.enable = true;
|
||||
|
||||
console.keyMap = "dvorak";
|
||||
|
||||
Reference in New Issue
Block a user