···11+let
22+ # ── Single-source font primitives ─────────────────────────────────────────
33+ # Change a name here and Konsole, KDE, and VS Code all update at once.
44+ monoFontBase = "FiraCode"; # root font family name
55+ monoFontFamily = "${monoFontBase} Nerd Font Mono"; # full name for KDE / Konsole
66+ monoFontSize = 11;
77+88+ uiFont = "Noto Sans"; # closest open-source match to macOS San Francisco
99+ uiFontSize = 10;
1010+in
111{
212 # Desktop environment configuration (Linux)
33-44- enable = true;
55-66- # Desktop environment
77- environment = "plasma6"; # "gnome", "plasma6", "xfce", etc.
88-99- # Display manager
1010- displayManager = "sddm"; # "gdm", "sddm", "lightdm", etc.
1313+ enable = true;
1414+ environment = "plasma6"; # "gnome" | "plasma6" | "xfce"
1515+ displayManager = "sddm"; # "gdm" | "sddm" | "lightdm"
11161217 # GTK/Qt theming
1318 theme = "Catppuccin-Mocha-Standard-Green-Dark";
1419 iconTheme = "Papirus-Dark";
15201616- # Monospace font (used in Konsole, terminal emulators, IDE configs, etc.)
1717- monoFont = "FiraCode Nerd Font Mono 11";
1818- monoFontConsole = "FiraCode Nerd Font Mono 11"; # Konsole uses the same font name as the system
2121+ # ── Font primitives — single source of truth ──────────────────────────────
2222+ # All consumers (KDE font roles, Konsole, VS Code) reference these;
2323+ # nothing below is ever hardcoded elsewhere.
2424+ inherit uiFont uiFontSize monoFontBase monoFontFamily monoFontSize;
19252020- # KDE Plasma-specific settings
2626+ # Computed composites — derived, never typed twice
2727+ monoFont = "${monoFontFamily} ${toString monoFontSize}"; # "FiraCode Nerd Font Mono 11"
2828+ monoFontConsole = monoFontFamily; # Konsole font.name = family only (no trailing size)
2929+3030+ # ── KDE Plasma-specific settings ───────────────────────────────────────────
2131 plasma = {
3232+ # Color scheme applied by plasma-apply-colorscheme on login.
3333+ # Mirrors macOS: NSGlobalDomain.AppleInterfaceStyle = "Dark"
3434+ # NSGlobalDomain.AppleAccentColor = 3 (Green)
3535+ colorScheme = "CatppuccinMochaGreen";
3636+3737+ # Plasma desktop style (controls panel/widget chrome).
3838+ desktopTheme = "breeze-dark";
3939+2240 # Packages to exclude from the default KDE Plasma install.
2341 # Must match attribute names under pkgs.kdePackages.
2442 excludePackages = [
2525- "oxygen" # Legacy Oxygen theme – use Breeze/Catppuccin instead
2626- "elisa" # KDE music player – use Spotify instead
4343+ "oxygen" # Legacy Oxygen theme — use Breeze/Catppuccin instead
4444+ "elisa" # KDE music player — use Spotify instead
2745 ];
2846 };
2947}
+22-12
settings/config/development.nix
···11+let
22+ # Pull the font primitives from the single source of truth so VS Code
33+ # stays in sync with KDE/Konsole without hardcoding "FiraCode" twice.
44+ desktop = import ./desktop.nix;
55+66+ # VS Code uses the bare family name (no "Nerd Font Mono" suffix) for the
77+ # editor pane, and the Nerd Font variant (without "Mono") for the terminal.
88+ editorFont = desktop.monoFontBase; # "FiraCode"
99+ terminalFont = "${desktop.monoFontBase} Nerd Font"; # "FiraCode Nerd Font"
1010+in
111{
212 # Development configuration
313···717818 # Theme
919 colorTheme = "Catppuccin Mocha";
1010- iconTheme = "catppuccin-vsc-icons";
2020+ iconTheme = "catppuccin-vsc-icons";
11211212- # Editor appearance
1313- fontFamily = "'FiraCode', 'monospace'";
1414- terminalFontFamily = "'FiraCode Nerd Font'";
1515- fontSize = 14;
1616- terminalFontSize = 13;
1717- lineHeight = 22;
1818- fontLigatures = true;
2222+ # Editor appearance — font strings derived from desktop.nix primitives
2323+ fontFamily = "'${editorFont}', 'monospace'"; # "'FiraCode', 'monospace'"
2424+ terminalFontFamily = "'${terminalFont}'"; # "'FiraCode Nerd Font'"
2525+ fontSize = 14;
2626+ terminalFontSize = 13;
2727+ lineHeight = 22;
2828+ fontLigatures = true;
19292020- # Extensions from nixpkgs (pkgs.vscode-extensions.<publisher>.<n>).
3030+ # Extensions from nixpkgs (pkgs.vscode-extensions.<publisher>.<name>).
2131 # Must match attribute paths in the nixpkgs vscode-extensions set.
2232 extensions = [
2333 # ── Nix ──────────────────────────────────────────────────────────────────
···6575 ];
66766777 # Extensions from the VS Code Marketplace via the nix-vscode-extensions
6868- # overlay (pkgs.vscode-marketplace.<publisher>.<n>).
7878+ # overlay (pkgs.vscode-marketplace.<publisher>.<name>).
6979 # Use this for extensions not packaged in base nixpkgs 25.11.
7080 marketplaceExtensions = [
7171- "golang.go" # Go language support (requires gopls on PATH)
7272- "svelte.svelte-vscode" # Svelte language server
8181+ "golang.go" # Go language support (requires gopls on PATH)
8282+ "svelte.svelte-vscode" # Svelte language server
7383 "ms-vscode.makefile-tools" # Makefile syntax, build targets, IntelliSense
7484 ];
7585 };
+49-50
settings/config/shell.nix
···11{
22 # Shell configuration
33-33+44 # Common aliases
55 aliases = {
66 # Modern CLI replacements
77- ls = "eza --icons";
88- ll = "eza -l --icons --git";
99- la = "eza -la --icons --git";
1010- lt = "eza --tree --level=2 --icons";
77+ ls = "eza --icons";
88+ ll = "eza -l --icons --git";
99+ la = "eza -la --icons --git";
1010+ lt = "eza --tree --level=2 --icons";
1111 cat = "bat";
1212-1212+1313 # Navigation
1414- ".." = "cd ..";
1515- "..." = "cd ../..";
1414+ ".." = "cd ..";
1515+ "..." = "cd ../..";
1616 "...." = "cd ../../..";
1717-1717+1818 # Safety nets
1919 rm = "rm -i";
2020 cp = "cp -i";
2121 mv = "mv -i";
2222-2222+2323 # Shortcuts
2424 h = "history";
2525 c = "clear";
2626 e = "$EDITOR";
2727-2727+2828 # Disk usage
2929 du1 = "du -h -d 1";
3030- df = "df -h";
3131-3030+ df = "df -h";
3131+3232 # Git shortcuts (use lazygit for TUI)
3333 lg = "lazygit";
3434 };
3535-3535+3636 # Git aliases
3737 gitAliases = {
3838 # Status and info
3939- gs = "git status";
4040- gss = "git status -s"; # Short status
4141- gl = "git log --oneline --graph --decorate";
4242-3939+ gs = "git status";
4040+ gss = "git status -s"; # Short status
4141+ gl = "git log --oneline --graph --decorate";
4242+4343 # Adding and committing
4444- ga = "git add";
4545- gaa = "git add -A"; # Add all
4646- gc = "git commit";
4747- gcm = "git commit -m"; # Commit with message
4444+ ga = "git add";
4545+ gaa = "git add -A"; # Add all
4646+ gc = "git commit";
4747+ gcm = "git commit -m"; # Commit with message
4848 gca = "git commit --amend";
4949-4949+5050 # Pushing and pulling
5151- gp = "git push";
5252- gpf = "git push --force-with-lease"; # Safer force push
5151+ gp = "git push";
5252+ gpf = "git push --force-with-lease"; # Safer force push
5353 gpl = "git pull";
5454- gpr = "git pull --rebase"; # Pull with rebase
5555-5454+ gpr = "git pull --rebase"; # Pull with rebase
5555+5656 # Branching
5757- gb = "git branch";
5757+ gb = "git branch";
5858 gco = "git checkout";
5959- gcb = "git checkout -b"; # Create and checkout branch
6060-5959+ gcb = "git checkout -b"; # Create and checkout branch
6060+6161 # Diffs
6262- gd = "git diff";
6262+ gd = "git diff";
6363 gds = "git diff --staged";
6464 };
6565-6666- # Linux-specific aliases
6767- linuxAliases = {
6868- # nrs/nrb/nrt defined dynamically based on hostname
6969- cleanup = "sudo nix-collect-garbage -d && nix-collect-garbage -d";
6565+6666+ # ── Nix tool aliases — shared by both platforms ───────────────────────────
6767+ # Any alias present on both Linux and macOS belongs here exactly once.
6868+ # Platform-specific aliases (cleanup, nrs/nrb/nrt) stay in their sections.
6969+ nixToolAliases = {
7070 flake-bump = "nix run ~/.config/nix-config/tools#flake-bump";
7171 gen-diff = "nix run ~/.config/nix-config/tools#gen-diff";
7272 health-check = "nix run ~/.config/nix-config/tools#health-check";
7373- # Removed: backup-gde (gnome-export retired — dconf now fully declarative)
7474- # Removed: secrets-setup (was a stub; health-check covers the age key check)
7373+ };
7474+7575+ # Linux-specific aliases
7676+ linuxAliases = {
7777+ # nixToolAliases are merged by zsh.nix — only put Linux-only entries here
7878+ cleanup = "sudo nix-collect-garbage -d && nix-collect-garbage -d";
7579 };
7676-8080+7781 # macOS-specific aliases
7882 darwinAliases = {
7979- # nrs/nrt defined dynamically based on hostname
8080- cleanup = "sudo nix-collect-garbage -d";
8181- flake-bump = "nix run ~/.config/nix-config/tools#flake-bump";
8282- gen-diff = "nix run ~/.config/nix-config/tools#gen-diff";
8383- health-check = "nix run ~/.config/nix-config/tools#health-check";
8484- # Removed: backup-dde (darwin-export retired — macOS settings now fully declarative)
8585- # Removed: secrets-setup (was a stub; health-check covers the age key check)
8383+ # nixToolAliases are merged by zsh.nix — only put macOS-only entries here
8484+ cleanup = "sudo nix-collect-garbage -d";
8685 };
8787-8686+8887 # History configuration
8988 history = {
9090- size = 10000;
9191- saveSize = 10000;
9292- file = "~/.zsh_history";
8989+ size = 10000;
9090+ saveSize = 10000;
9191+ file = "~/.zsh_history";
9392 ignoreDups = true;
9493 };
9594}
+275-157
settings/plasma/default.nix
···11##############################################################################
22-# Declarative KDE Plasma 6 settings via plasma-manager.
22+# Declarative KDE Plasma 6 settings — macOS-inspired layout.
33#
44# Philosophy:
55# ✓ Only include values that express a deliberate preference
66# ✗ No window positions, sidebar widths, last-opened panels, or scroll state
77# ✗ No machine-specific paths or device UUIDs
88# ✗ No internal migration flags or analytics timestamps
99-# ✗ No duplicates of keys already set by home/programs/kde.nix
1010-# (wallpaper, fonts, icon theme — those come from settings/config/desktop.nix)
119#
1212-# Settings are mirrored from settings/darwin/default.nix wherever possible,
1313-# so behaviour matches the macmini as closely as KDE allows.
1010+# All font families, sizes, color schemes, and icon themes come from
1111+# settings/config/desktop.nix — never hardcoded here.
1212+# Wallpaper and the Konsole profile live in home/programs/kde.nix.
1413#
1514# macOS-like layout:
1616-# ┌─────────────────────────────────────────────────────┐
1717-# │ [NixLogo] [App Menu — File Edit View …] [Tray][🕐] │ ← top menu bar
1818-# ├─────────────────────────────────────────────────────┤
1919-# │ desktop / windows │
2020-# │ ╔══════════════════════════════════════════════╗ │
2121-# │ ║ 🐬 📡 📝 🎵 🎮 💬 🦊 💻 ║ │ ← always-visible dock
2222-# │ ╚══════════════════════════════════════════════╝ │
2323-# └─────────────────────────────────────────────────────┘
1515+# ┌─────────────────────────────────────────────────────────────────┐
1616+# │ [NixLogo] [File Edit View …] [Tray extras] [🕐] │ ← 28px menu bar
1717+# ├─────────────────────────────────────────────────────────────────┤
1818+# │ desktop / windows │
1919+# │ ╔═══════════════════════════════════════════════════════════╗ │
2020+# │ ║ 🐬 📡 📝 🎵 🎮 💬 🦊 💻 ║ │ ← floating dock
2121+# │ ╚═══════════════════════════════════════════════════════════╝ │
2222+# └─────────────────────────────────────────────────────────────────┘
2423#
2525-# After editing, run `nixos-rebuild switch` to apply.
2424+# After editing: nixos-rebuild switch (or home-manager switch)
2625##############################################################################
2727-{ lib, ... }:
2626+{ lib, cfgLib, ... }:
28272828+let
2929+ cfg = cfgLib.cfg;
3030+ d = cfg.desktop; # shorthand
3131+in
2932{
3033 programs.plasma = {
31343235 # ── Input – keyboard ───────────────────────────────────────────────────────
3333- # Mac: InitialKeyRepeat = 15 (15 × 15ms = 225ms delay before repeat)
3434- # KeyRepeat = 2 (2 × 15ms = 30ms interval → ~33 repeats/s)
3636+ # mac: InitialKeyRepeat = 15 (15 × 15 ms = 225 ms before first repeat)
3737+ # KeyRepeat = 2 (2 × 15 ms = 30 ms → ~33 repeats / second)
3538 input.keyboard = {
3639 numlockOnStartup = "off";
3740 repeatDelay = 225;
···4144 # ── KWin (window manager) ──────────────────────────────────────────────────
4245 kwin = {
43464444- # Four virtual desktops in a single row (macOS Spaces)
4747+ # Four named virtual desktops in one row — analogous to macOS Spaces.
4848+ # mac: "com.apple.spaces"."spans-displays" = 0 (per-display Spaces)
4549 virtualDesktops = {
4646- number = 4;
4747- rows = 1;
5050+ names = [ "Main" "Work" "Media" "Social" ];
5151+ rows = 1;
4852 };
49535050- # Night light
5454+ # Borderless maximised windows — mirrors macOS hiding the titlebar in
5555+ # full-screen mode.
5656+ borderlessMaximizedWindows = true;
5757+5858+ # Night light — constant warm tone at all times.
5959+ # To switch to automatic sunset/sunrise for Birmingham UK, set:
6060+ # mode = "location";
6161+ # location.latitude = "52.48";
6262+ # location.longitude = "-1.89";
5163 nightLight = {
5264 enable = true;
5353- mode = "constantColor";
6565+ mode = "constant"; # valid: "constant" | "location" | "times"
5466 temperature = {
5555- day = 6500;
5656- night = 4000;
6767+ day = 6500; # neutral daylight white
6868+ night = 4000; # warm amber (macOS default ≈ 3700 K)
5769 };
5870 };
59717272+ # Titlebar buttons on the LEFT — mac: close → minimise → maximise
7373+ titlebarButtons.left = [ "close" "minimize" "maximize" ];
7474+ titlebarButtons.right = [];
7575+7676+ # KWin visual effects ────────────────────────────────────────────────────
6077 effects = {
6161- translucency.enable = true; # glass feel while moving/resizing
6262- shakeCursor.enable = false; # macOS doesn't shake cursor to locate it
7878+7979+ # Frosted-glass background behind panels and menus.
8080+ # Mirrors NSVisualEffectView — the ubiquitous blur layer in macOS UI.
8181+ blur = {
8282+ enable = true;
8383+ strength = 7; # 1–15; 7 ≈ macOS vibrancy intensity
8484+ noiseStrength = 0; # no grain — macOS blur is clean
8585+ };
8686+8787+ # Magic Lamp minimise — window squishes into the dock icon.
8888+ # mac: dock.minimize-to-application = true
8989+ minimization = {
9090+ animation = "magiclamp";
9191+ duration = 400; # ms; macOS default ≈ 300–400 ms
9292+ };
9393+9494+ # Glide for window open / close — closest to macOS scale + fade.
9595+ windowOpenClose.animation = "glide";
9696+9797+ # Slide between virtual desktops (macOS Spaces slide animation).
9898+ desktopSwitching = {
9999+ animation = "slide";
100100+ navigationWrapping = false; # macOS does not wrap around Spaces
101101+ };
102102+103103+ # Glass feel while moving / resizing windows.
104104+ translucency.enable = true;
105105+106106+ # macOS does not shake the cursor to locate it.
107107+ shakeCursor.enable = false;
108108+109109+ # macOS never dims inactive windows.
110110+ dimInactive.enable = false;
111111+63112 };
113113+114114+ }; # end kwin
115115+116116+ # ── KWin raw configFile (no first-class plasma-manager option yet) ─────────
117117+ configFile."kwinrc" = {
118118+119119+ # Animation speed: 2 = Fast (KDE default 3 = Normal).
120120+ Compositing.AnimationSpeed = 2;
121121+122122+ # Hot corners — mirrors macOS dock.wvous-* settings exactly:
123123+ # BL → Mission Control (wvous-bl-corner = 2)
124124+ # BR → Show Desktop (wvous-br-corner = 4)
125125+ # TL → None (wvous-tl-corner = 1)
126126+ # TR → Lock Screen (wvous-tr-corner = 5 ≈ Screen Saver)
127127+ ElectricBorders = {
128128+ BottomLeft = "Overview";
129129+ BottomRight = "ShowDesktop";
130130+ TopLeft = "None";
131131+ TopRight = "LockScreen";
132132+ };
133133+64134 };
651356666- # ── Colour scheme and desktop theme ─────────────────────────────────────────
6767- # mac: NSGlobalDomain.AppleInterfaceStyle = "Dark"
6868- # CustomUserPreferences.NSGlobalDomain.AppleAccentColor = 3 (Green)
6969- # workspace.colorScheme sets the Qt/KDE colour palette (kdeglobals).
7070- # The catppuccin home-manager module also sets this via lib.mkDefault;
7171- # being explicit here ensures it is always set, even if that module changes.
7272- workspace.colorScheme = "CatppuccinMochaGreen";
136136+ # ── Workspace ─────────────────────────────────────────────────────────────
137137+ # Wallpaper is set in home/programs/kde.nix (path relative to that file).
138138+ workspace = {
731397474- # Plasma desktop style (plasmarc Theme.name) — controls panel/widget chrome.
7575- # No catppuccin plasma *style* package exists; Breeze Dark is the best base.
7676- workspace.theme = "breeze-dark";
140140+ # Color scheme — from settings/config/desktop.nix.
141141+ # Explicit here so it always wins, even if the catppuccin module changes
142142+ # its lib.mkDefault later.
143143+ colorScheme = d.plasma.colorScheme; # "CatppuccinMochaGreen"
771447878- # ── Window decoration ──────────────────────────────────────────────────────
7979- workspace.windowDecorations = {
8080- theme = "Breeze";
8181- library = "org.kde.breeze";
145145+ # Plasma desktop style — from settings/config/desktop.nix.
146146+ theme = d.plasma.desktopTheme; # "breeze-dark"
147147+148148+ # Icon theme — from settings/config/desktop.nix.
149149+ # Uses the proper API (runs plasma-changeicons on login) instead of the
150150+ # raw configFile."kdeglobals".Icons.Theme approach.
151151+ iconTheme = d.iconTheme; # "Papirus-Dark"
152152+153153+ # Window decorations — Breeze (left-side buttons configured in kwin above).
154154+ windowDecorations = {
155155+ library = "org.kde.breeze";
156156+ theme = "Breeze";
157157+ };
158158+159159+ # No splash screen — macOS shows nothing on login.
160160+ splashScreen.theme = "None";
161161+162162+ # Single-click selects, double-click opens — standard macOS Finder behaviour.
163163+ clickItemTo = "select";
164164+165165+ # Disable middle-click paste — macOS has no X11 primary selection.
166166+ enableMiddleClickPaste = false;
167167+168168+ # Tooltip delay — 500 ms ≈ macOS hover timing (KDE default 700 ms).
169169+ tooltipDelay = 500;
170170+171171+ # Breeze widget style — cleanest, most macOS-like Qt widget rendering.
172172+ widgetStyle = "breeze";
173173+174174+ # Cursor theme — uncomment to use a macOS-inspired cursor.
175175+ # Requires pkgs.capitaine-cursors (or pkgs.apple-cursor) in home.packages.
176176+ # cursor = {
177177+ # theme = "capitaine-cursors";
178178+ # size = 24;
179179+ # cursorFeedback = "Bouncing"; # macOS: app icon bounces in dock on launch
180180+ # };
181181+82182 };
831838484- # Titlebar buttons on the LEFT, mac-style: close → minimise → maximise
8585- kwin.titlebarButtons.left = [ "close" "minimize" "maximize" ];
8686- kwin.titlebarButtons.right = [ ];
184184+ # ── Fonts — all roles, all from settings/config/desktop.nix ───────────────
185185+ # d.uiFont / d.uiFontSize / d.monoFontFamily / d.monoFontSize are the
186186+ # single source of truth; change them once, everything updates.
187187+ fonts = {
188188+ general = {
189189+ family = d.uiFont; # "Noto Sans"
190190+ pointSize = d.uiFontSize; # 10
191191+ };
192192+ fixedWidth = {
193193+ family = d.monoFontFamily; # "FiraCode Nerd Font Mono"
194194+ pointSize = d.monoFontSize; # 11
195195+ };
196196+ small = {
197197+ family = d.uiFont;
198198+ pointSize = d.uiFontSize - 2; # 8 — status bars, breadcrumbs, subtitles
199199+ };
200200+ toolbar = {
201201+ family = d.uiFont;
202202+ pointSize = d.uiFontSize;
203203+ };
204204+ menu = {
205205+ family = d.uiFont;
206206+ pointSize = d.uiFontSize;
207207+ };
208208+ windowTitle = {
209209+ family = d.uiFont;
210210+ pointSize = d.uiFontSize;
211211+ weight = "medium"; # macOS window titles are slightly heavier than body
212212+ };
213213+ };
872148888- # ── Workspace ──────────────────────────────────────────────────────────────
8989- # Wallpaper and icon theme are set in home/programs/kde.nix.
9090- workspace.clickItemTo = "select"; # single-click selects, double-click opens
215215+ # ── Windows ───────────────────────────────────────────────────────────────
216216+ # Allow apps to remember their own window positions.
217217+ # mac: WindowServer stores geometry per app.
218218+ windows.allowWindowsToRememberPositions = true;
219219+220220+ # ── KRunner — Spotlight equivalent (Meta+Space) ───────────────────────────
221221+ krunner = {
222222+ position = "center"; # macOS Spotlight is a centred overlay
223223+ activateWhenTypingOnDesktop = false; # Spotlight requires explicit shortcut
224224+ shortcuts = {
225225+ launch = [ "Meta+Space" "Alt+F2" ];
226226+ runCommandOnClipboard = [ "Meta+Shift+Space" "Alt+Shift+F2" ];
227227+ };
228228+ };
9122992230 # ── Keyboard shortcuts ─────────────────────────────────────────────────────
93231 shortcuts = {
94232 kwin = {
9595- # Virtual desktop switching
9696- "Switch to Desktop 1" = [ "Meta+1" ];
9797- "Switch to Desktop 2" = [ "Meta+2" ];
9898- "Switch to Desktop 3" = [ "Meta+3" ];
9999- "Switch to Desktop 4" = [ "Meta+4" ];
100100- "Switch One Desktop to the Left" = [ "Meta+Left" ];
233233+ # Virtual desktop / Spaces navigation
234234+ # mac: Ctrl+1–4 and Ctrl+← / → switch Spaces
235235+ "Switch to Desktop 1" = [ "Meta+1" ];
236236+ "Switch to Desktop 2" = [ "Meta+2" ];
237237+ "Switch to Desktop 3" = [ "Meta+3" ];
238238+ "Switch to Desktop 4" = [ "Meta+4" ];
239239+ "Switch One Desktop to the Left" = [ "Meta+Left" ];
101240 "Switch One Desktop to the Right" = [ "Meta+Right" ];
102102- # Send window to desktop
241241+242242+ # Move window to a named Space
103243 "Window to Desktop 1" = [ "Meta+Shift+1" ];
104244 "Window to Desktop 2" = [ "Meta+Shift+2" ];
105245 "Window to Desktop 3" = [ "Meta+Shift+3" ];
106246 "Window to Desktop 4" = [ "Meta+Shift+4" ];
107107- # Window management
108108- "Window Close" = [ "Meta+Q" ]; # macOS Cmd+Q
109109- "Window Minimize" = [ "Meta+H" ]; # macOS Cmd+H (hide)
110110- "Toggle Window Maximized" = [ "Meta+Ctrl+F" ]; # macOS Ctrl+Cmd+F
247247+248248+ # Window management — macOS Cmd+* equivalents
249249+ "Window Close" = [ "Meta+Q" ]; # Cmd+Q (quit)
250250+ "Window Minimize" = [ "Meta+H" ]; # Cmd+H (hide / minimise)
251251+ "Toggle Window Maximized" = [ "Meta+Ctrl+F" ]; # Ctrl+Cmd+F (full-screen toggle)
252252+111253 # Mission Control equivalents
112112- # mac: wvous-bl-corner = 2 (Mission Control) → Meta+W as keyboard shortcut
113113- "Overview" = [ "Meta+W" ]; # all desktops + windows
114114- "Expose" = [ "Meta+D" ]; # present windows on current desktop
115115- "Show Desktop" = [ "Meta+Shift+D" ];
254254+ "Overview" = [ "Meta+W" ]; # all desktops + all windows
255255+ "Expose" = [ "Meta+D" ]; # windows on current desktop only
256256+ "Show Desktop" = [ "Meta+Shift+D" ]; # reveal desktop (≡ Fn+F11 on mac)
116257 };
117258 };
118259119119- # ── Panels ────────────────────────────────────────────────────────────────
260260+ # ── Spectacle — macOS screenshot shortcut mapping ─────────────────────────
261261+ # mac: Cmd+Shift+3 = full screen → Meta+Shift+3
262262+ # Cmd+Shift+4 = region → Meta+Shift+4
263263+ # Cmd+Shift+5 = UI → Meta+Shift+5
264264+ spectacle.shortcuts = {
265265+ captureEntireDesktop = [ "Meta+Shift+3" ];
266266+ captureRectangularRegion = [ "Meta+Shift+4" ];
267267+ launch = [ "Meta+Shift+5" ];
268268+ captureActiveWindow = [ "Meta+Shift+Alt+4" ];
269269+ };
270270+271271+ # Spectacle save location and format
272272+ # mac: system.defaults.screencapture.location = "~/Desktop", type = "png"
273273+ configFile."spectaclerc" = {
274274+ General.launchAction = "DoNotTakeScreenshot";
275275+ ImageSave.defaultFolder = "%DESKTOP%";
276276+ ImageSave.saveImageFormat = "PNG";
277277+ };
278278+279279+ # ── Screen locker ──────────────────────────────────────────────────────────
280280+ # mac: "Require password … after sleep or screen saver begins" (immediately)
281281+ # + 5-minute idle auto-lock.
282282+ kscreenlocker = {
283283+ autoLock = true;
284284+ timeout = 5; # lock after 5 min idle
285285+ lockOnResume = true; # lock on wake from sleep
286286+ passwordRequired = true;
287287+ passwordRequiredDelay = 0; # no grace period
288288+ };
289289+290290+ # ── Notifications — top-right (macOS notification banner position) ─────────
291291+ configFile."plasmanotifyrc".Notifications.PopupPosition = "TopRight";
292292+293293+ # ── Dolphin — mirrors macOS Finder preferences ────────────────────────────
294294+ # mac: finder.AppleShowAllExtensions = true
295295+ # finder._FXSortFoldersFirst = true
296296+ # finder.ShowPathbar = true
297297+ # finder.ShowStatusBar = false
298298+ # finder._FXShowPosixPathInTitle = true
299299+ # finder.FXDefaultSearchScope = "SCcf"
300300+ configFile."dolphinrc" = {
301301+ General = {
302302+ ShowHiddenFiles = true;
303303+ SortFoldersFirst = true;
304304+ ShowStatusBar = false;
305305+ BreadcrumbNavigation = true;
306306+ };
307307+ DetailsMode."ExpandableFolders" = false;
308308+ "KFileDialog Settings"."Show Full Path" = true;
309309+ };
310310+311311+ # ── Panels ─────────────────────────────────────────────────────────────────
120312121313 panels = [
122314123123- # ── Top menu bar ─────────────────────────────────────────────────────────
124124- # Full-width, always visible, 28 px — hosts the global app menu.
125125- # Mirrors the macOS menu bar: launcher on left, app menus inline,
126126- # tray + clock on right.
315315+ # ── Top menu bar ──────────────────────────────────────────────────────────
316316+ # Full-width, always visible, 28 px tall.
317317+ # Left: [Launcher] [Global App Menu — File Edit View …]
318318+ # Right: [System Tray] [Clock 12h + seconds]
127319 {
128320 location = "top";
129321 floating = false;
···131323132324 widgets = [
133325134134- # Application launcher (Apple menu equivalent)
326326+ # Application launcher — the "Apple menu" / NixOS logo equivalent.
135327 {
136328 name = "org.kde.plasma.kickoff";
137329 config.General = {
···140332 };
141333 }
142334143143- # Global app menu — active window's menus appear here
335335+ # Global app menu — active window's menu bar appears inline here,
336336+ # just as on macOS every app's menu bar lives at the top.
144337 "org.kde.plasma.appmenu"
145338146146- # Flexible spacer
339339+ # Flexible spacer — pushes tray + clock to the far right.
147340 "org.kde.plasma.panelspacer"
148341149149- # System tray
342342+ # System tray — equivalent to macOS menu-bar extras.
150343 {
151344 name = "org.kde.plasma.systemtray";
152345 config.General.shownItems = 3;
153346 }
154347155155- # Clock — mirroring mac menuExtraClock:
156156- # ShowAMPM = true (12-hour)
157157- # ShowSeconds = true
158158- # ShowDate = 0 (never)
159159- # ShowDayOfWeek = false
348348+ # Digital clock — mirrors macOS menuExtraClock:
349349+ # ShowAMPM = true, ShowSeconds = true
350350+ # ShowDate = 0 (never), ShowDayOfWeek = false
160351 {
161352 name = "org.kde.plasma.digitalclock";
162353 config.Appearance = {
···171362 ];
172363 }
173364174174- # ── Bottom dock ───────────────────────────────────────────────────────────
175175- # Floating, centred, always visible (mac dock.autohide = false).
176176- # Icon-only task manager — no labels — mirrors the macOS dock.
177177- # Height 56 ≈ tilesize 46 + padding (mac dock.tilesize = 46).
365365+ # ── Bottom floating dock ──────────────────────────────────────────────────
366366+ # Centred, floating, always visible.
367367+ # mac: dock.autohide = false dock.tilesize = 46 dock.orientation = "bottom"
368368+ # Height 56 px ≈ icon size 46 + padding.
178369 {
179370 location = "bottom";
180371 floating = true;
181372 height = 56;
182373 alignment = "center";
183183- lengthMode = "fit";
184184- hiding = "none"; # mac: dock.autohide = false
374374+ lengthMode = "fit"; # shrinks to fit its launchers
375375+ hiding = "none"; # always visible
185376186377 widgets = [
187378 {
···190381 showOnlyCurrentDesktop = "false";
191382 showOnlyCurrentScreen = "false";
192383 launchers = [
193193- "applications:org.kde.dolphin.desktop" # Files (Finder)
384384+ "applications:org.kde.dolphin.desktop" # Dolphin ≡ Finder
194385 "applications:signal-desktop.desktop"
195386 "applications:obsidian.desktop"
196387 "applications:spotify.desktop"
···205396 ];
206397 }
207398208208- ];
209209-210210- # ── KWin config via configFile ────────────────────────────────────────────
211211- configFile."kwinrc" = {
212212-213213- # Blur behind panels and menus (frosted-glass macOS look)
214214- Plugins.blurEnabled = true;
215215- "Effect-blur" = {
216216- BlurStrength = 7;
217217- NoiseStrength = 0;
218218- };
219219-220220- # Magic Lamp minimise animation — mirrors mac dock.minimize-to-application = true.
221221- # The window squishes into the dock icon rather than zooming to the centre.
222222- Plugins.magiclampEnabled = true;
223223- Plugins.squashEnabled = false;
224224-225225- # Faster animations — snappier than KDE default (3)
226226- Compositing.AnimationSpeed = 2;
227227-228228- # Hot corners — mirroring mac dock wvous-* settings:
229229- # BL → Mission Control (Overview in KDE = 9)
230230- # BR → Desktop (ShowDesktop = 4)
231231- # TL → None (None = 0)
232232- # TR → Screen Saver (LockScreen = 5, closest KDE equivalent)
233233- ElectricBorders = {
234234- BottomLeft = "Overview"; # mac: wvous-bl-corner = 2 (Mission Control)
235235- BottomRight = "ShowDesktop"; # mac: wvous-br-corner = 4 (Desktop)
236236- TopLeft = "None"; # mac: wvous-tl-corner = 1 (None)
237237- TopRight = "LockScreen"; # mac: wvous-tr-corner = 5 (Screen Saver)
238238- };
239239- };
240240-241241- # ── KRunner = Spotlight (Meta+Space) ─────────────────────────────────────
242242- configFile."kglobalshortcutsrc".krunner = {
243243- _launch = "Meta+Space,Alt+F2,Run Command";
244244- RunClipboard = "Meta+Shift+Space,Alt+Shift+F2,Run Command on clipboard contents";
245245- };
246246-247247- # ── Notifications — top-right (macOS position) ────────────────────────────
248248- configFile."plasmanotifyrc".Notifications.PopupPosition = "TopRight";
249249-250250- # ── Splash screen — none (macOS has none) ────────────────────────────────
251251- configFile."ksplashrc".KSplash = {
252252- Engine = "none";
253253- Theme = "None";
254254- };
255255-256256- # ── Dolphin (file manager) ────────────────────────────────────────────────
257257- # mirrors: finder.AppleShowAllExtensions = true
258258- # finder._FXSortFoldersFirst = true
259259- # finder.ShowPathbar = true
260260- # finder.ShowStatusBar = false
261261- # finder._FXShowPosixPathInTitle = true
262262- # finder.FXDefaultSearchScope = "SCcf" (search current folder)
263263- configFile."dolphinrc".General = {
264264- ShowHiddenFiles = true;
265265- SortFoldersFirst = true; # mac: finder._FXSortFoldersFirst = true
266266- ShowStatusBar = false; # mac: finder.ShowStatusBar = false
267267- BreadcrumbNavigation = true; # mac: finder.ShowPathbar = true
268268- };
269269- configFile."dolphinrc".DetailsMode.ExpandableFolders = false;
399399+ ]; # end panels
270400271271- # Display full posix path in the Dolphin title bar
272272- # mac: finder._FXShowPosixPathInTitle = true
273273- configFile."dolphinrc"."KFileDialog Settings"."Show Full Path" = true;
274274-275275- # ── Spectacle (screenshot) ────────────────────────────────────────────────
276276- # mac: screencapture.location = "~/Desktop" screencapture.type = "png"
277277- configFile."spectaclerc" = {
278278- General.launchAction = "DoNotTakeScreenshot";
279279- ImageSave.defaultFolder = "%DESKTOP%";
280280- ImageSave.saveImageFormat = "PNG";
281281- };
282282-283283- };
401401+ }; # end programs.plasma
284402}