diff --git a/AGENTS.md b/AGENTS.md index 082ccb9..1f00213 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,8 +11,9 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux Mint and Fr - Codex config is rendered from `dotfiles/common/.codex/config.toml.j2` so `model_instructions_file` points to the deployed `~/.config/ai/bootstrap.md`. ## Topology -- Current Void desktops: `ikaros`, `nymph` via `platform_void + graphical_desktop` -- Target model: `ikaros = platform_mint + role_personal_workstation + desktop_cinnamon`; `nymph = platform_freebsd + role_lab + desktop_hyprland` +- Current personal desktop: `ikaros = platform_mint + role_personal_workstation + desktop_cinnamon` +- Current laptop/lab: `nymph = platform_freebsd + role_lab + desktop_niri` +- Void desktop profile remains available for future/reference hosts via `platform_void + graphical_desktop` - Native Linux workstation: `deadalus-fedora` - WSL dev: `deadalus-wsl` - Ubuntu server: `prometheus` @@ -36,13 +37,13 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux Mint and Fr - `ansible-lint ansible/roles` - `yamllint ansible/` - Host-focused dry runs: - - Current Void preservation: `ansible-playbook ansible/site.yml --limit ikaros,nymph --check --diff` - - Void desktop work: `ansible-playbook ansible/site.yml --limit ikaros --check --diff` or `--limit nymph --check --diff` + - Mint desktop work: `ansible-playbook ansible/site.yml --limit ikaros --check --diff` + - FreeBSD laptop work: `ansible-playbook ansible/site.yml --limit nymph --check --diff` - Fedora workstation: `ansible-playbook ansible/site.yml --limit deadalus-fedora --check --diff` - WSL dev: `ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff` - Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff` - Focused checks: - - Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff` + - Emacs is disabled by default; temporary Emacs check: `ansible-playbook ansible/site.yml --limit --tags emacs --check --diff -e emacs_enabled=true` - Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh` - Server compose render: `docker compose -f /opt/docker/server/docker-compose.yml config` @@ -55,18 +56,19 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux Mint and Fr - Use `no_log: true` for secret-bearing task inputs or outputs. ## Desktop Notes -- `desktop_profile` names independently selectable desktop groups such as `desktop_hyprland`, `desktop_sway`, and `desktop_cinnamon`. Keep platform-specific session bootstrap in platform-specific roles. +- `desktop_profile` names independently selectable desktop groups such as `desktop_hyprland`, `desktop_sway`, `desktop_niri`, and `desktop_cinnamon`. Keep platform-specific session bootstrap in platform-specific roles. - `desktop_environment` selects the mutually exclusive `minimal` (default), `xfce`, or `kde` desktop mode. `profile_desktop_common` owns shared bootstrap; the minimal mode uses `profile_desktop_sway` and `profile_desktop_hyprland`, `profile_desktop_xfce` owns the reproducible XFCE setup, and `profile_desktop_kde` owns KDE-specific defaults and cleanup. `desktop_sessions_enabled` and `desktop_default_session` apply only to the minimal mode. -- `.emacs.d` is deployed by a dedicated `profile_desktop_common` task tagged `emacs`. +- Emacs packages and `.emacs.d` deploy are disabled by default via `emacs_enabled: false`; keep the dotfiles in the repo for reversible opt-in only. - NTFS filesystem support is provided by `ntfs-3g` in `ansible/inventory/group_vars/void.yml`. - Void user services are managed by `turnstile` and live under `dotfiles/desktop/.config/service/`. - `ssh-agent` keeps the stable socket `~/.local/state/ssh-agent/socket`. - Critical session entrypoints: - `dotfiles/desktop/.config/sway/config` plus `host.conf` and `session-env` deployed via `host_sway_dotfiles` (sway / Wayland) - `dotfiles/desktop/.config/hypr/hyprland.conf` plus `host.conf` and `session-env` deployed via `host_hyprland_dotfiles` (Hyprland / Wayland) -- FreeBSD Hyprland must reuse common Hyprland dotfiles and keep FreeBSD-specific package, rc, DBus, seat, portal, and launcher behavior in `profile_desktop_hyprland_freebsd` or FreeBSD platform vars. + - `dotfiles/desktop/.config/niri/config.kdl` and `session-env` deployed via `desktop_niri_dotfiles` (Niri / Wayland) +- FreeBSD Niri must keep FreeBSD-specific package, rc, DBus, seat, portal, and launcher behavior in `profile_desktop_niri_freebsd` or FreeBSD platform vars. - Do not switch or restart a display manager during a playbook run from an active graphical session. Changing among `emptty`, LightDM, and SDDM requires an explicit run from another TTY/SSH session with `desktop_allow_display_manager_switch=true`. Apply managed XFCE XML while logged out of XFCE so `xfconfd` cannot overwrite it from its in-memory state. -- `nymph` is a Void laptop with NVIDIA Optimus, running sway (Wayland) and Hyprland (Wayland); host-specific tasks in `profile_desktop_host/tasks/nymph.yml` handle GRUB NVIDIA cmdline params, `prime-run` wrapper, and the WirePlumber camera priority config. Multi-monitor on sway is driven by `kanshi` (config deployed via `host_sway_dotfiles`), and on Hyprland by host-specific Hyprland monitor/workspace rules. +- `nymph` is the FreeBSD/Niri laptop target; prefer minimal scrollable-tiling defaults first, then host-specific tuning after real use. ## Void Package And Dotfile Bucket Rules `platform_void` is the reusable Void platform selection. The legacy `void` group remains a compatibility parent so existing `group_vars/void.yml` and `when: "'void' in group_names"` checks keep working during the transition. diff --git a/README.md b/README.md index 3c9269b..34dc286 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Matrice target: | Host | Platform | Role | Desktop | | -------------- | ---------- | -------------------- | --------------------------------- | | ikaros | Linux Mint | Personal workstation | Cinnamon | -| nymph | FreeBSD | Lab | Hyprland | +| nymph | FreeBSD | Lab | Niri | | void-reference | Void Linux | Lab/reference | Current preserved desktop profile | Regola operativa: @@ -81,10 +81,10 @@ ikaros must be boring nymph is allowed to break ``` -Durante il refactoring strutturale iniziale `ikaros` e `nymph` restano in -`platform_void` per preservare il comportamento esistente. I gruppi legacy -`void` e `desktop` restano alias di compatibilita mentre i nuovi assi sono -`platform_*`, `role_*` e `desktop_*`. +`ikaros` usa il target stabile Linux Mint/Cinnamon; `nymph` usa il target +FreeBSD/Niri per il workflow laptop scrollable-tiling. I gruppi legacy `void` e +`desktop` restano alias di compatibilita per eventuali host Void futuri mentre i +nuovi assi sono `platform_*`, `role_*` e `desktop_*`. Prima di una migrazione reale degli host e consigliato creare uno snapshot logico, per esempio: @@ -96,34 +96,27 @@ git tag void-desktop-before-platform-refactor Nota sullo stato attuale del playbook principale: -- `ansible/site.yml` applica oggi in automatico il profilo desktop su host Void Linux +- `ansible/site.yml` applica oggi in automatico Cinnamon su Linux Mint e Niri su FreeBSD - `ansible/site.yml` applica la workstation Linux nativa separando il layer dev comune dal layer host GNOME - `ansible/site.yml` applica anche il ramo `workstation_dev_wsl` per il modello dev in WSL - `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW -## Desktop - -Sistema operativo: - -- Void Linux - -Modalita desktop: +## Desktop -- `minimal`: sway (Wayland) + Hyprland (Wayland), gestite da `emptty` -- `xfce`: XFCE puro con look scuro e sobrio, gestito da LightDM -- `kde`: KDE Plasma, gestito da SDDM - -Macchine: - -- `ikaros` -- `nymph` - -Queste macchine condividono la stessa configurazione base desktop e vengono mantenute allineate tramite Ansible. `desktop_environment` seleziona in modo esclusivo `minimal` (default), `xfce` oppure `kde`. Nella modalita minimale Sway/SwayFX e Hyprland sono installate in parallelo e selezionabili da `emptty`; `desktop_default_session` decide quale sessione viene preselezionata al login. XFCE usa direttamente la sessione `xfce` tramite LightDM. +Target operativi: + +- `ikaros`: Linux Mint + Cinnamon, desktop personale stabile/floating. +- `nymph`: FreeBSD + Niri, laptop scrollable-tiling per sfruttare meglio lo schermo piccolo. + +Il profilo Void desktop resta disponibile come modello riutilizzabile per host +futuri. `desktop_environment` continua a selezionare in modo esclusivo +`minimal`, `xfce` oppure `kde` per i desktop Void; Niri e Cinnamon sono profili +desktop indipendenti via gruppi `desktop_niri` e `desktop_cinnamon`. Lo stato attuale del profilo desktop include, tra le altre cose: - dotfiles comuni e desktop -- sessioni sway e Hyprland su entrambi gli host in modalita `minimal` +- sessioni sway e Hyprland per eventuali host Void in modalita `minimal` - KDE Plasma con applicazioni KDE curate e SDDM disponibile come alternativa esclusiva - XFCE con pannello, keybinding, terminale, tema e workspace dichiarativi, LightDM e Thunderbird come client grafico principale - `emptty` con default host-specific in modalita `minimal`, con session file Wayland esposti per `sway` e `hyprland` @@ -134,14 +127,13 @@ Lo stato attuale del profilo desktop include, tra le altre cose: - `desktop_xfce_packages` per XFCE, LightDM e le relative integrazioni - `desktop_kde_packages` per Plasma, SDDM e le applicazioni KDE equivalenti - `desktop_sway_packages` e `desktop_hyprland_packages` per i binari specifici di ciascuna sessione -- `turnstile` per i servizi utente, inclusi `emacs` e `ssh-agent` -- `ssh-agent` con socket stabile condiviso tra shell, SSH ed Emacs in `~/.local/state/ssh-agent/socket` -- `.emacs.d` distribuito da un task dedicato Ansible con tag `emacs` +- `turnstile` per i servizi utente Void, incluso `ssh-agent` +- `ssh-agent` con socket stabile condiviso tra shell e SSH in `~/.local/state/ssh-agent/socket` +- Emacs e i relativi dotfile restano nel repo ma sono disabilitati di default tramite `emacs_enabled: false` - `tmux` con plugin gestiti da TPM al bootstrap del profilo desktop - Flatpak con remoto Flathub - GNOME Keyring e `udiskie` nella modalita minimale; KWallet e integrazione UDisks di Plasma nella modalita KDE -- multi-monitor: sotto sway è gestito da `kanshi` (config host-specifica in `host_sway_dotfiles` su `nymph`); sotto Hyprland gli override monitor vivono in `host_hyprland_dotfiles` -- override NVIDIA Optimus su `nymph`: parametri kernel GRUB iniettati in modo idempotente in `GRUB_CMDLINE_LINUX`, wrapper `prime-run` e config WirePlumber per priorità telecamera +- multi-monitor Void: sotto sway è gestito da `kanshi`; sotto Hyprland gli override monitor vivono in `host_hyprland_dotfiles` --- @@ -240,12 +232,11 @@ ansible-playbook ansible/site.yml --limit prometheus -e server_username=myuser - # Composizione della configurazione -Deploy mirato della configurazione Emacs sui desktop Void: - -```bash -ansible-playbook ansible/site.yml --limit ikaros --tags emacs -ansible-playbook ansible/site.yml --limit nymph --tags emacs -``` +Emacs è disabilitato di default. Per riattivare temporaneamente il deploy Emacs: + +```bash +ansible-playbook ansible/site.yml --limit --tags emacs -e emacs_enabled=true +``` La configurazione finale di una macchina è ottenuta combinando più livelli. @@ -257,23 +248,11 @@ common configuration + host overrides ``` -Esempio corrente per `ikaros` nella fase conservativa: +Esempi correnti: ```text -common + platform_void + graphical_desktop + role_personal_workstation + desktop_hyprland/desktop_sway + ikaros -``` - -Esempio corrente per `nymph` nella fase conservativa: - -```text -common + platform_void + graphical_desktop + role_lab + desktop_hyprland/desktop_sway + nymph -``` - -Esempi target, da attivare con un cambio inventory separato: - -```text -ikaros -> platform_mint + role_personal_workstation + desktop_cinnamon -nymph -> platform_freebsd + role_lab + desktop_hyprland +ikaros -> common + platform_mint + role_personal_workstation + desktop_cinnamon + ikaros +nymph -> common + platform_freebsd + role_lab + desktop_niri + nymph ``` Questo approccio consente di: @@ -304,7 +283,7 @@ I principali ruoli attualmente presenti sono: | profile_desktop_common | bootstrap desktop Void condiviso | | profile_desktop_sway | sessione desktop sway / SwayFX (Wayland) | | profile_desktop_hyprland | sessione desktop Hyprland (Wayland) | -| profile_desktop_hyprland_freebsd | adattamenti FreeBSD per Hyprland | +| profile_desktop_niri_freebsd | adattamenti FreeBSD per Niri | | profile_desktop_cinnamon | impostazioni Cinnamon circoscritte | | profile_desktop_host | override desktop specifici per host | | profile_personal_workstation | layer stabile per workstation personale | @@ -331,7 +310,7 @@ platform_mint & role_personal_workstation -> profile_personal_workstation platform_mint & desktop_cinnamon -> profile_desktop_cinnamon platform_freebsd -> packages_freebsd + services_freebsd platform_freebsd & role_lab -> profile_lab -platform_freebsd & desktop_hyprland -> profile_desktop_hyprland_freebsd +platform_freebsd & desktop_niri -> profile_desktop_niri_freebsd workstation_dev_fedora -> packages_fedora + services_systemd + profile_workstation_dev_common workstation_host_linux -> profile_workstation_gnome workstation_dev_wsl -> packages_ubuntu + services_systemd + profile_workstation_dev_common + profile_workstation_dev_wsl @@ -340,8 +319,9 @@ ubuntu_server -> packages_ubuntu + services_systemd + profile_server Questo significa che, allo stato attuale: -- i desktop Void (`ikaros`, `nymph`) restano il target operativo piu completo tramite `platform_void + graphical_desktop` -- Linux Mint/Cinnamon e FreeBSD/Hyprland sono scaffolding selezionabile tramite gruppi, ma non ricevono host reali nel refactoring strutturale iniziale +- `ikaros` riceve Linux Mint/Cinnamon come target stabile +- `nymph` riceve FreeBSD/Niri come target laptop scrollable-tiling +- il profilo Void resta selezionabile tramite `platform_void + graphical_desktop` per host futuri - la workstation Fedora (`deadalus-fedora`) usa il principio di composizione a gruppi con il ramo Fedora dedicato e con `gsettings` host-specifici dichiarati in inventory - il ramo WSL (`deadalus-wsl`) e predisposto con play dev dedicato - il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall @@ -490,9 +470,10 @@ Allo stato attuale `ansible/site.yml` espone questi tag: | `xfce` | profilo XFCE, LightDM e relativa pulizia | desktop Void | | `cinnamon` | impostazioni Cinnamon circoscritte | Linux Mint desktop | | `gnome` | configurazione host GNOME | workstation host Linux, parte desktop | -| `sway` | sessione/configurazione sway / SwayFX (Wayland) | desktop Void | -| `hyprland` | sessione/configurazione Hyprland (Wayland) | desktop Void | -| `npm` | installazione pacchetti npm globali | desktop Void, workstation Linux, WSL | +| `sway` | sessione/configurazione sway / SwayFX (Wayland) | desktop Void | +| `hyprland` | sessione/configurazione Hyprland (Wayland) | desktop Void | +| `niri` | sessione/configurazione Niri (Wayland) | FreeBSD laptop | +| `npm` | installazione pacchetti npm globali | desktop Void, workstation Linux, WSL | | `nvidia` | componenti NVIDIA desktop | desktop Void | | `packages` | installazione e aggiornamento pacchetti | tutti i profili | | `services` | gestione servizi runit/systemd | tutti i profili | @@ -502,10 +483,9 @@ Allo stato attuale `ansible/site.yml` espone questi tag: Esempi pratici: ```bash -ansible-playbook ansible/site.yml --limit nymph --tags dotfiles:desktop,sway --check --diff -ansible-playbook ansible/site.yml --limit ikaros --tags sway,portal --check --diff -ansible-playbook ansible/site.yml --limit ikaros --tags hyprland,portal --check --diff -ansible-playbook ansible/site.yml --limit deadalus-fedora --tags packages,vscode --check --diff +ansible-playbook ansible/site.yml --limit nymph --tags dotfiles:desktop,niri --check --diff +ansible-playbook ansible/site.yml --limit ikaros --tags cinnamon --check --diff +ansible-playbook ansible/site.yml --limit deadalus-fedora --tags packages,vscode --check --diff ansible-playbook ansible/site.yml --limit prometheus --tags services,dotfiles:server --check --diff ``` diff --git a/ansible/inventory/group_vars/all.yml b/ansible/inventory/group_vars/all.yml index 072f4b7..4fe2de1 100644 --- a/ansible/inventory/group_vars/all.yml +++ b/ansible/inventory/group_vars/all.yml @@ -7,6 +7,7 @@ user_shell: /bin/bash effective_username: "{{ username }}" effective_user_group: "{{ user_group }}" effective_user_home: "{{ user_home }}" +emacs_enabled: false xdg_user_directories: - Desktop diff --git a/ansible/inventory/group_vars/desktop.yml b/ansible/inventory/group_vars/desktop.yml index 90c2766..2596013 100644 --- a/ansible/inventory/group_vars/desktop.yml +++ b/ansible/inventory/group_vars/desktop.yml @@ -94,10 +94,6 @@ desktop_common_dotfiles: src: .bashrc.d/20-editor-desktop.sh dest: .bashrc.d/20-editor-desktop.sh mode: "0644" - - name: Bash Emacs client fragment - src: .bashrc.d/25-emacs-client-desktop.sh - dest: .bashrc.d/25-emacs-client-desktop.sh - mode: "0644" - name: Bash VM helper fragment src: .bashrc.d/30-runvm.sh dest: .bashrc.d/30-runvm.sh @@ -170,6 +166,10 @@ desktop_minimal_managed_paths: - .local/bin/udiskie-password desktop_emacs_dotfiles: + - name: Bash Emacs client fragment + src: .bashrc.d/25-emacs-client-desktop.sh + dest: .bashrc.d/25-emacs-client-desktop.sh + mode: "0644" - name: Emacs config src: .emacs.d/ dest: .emacs.d/ @@ -239,6 +239,28 @@ desktop_hyprland_dotfiles: dest: .config/foot/ mode: preserve +desktop_niri_dotfiles: + - name: foot config + src: .config/foot/ + dest: .config/foot/ + mode: preserve + - name: dunst config + src: .config/dunst/ + dest: .config/dunst/ + mode: preserve + - name: rofi config + src: .config/rofi/ + dest: .config/rofi/ + mode: preserve + - name: waybar config + src: .config/waybar/ + dest: .config/waybar/ + mode: preserve + - name: niri config + src: .config/niri/ + dest: .config/niri/ + mode: preserve + desktop_xfce_dotfiles: - name: XFCE configuration src: .config/xfce4/ diff --git a/ansible/inventory/group_vars/desktop_niri.yml b/ansible/inventory/group_vars/desktop_niri.yml new file mode 100644 index 0000000..0eecb94 --- /dev/null +++ b/ansible/inventory/group_vars/desktop_niri.yml @@ -0,0 +1,3 @@ +--- +desktop_profile: niri +desktop_default_session: niri diff --git a/ansible/inventory/group_vars/platform_freebsd.yml b/ansible/inventory/group_vars/platform_freebsd.yml index e167fd0..353f434 100644 --- a/ansible/inventory/group_vars/platform_freebsd.yml +++ b/ansible/inventory/group_vars/platform_freebsd.yml @@ -75,6 +75,19 @@ freebsd_hyprland_packages: - xdg-desktop-portal-hyprland - xwayland +freebsd_niri_packages: + - cliphist + - dunst + - foot + - grim + - niri + - rofi-wayland + - seatd + - slurp + - waybar + - wl-clipboard + - xdg-desktop-portal-gtk + freebsd_lab_packages: - lldb - llvm diff --git a/ansible/inventory/group_vars/platform_mint.yml b/ansible/inventory/group_vars/platform_mint.yml index ba73734..7aaa3f2 100644 --- a/ansible/inventory/group_vars/platform_mint.yml +++ b/ansible/inventory/group_vars/platform_mint.yml @@ -38,32 +38,14 @@ mint_development_packages: - python3-venv mint_desktop_common_packages: - # autoconf/automake/libtool-bin build the Emacs pdf-tools (epdfinfo) and - # vterm native modules; the lib*-dev headers below are their link deps. - - autoconf - - automake - dconf-cli - deja-dup - - emacs - firefox - fonts-liberation - fonts-noto-color-emoji - git-delta - gnome-keyring - # hunspell CLI + Italian dictionary for Emacs spell checking (spell.el sets - # ispell-really-hunspell); hunspell-en-us is pulled in as a dependency. - - hunspell - - hunspell-it - - libfreetype-dev - # pdf-tools epdfinfo build deps (poppler); libpng-dev/zlib1g-dev are already - # satisfied by other packages. - - libpoppler-glib-dev - - libpoppler-private-dev - libsecret-tools - - libtool-bin - # vterm/multi-vterm native module (compiled against system libvterm). - - libvterm-dev - - libx11-dev - mpv - pinentry-gnome3 - pinentry-gtk2 @@ -74,6 +56,19 @@ mint_desktop_common_packages: - xdg-user-dirs - yt-dlp +mint_emacs_packages: + - autoconf + - automake + - emacs + - hunspell + - hunspell-it + - libfreetype-dev + - libpoppler-glib-dev + - libpoppler-private-dev + - libtool-bin + - libvterm-dev + - libx11-dev + mint_cinnamon_packages: - cinnamon - cinnamon-control-center @@ -95,13 +90,11 @@ mint_flatpak_packages: - com.spotify.Client - org.telegram.desktop -# Nerd Fonts referenced by the desktop configs deployed on Mint (fontconfig -# symbols, Emacs UI/vterm). Debian has no equivalent of Void's nerd-fonts-ttf -# package, so they are fetched from the upstream ryanoasis/nerd-fonts release. +# Nerd Fonts referenced by the desktop configs deployed on Mint. Debian has no +# equivalent of Void's nerd-fonts-ttf package, so they are fetched from the +# upstream ryanoasis/nerd-fonts release. mint_nerd_fonts_version: v3.3.0 mint_nerd_fonts: - Hack - # Archive is named UbuntuSans; it ships the "UbuntuSansMono Nerd Font" faces - # referenced by the Emacs UI config. - UbuntuSans - NerdFontsSymbolsOnly diff --git a/ansible/inventory/group_vars/void.yml b/ansible/inventory/group_vars/void.yml index 848d2d0..c6e543b 100644 --- a/ansible/inventory/group_vars/void.yml +++ b/ansible/inventory/group_vars/void.yml @@ -100,13 +100,15 @@ desktop_common_packages: - cups-pk-helper - flatpak - libsecret - - pinentry-emacs - sane - sane-airscan - turnstile - xdg-desktop-portal - xdg-user-dirs +desktop_emacs_packages: + - pinentry-emacs + desktop_minimal_packages: - alacritty - blueman @@ -228,7 +230,6 @@ profile_packages: - deluge-gtk - delve - dnsmasq - - emacs-pgtk - poppler-glib - poppler-utils - fontconfig-devel @@ -270,3 +271,6 @@ profile_packages: - yaru - yaru-plus - zstd + +profile_emacs_packages: + - emacs-pgtk diff --git a/ansible/inventory/host_vars/nymph.yml b/ansible/inventory/host_vars/nymph.yml index fd624b2..37bf693 100644 --- a/ansible/inventory/host_vars/nymph.yml +++ b/ansible/inventory/host_vars/nymph.yml @@ -1,44 +1,7 @@ --- hostname: nymph -desktop_emptty_session_error_logging: rotate - -host_packages: - - nvidia580 - - linux-mainline-headers - - mesa-dri - - vulkan-loader - - mesa-vulkan-intel - - intel-video-accel - - power-profiles-daemon - - tlp - - tlp-rdw - - upower - -host_enabled_services: - - tlp - -host_sway_dotfiles: - - src: .config/sway/host.conf - dest: .config/sway/host.conf - mode: "0644" - - src: .config/sway/session-env - dest: .config/sway/session-env - mode: "0644" - - src: .config/kanshi/ - dest: .config/kanshi/ - mode: preserve - - src: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf - dest: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf - mode: "0644" - -host_hyprland_dotfiles: - - src: .config/hypr/host.conf - dest: .config/hypr/host.conf - mode: "0644" - - src: .config/hypr/session-env - dest: .config/hypr/session-env - mode: "0644" - - src: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf - dest: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf - mode: "0644" +# FreeBSD/Niri laptop target. Keep host-specific packages empty until hardware +# support is verified on the installed system. +host_packages: [] +host_enabled_services: [] diff --git a/ansible/inventory/hosts.yml b/ansible/inventory/hosts.yml index befcd25..8f63a4d 100644 --- a/ansible/inventory/hosts.yml +++ b/ansible/inventory/hosts.yml @@ -10,7 +10,9 @@ all: ansible_connection: local platform_freebsd: - hosts: {} + hosts: + nymph: + ansible_connection: local void: children: @@ -43,8 +45,13 @@ all: desktop_hyprland: hosts: {} + desktop_niri: + hosts: + nymph: + ansible_connection: local + desktop_cinnamon: - hosts: + hosts: ikaros: ansible_connection: local diff --git a/ansible/roles/packages_freebsd/tasks/main.yml b/ansible/roles/packages_freebsd/tasks/main.yml index 627dc20..23bde2d 100644 --- a/ansible/roles/packages_freebsd/tasks/main.yml +++ b/ansible/roles/packages_freebsd/tasks/main.yml @@ -17,6 +17,11 @@ if 'desktop_hyprland' in group_names else [] ) + + ( + (freebsd_niri_packages | default([])) + if 'desktop_niri' in group_names + else [] + ) + ( (freebsd_lab_packages | default([])) if 'role_lab' in group_names diff --git a/ansible/roles/packages_mint/tasks/main.yml b/ansible/roles/packages_mint/tasks/main.yml index 2486129..df40d33 100644 --- a/ansible/roles/packages_mint/tasks/main.yml +++ b/ansible/roles/packages_mint/tasks/main.yml @@ -19,6 +19,14 @@ if 'graphical_desktop' in group_names else [] ) + + ( + (mint_emacs_packages | default([])) + if ( + 'graphical_desktop' in group_names + and (emacs_enabled | default(false) | bool) + ) + else [] + ) + ( (mint_cinnamon_packages | default([])) if 'desktop_cinnamon' in group_names diff --git a/ansible/roles/packages_void/tasks/main.yml b/ansible/roles/packages_void/tasks/main.yml index 78c31ce..8275232 100644 --- a/ansible/roles/packages_void/tasks/main.yml +++ b/ansible/roles/packages_void/tasks/main.yml @@ -105,7 +105,9 @@ (common_packages | default([])) + (void_packages_base | default([])) + (profile_packages | default([])) + + ((profile_emacs_packages | default([])) if (emacs_enabled | default(false) | bool) else []) + (desktop_common_packages | default([])) + + ((desktop_emacs_packages | default([])) if (emacs_enabled | default(false) | bool) else []) + (packages_void_selected_desktop_packages | default([])) + (host_packages | default([])) ) diff --git a/ansible/roles/profile_desktop_cinnamon/tasks/main.yml b/ansible/roles/profile_desktop_cinnamon/tasks/main.yml index 66cae08..2e7b712 100644 --- a/ansible/roles/profile_desktop_cinnamon/tasks/main.yml +++ b/ansible/roles/profile_desktop_cinnamon/tasks/main.yml @@ -40,6 +40,7 @@ owner: "{{ username }}" group: "{{ user_group }}" mode: "0755" + when: emacs_enabled | default(false) | bool - name: Ensure GnuPG directory exists tags: [dotfiles, dotfiles:desktop, git] @@ -71,6 +72,7 @@ group: "{{ user_group }}" mode: "{{ item.mode }}" loop: "{{ desktop_emacs_dotfiles | default([]) }}" + when: emacs_enabled | default(false) | bool loop_control: label: "{{ item.dest }}" diff --git a/ansible/roles/profile_desktop_common/tasks/main.yml b/ansible/roles/profile_desktop_common/tasks/main.yml index ced6143..1270fd1 100644 --- a/ansible/roles/profile_desktop_common/tasks/main.yml +++ b/ansible/roles/profile_desktop_common/tasks/main.yml @@ -315,6 +315,7 @@ group: "{{ user_group }}" mode: "{{ item.mode }}" loop: "{{ desktop_emacs_dotfiles | default([]) }}" + when: emacs_enabled | default(false) | bool loop_control: label: "{{ item.dest }}" @@ -564,7 +565,7 @@ label: "{{ item.name }}" - name: Install desktop Python tools with uv - tags: [packages, emacs] + tags: [packages] ansible.builtin.command: cmd: "uv tool install --upgrade {{ item }}" become: true diff --git a/ansible/roles/profile_desktop_niri_freebsd/tasks/main.yml b/ansible/roles/profile_desktop_niri_freebsd/tasks/main.yml new file mode 100644 index 0000000..51d1f58 --- /dev/null +++ b/ansible/roles/profile_desktop_niri_freebsd/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Ensure FreeBSD Niri user config directories exist + tags: [dotfiles, dotfiles:desktop, niri] + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "0755" + loop: + - "{{ user_home }}/.config" + - "{{ user_home }}/.config/dunst" + - "{{ user_home }}/.config/foot" + - "{{ user_home }}/.config/niri" + - "{{ user_home }}/.config/rofi" + - "{{ user_home }}/.config/waybar" + - "{{ user_home }}/.local" + - "{{ user_home }}/.local/bin" + - "{{ user_home }}/.local/state" + - "{{ user_home }}/.local/state/ssh-agent" + +- name: Copy common Niri desktop dotfiles on FreeBSD + tags: [dotfiles, dotfiles:desktop, niri] + ansible.builtin.copy: + src: "{{ playbook_dir }}/../dotfiles/desktop/{{ item.src }}" + dest: "{{ user_home }}/{{ item.dest }}" + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "{{ item.mode }}" + loop: "{{ desktop_niri_dotfiles | default([]) }}" + loop_control: + label: "{{ item.dest }}" + +- name: Render FreeBSD Niri session launcher + tags: [packages, services, niri] + ansible.builtin.template: + src: start-niri-session.j2 + dest: /usr/local/bin/start-niri-session + owner: root + group: wheel + mode: "0755" diff --git a/ansible/roles/profile_desktop_niri_freebsd/templates/start-niri-session.j2 b/ansible/roles/profile_desktop_niri_freebsd/templates/start-niri-session.j2 new file mode 100644 index 0000000..2101951 --- /dev/null +++ b/ansible/roles/profile_desktop_niri_freebsd/templates/start-niri-session.j2 @@ -0,0 +1,24 @@ +#!/bin/sh + +[ -r /etc/profile ] && . /etc/profile +[ -r "$HOME/.profile" ] && . "$HOME/.profile" + +export XDG_CURRENT_DESKTOP=niri +export XDG_SESSION_DESKTOP=niri +export XDG_SESSION_TYPE=wayland + +export MOZ_ENABLE_WAYLAND=1 +export QT_QPA_PLATFORM='wayland;xcb' +export _JAVA_AWT_WM_NONREPARENTING=1 +export SDL_VIDEODRIVER=wayland +export GDK_BACKEND='wayland,x11' + +export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket" + +[ -r "$HOME/.config/niri/session-env" ] && . "$HOME/.config/niri/session-env" + +if command -v dbus-run-session >/dev/null 2>&1; then + exec dbus-run-session niri --session +fi + +exec niri --session diff --git a/ansible/site.yml b/ansible/site.yml index 160c9e8..0e8c96f 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -79,12 +79,12 @@ roles: - profile_lab -- name: Configure Hyprland desktop on FreeBSD - hosts: platform_freebsd:&desktop_hyprland +- name: Configure Niri desktop on FreeBSD + hosts: platform_freebsd:&desktop_niri become: true roles: - - profile_desktop_hyprland_freebsd + - profile_desktop_niri_freebsd - name: Configure Fedora workstation development layer hosts: workstation_dev_fedora diff --git a/ansible/templates/desktop/.gitconfig.j2 b/ansible/templates/desktop/.gitconfig.j2 index 3db770a..3a2d06d 100644 --- a/ansible/templates/desktop/.gitconfig.j2 +++ b/ansible/templates/desktop/.gitconfig.j2 @@ -29,9 +29,19 @@ [mergetool] prompt = false +[mergetool "meld"] + cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED" + trustExitCode = false + [diff] tool = meld +[difftool] + prompt = false + +[difftool "meld"] + cmd = meld "$LOCAL" "$REMOTE" + [color] ui = always diff --git a/dotfiles/desktop/.bashrc.d/20-editor-desktop.sh b/dotfiles/desktop/.bashrc.d/20-editor-desktop.sh index 0e1b4e5..7aec4f1 100644 --- a/dotfiles/desktop/.bashrc.d/20-editor-desktop.sh +++ b/dotfiles/desktop/.bashrc.d/20-editor-desktop.sh @@ -1,2 +1,2 @@ export EDITOR=vim -export VISUAL=emacs +export VISUAL=vim diff --git a/dotfiles/desktop/.config/niri/config.kdl b/dotfiles/desktop/.config/niri/config.kdl new file mode 100644 index 0000000..32dcf59 --- /dev/null +++ b/dotfiles/desktop/.config/niri/config.kdl @@ -0,0 +1,88 @@ +// Minimal niri profile for the laptop. +// niri arranges windows in scrollable columns, which keeps small laptop screens usable. + +input { + keyboard { + xkb { + layout "us" + variant "intl" + } + } + + touchpad { + tap + natural-scroll + } +} + +layout { + gaps 12 + center-focused-column "on-overflow" + + preset-column-widths { + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + } + + default-column-width { proportion 0.5; } + + focus-ring { + width 4 + active-color "#54d6ff" + inactive-color "#505050" + } +} + +spawn-at-startup "waybar" + +prefer-no-csd +screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" + +binds { + Mod+Shift+Slash { show-hotkey-overlay; } + + Mod+Return hotkey-overlay-title="Open a Terminal" { spawn "foot"; } + Mod+D hotkey-overlay-title="Run an Application" { spawn "rofi" "-show" "drun"; } + Mod+B hotkey-overlay-title="Open Browser" { spawn "firefox"; } + + Mod+Q repeat=false { close-window; } + Mod+O repeat=false { toggle-overview; } + + Mod+H { focus-column-left; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+L { focus-column-right; } + + Mod+Ctrl+H { move-column-left; } + Mod+Ctrl+J { move-window-down; } + Mod+Ctrl+K { move-window-up; } + Mod+Ctrl+L { move-column-right; } + + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + Mod+Ctrl+U { move-column-to-workspace-down; } + Mod+Ctrl+I { move-column-to-workspace-up; } + + Mod+1 { focus-workspace 1; } + Mod+2 { focus-workspace 2; } + Mod+3 { focus-workspace 3; } + Mod+4 { focus-workspace 4; } + Mod+5 { focus-workspace 5; } + Mod+Ctrl+1 { move-column-to-workspace 1; } + Mod+Ctrl+2 { move-column-to-workspace 2; } + Mod+Ctrl+3 { move-column-to-workspace 3; } + Mod+Ctrl+4 { move-column-to-workspace 4; } + Mod+Ctrl+5 { move-column-to-workspace 5; } + + Mod+R { switch-preset-column-width; } + Mod+F { maximize-column; } + Mod+Shift+F { fullscreen-window; } + Mod+V { toggle-window-floating; } + + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + + Print { screenshot; } + Mod+Shift+E { quit; } +} diff --git a/dotfiles/desktop/.config/niri/session-env b/dotfiles/desktop/.config/niri/session-env new file mode 100644 index 0000000..4563f20 --- /dev/null +++ b/dotfiles/desktop/.config/niri/session-env @@ -0,0 +1 @@ +# Per-host Niri environment overrides. Empty by default.