{ config, pkgs, ... }: { # === Linux desktop packages === home.packages = with pkgs; [ # pi + qmd (from overlay) qmd # Browser chromium # Terminal ghostty zellij # Status bar waybar # App launcher rofi # Notifications dunst libnotify # Wallpaper awww btop fuzzel # Screen recording / streaming obs-studio # Communication webex zapzap # Lock + idle hyprlock hypridle # Screenshots grim slurp swappy # Clipboard wl-clipboard cliphist # Brightness / audio brightnessctl pavucontrol # File manager thunar # Polkit agent polkit_gnome # Theming bibata-cursors papirus-icon-theme adw-gtk3 beos-r5-icons haiku-cursor # Network / containers / system networkmanagerapplet gh winetricks cabextract # required by winetricks for .cab extraction tailscale docker dive beeper discord slack nmap tcpdump speedtest-cli protonmail-bridge-gui ]; # === Proton Mail Bridge user service (starts at login) === systemd.user.services.protonmail-bridge = { Unit = { Description = "Proton Mail Bridge"; After = [ "network-online.target" "graphical-session.target" ]; Wants = [ "network-online.target" ]; }; Service = { Type = "simple"; ExecStart = "${pkgs.protonmail-bridge}/bin/protonmail-bridge --non-interactive"; Restart = "on-failure"; RestartSec = "5"; }; Install = { WantedBy = [ "graphical-session.target" ]; }; }; # === GTK / QT theming === gtk = { enable = true; theme.name = "adw-gtk3-dark"; iconTheme.name = "BeOS-r5"; cursorTheme = { name = "Haiku_Cursor"; size = 24; }; gtk3.extraConfig = { gtk-application-prefer-dark-theme = 1; }; gtk4.extraConfig = { gtk-application-prefer-dark-theme = 1; }; }; qt = { enable = true; platformTheme.name = "gtk3"; style.name = "adwaita-dark"; }; # === libadwaita dark mode === dconf.settings = { "org/gnome/desktop/interface" = { color-scheme = "prefer-dark"; }; }; # === Hyprland WM config === home.file.".config/hypr/hyprland.conf" = { force = true; source = ./hyprland.conf; }; # === Ghostty config === home.file.".config/ghostty/config" = { force = true; text = '' font-family = JetBrainsMono Nerd Font font-size = 13 theme = Catppuccin Mocha background-opacity = 0.9 window-padding-x = 8 window-padding-y = 4 cursor-style = bar confirm-close-surface = false shell-integration = zsh gtk-single-instance = true ''; }; # === Zellij config === home.file.".config/zellij/config.kdl" = { force = true; text = '' theme "catppuccin-mocha" default_shell "zsh" show_startup_tips false pane_frames false scrollback_editor "nvim" keybinds clear-defaults=true { normal { bind "Ctrl g" { SwitchToMode "Locked"; } } locked { bind "Ctrl g" { SwitchToMode "Normal"; } bind "Ctrl q" { CloseTab; } bind "Ctrl p" { NewPane "down"; } bind "Ctrl n" { NewPane "right"; } bind "Ctrl t" { NewTab; } bind "Ctrl x" { CloseFocus; } bind "Ctrl f" { ToggleFloatingPanes; } bind "Ctrl z" { ToggleFocusFullscreen; } bind "Ctrl d" { Detach; } bind "Ctrl h" { MoveFocusOrTab "left"; } bind "Ctrl j" { MoveFocusOrTab "down"; } bind "Ctrl k" { MoveFocusOrTab "up"; } bind "Ctrl l" { MoveFocusOrTab "right"; } bind "Ctrl r" { SwitchToMode "RenameTab"; } } renametab { bind "Ctrl c" { SwitchToMode "Locked"; } bind "Esc" { SwitchToMode "Locked"; } } } ''; }; # === Hyprlock === home.file.".config/hypr/hyprlock.conf".text = '' general { disable_loading_bar = false; hide_cursor = true; grace = 0; no_fade_in = false; } background { path = screenshot; blur_passes = 3; blur_size = 10; color = rgba(0,0,0,0.6); } input-field { size = 250, 50; position = 0, -200; monitor = dots_center = true; fade_on_empty = false placeholder_text = unlock outer_color = rgba(8ebdff,0.8); inner_color = rgba(30,30,46,0.8) font_color = rgba(255,255,255,0.9) } label { text = cmd[update:60] date +"%A, %B %d %H:%M" position = 0, 200; monitor = font_size = 32; font_family = JetBrains Mono Nerd Font color = rgba(255,255,255,0.9) } ''; # === Hypridle === home.file.".config/hypr/hypridle.conf".text = '' general { lock_cmd = hyprlock; before_sleep_cmd = hyprlock; } listener { timeout = 300; on-timeout = hyprlock; } listener { timeout = 600; on-timeout = hyprctl dispatch dpms off; on-resume = hyprctl dispatch dpms on; } ''; # === Waybar config === home.file.".config/waybar/config.jsonc" = { force = true; text = builtins.toJSON { layer = "top"; position = "top"; height = 32; spacing = 4; margin = "6 8 0 8"; modules-left = [ "hyprland/workspaces" ]; modules-center = [ "clock" ]; modules-right = [ "tray" "bluetooth" "pulseaudio" "backlight" "battery" "network" "cpu" "temperature" "memory" ]; "hyprland/workspaces" = { format = "{icon}"; format-icons = { "1" = "󰆍"; "2" = "󰨞"; "3" = "󰖟"; "4" = "󰭻"; "5" = "󰠮"; media = "󰎆"; "7" = "󰎇"; "8" = "󰎈"; "9" = "󰎉"; sys = "󰒓"; default = "󰊌"; }; persistent_workspaces = { "1" = []; "2" = []; "3" = []; "4" = []; "5" = []; }; }; clock = { format = "{:%a %b %d %I:%M %p}"; tooltip-format = "{:%Y %B}\n{calendar}"; }; cpu = { format = " {usage}%"; }; temperature = { format = " {temperatureC}°C"; interval = 10; thermal-zone = 5; }; memory = { format = "󰍛 {}%"; }; backlight = { format = "{icon} {percent}%"; format-icons = [ "󰃝" "󰃞" "󰃟" "󰃠" ]; }; battery = { format = "{icon} {capacity}%"; format-icons = [ "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; format-charging = "󰂄 {capacity}%"; }; network = { format-wifi = "󰖩 {signalStrength}%"; format-ethernet = "󰈀"; format-disconnected = "⚠"; tooltip-format = "{ifname} via {gwaddr}"; }; pulseaudio = { format = "{icon} {volume}%"; format-bluetooth = "{icon}󰂯 {volume}%"; format-muted = "󰝟"; format-icons.default = [ "󰕿" "󰖀" "󰕾" ]; on-click = "pavucontrol"; }; bluetooth = { format = "󰂯"; format-connected = "󰂯 {device_alias}"; format-disabled = ""; format-no-controller = ""; format-off = "󰂲"; tooltip-format = "{device_alias} — {device_address}"; on-click = "blueman-manager"; }; tray.spacing = 10; }; }; # === Waybar style === home.file.".config/waybar/style.css".text = '' * { font-family: "JetBrainsMono Nerd Font", "Font Awesome 6 Free"; font-size: 13px; } window#waybar { background: rgba(30,30,46,0.85); border-radius: 8px; color: #cdd6f4; } #workspaces button { padding: 0 6px; color: #6c7086; background: transparent; border-radius: 4px; } #workspaces button.active { color: #cdd6f4; background: #45475a; } #workspaces button:hover { color: #cdd6f4; background: #313244; } #clock, #cpu, #memory, #backlight, #battery, #network, #pulseaudio, #bluetooth, #tray { padding: 0 10px; color: #cdd6f4; } #cpu.warning, #memory.warning, #battery.warning { color: #f9e2af; } #cpu.critical, #memory.critical, #battery.critical { color: #f38ba8; } tooltip { background: rgba(30,30,46,0.95); border: 1px solid #45475a; border-radius: 6px; } ''; # === Rofi launcher === home.file.".config/rofi/config.rasi" = { force = true; source = ./spotlight-dark.rasi; }; # === Dunst notifications === home.file.".config/dunst/dunstrc".text = '' [global] monitor = 0; follow = mouse; width = 350; height = 150; offset = 10x50; origin = top-right notification_limit = 5; indicate_hidden = yes; shrink = no; transparency = 0 separator_height = 2; padding = 12; horizontal_padding = 12; frame_width = 2 frame_color = "#89b4fa"; separator_color = frame; sort = yes font = JetBrainsMono Nerd Font 11; corner_radius = 8 background = "#1e1e2e"; foreground = "#cdd6f4"; timeout = 5 idle_threshold = 120; icon_position = left; max_icon_size = 48; markup = full format = "%s\n%b" [urgency_low] background = "#1e1e2e"; foreground = "#cdd6f4"; timeout = 3 [urgency_normal] background = "#1e1e2e"; foreground = "#cdd6f4"; timeout = 5 [urgency_critical] background = "#f38ba8"; foreground = "#1e1e2e"; timeout = 0 ''; # === Lid handler === home.file.".config/hypr/scripts/lid-handler.sh" = { force = true; executable = true; source = ./bin/lid-handler.sh; }; # === Wallpaper rotation === home.file.".local/bin/wallpaper-rotate" = { force = true; source = ./wallpaper-rotate.sh; }; # === BeOS cursor theme installer === home.file.".local/bin/install-beos-cursor" = { force = true; executable = true; text = '' #!/usr/bin/env bash set -euo pipefail CURSOR_NAME="BeOS" ICONS_DIR="$HOME/.local/share/icons" CURSOR_DIR="$ICONS_DIR/$CURSOR_NAME" echo "==> BeOS Cursor Installer" echo "" if [ -d "$CURSOR_DIR" ] && [ -f "$CURSOR_DIR/index.theme" ]; then echo " ✅ BeOS cursor already installed at $CURSOR_DIR" echo "" echo "To switch to it:" echo " gsettings set org.gnome.desktop.interface cursor-theme BeOS" echo " # Or update ~/.config/gtk-3.0/settings.ini:" echo " # gtk-cursor-theme-name=BeOS" exit 0 fi echo "To install BeOS cursors:" echo " 1. Open https://www.gnome-look.org/p/999293/ in your browser" echo " 2. Download the BeOS-Cursors.tar.gz" echo " 3. Run: install-beos-cursor /path/to/BeOS-Cursors.tar.gz" echo "" if [ $# -eq 0 ]; then echo "No file provided. See instructions above." exit 1 fi ARCHIVE="$1" if [ ! -f "$ARCHIVE" ]; then echo " ❌ File not found: $ARCHIVE" exit 1 fi echo "==> Installing BeOS cursor from $ARCHIVE..." mkdir -p "$ICONS_DIR" tar xzf "$ARCHIVE" -C "$ICONS_DIR" 2>/dev/null || tar xzf "$ARCHIVE" -C "$ICONS_DIR" --strip-components=1 2>/dev/null || true if [ -f "$CURSOR_DIR/index.theme" ]; then echo " ✅ Installed to $CURSOR_DIR" echo "" echo "Now switch to BeOS cursor:" echo " gsettings set org.gnome.desktop.interface cursor-theme BeOS" else # Try to find what was extracted echo " Checking extracted directories..." find "$ICONS_DIR" -name "index.theme" -exec dirname {} \\; 2>/dev/null | head -5 echo "" echo "The extracted cursor directories are listed above." fi ''; }; # === Logos Bible Software (Wine) === # Helper script: first run installs Logos, subsequent runs launch it home.file.".local/bin/logos" = { force = true; executable = true; text = '' #!/usr/bin/env bash # Launch Logos Bible Software as a Chromium web app exec chromium --app="https://app.logos.com" --name="Logos" "$@" ''; }; # Logos web app icon home.file.".local/share/icons/hicolor/scalable/apps/logos.svg".source = ./logos-icon.svg; # Desktop entry for Logos web app home.file.".local/share/applications/logos.desktop" = { force = true; text = '' [Desktop Entry] Type=Application Name=Logos Bible Software Comment=Logos Bible Software (Web App) Exec=logos Icon=logos Terminal=false Categories=Office;Education;Network; StartupWMClass=logos MimeType=x-scheme-handler/logos; ''; }; }