diff --git a/.config/dms/settings.json b/.config/dms/settings.json index 9f189ea..81e1ffb 100644 --- a/.config/dms/settings.json +++ b/.config/dms/settings.json @@ -269,5 +269,7 @@ "monoFontFamily": "JetBrains Mono", "displayFontFamily": "JetBrains Mono", "fontWeight": 300, - "fontScale": 1 + "fontScale": 1, + "currentThemeName": "pink", + "wallpaperFillMode": "Fill" } \ No newline at end of file diff --git a/.config/sway/config.d/50-dms.conf b/.config/sway/config.d/50-dms.conf index 0cd0396..880c9f2 100644 --- a/.config/sway/config.d/50-dms.conf +++ b/.config/sway/config.d/50-dms.conf @@ -1,6 +1,9 @@ # DankMaterialShell: bar, launcher, control center, notifications (replaces waybar/swaync/rofi launcher) exec_always sh -c 'pgrep -x dms >/dev/null || exec dms run' +# First login on a new machine: wallpaper + monitor layout (does nothing when already set up) +exec ~/.config/sway/firstrun.sh + # Hotkeys: $mod+d launcher, $mod+n control center, $mod+Shift+n notifications, $mod+Shift+p power menu (set in config / config.d) bindsym --to-code $mod+Shift+v exec dms ipc call clipboard toggle diff --git a/.config/sway/config.d/60-autostart.conf b/.config/sway/config.d/60-autostart.conf index 8613d92..8474492 100644 --- a/.config/sway/config.d/60-autostart.conf +++ b/.config/sway/config.d/60-autostart.conf @@ -1,4 +1,5 @@ -# Autostart (xdg-autostart does not run under sway). Delayed so the DMS tray is ready; guarded against duplicates. -exec sh -c 'sleep 5; pgrep -f "[n]extcloud.*--background" >/dev/null || flatpak run com.nextcloud.desktopclient.nextcloud --background' -exec sh -c 'sleep 5; pgrep -f "[R]emmina.* -i" >/dev/null || flatpak run org.remmina.Remmina -i' -exec sh -c 'sleep 8; pgrep -x geary >/dev/null || geary --gapplication-service' +# Autostart (xdg-autostart does not run under sway). Delayed so the DMS tray is ready; +# guarded against duplicates and against apps that are not installed on this machine. +exec sh -c 'sleep 5; flatpak info com.nextcloud.desktopclient.nextcloud >/dev/null 2>&1 && ! pgrep -f "[n]extcloud.*--background" >/dev/null && flatpak run com.nextcloud.desktopclient.nextcloud --background' +exec sh -c 'sleep 5; flatpak info org.remmina.Remmina >/dev/null 2>&1 && ! pgrep -f "[R]emmina.* -i" >/dev/null && flatpak run org.remmina.Remmina -i' +exec sh -c 'sleep 8; command -v geary >/dev/null && ! pgrep -x geary >/dev/null && geary --gapplication-service' diff --git a/.config/sway/doctor.sh b/.config/sway/doctor.sh index b722b9d..0faa6dc 100755 --- a/.config/sway/doctor.sh +++ b/.config/sway/doctor.sh @@ -22,6 +22,10 @@ if have dms; then pgrep -x dms >/dev/null && ok "dms is running" || { [ -n "${SWAYSOCK:-}" ] && bad "dms is not running" || warn "dms not running (not in session)"; } else bad "dms not installed"; fi [ -f "$CFG/dms/settings.json" ] && ok "DMS settings present" || warn "no DMS settings yet" +if have dms && pgrep -x dms >/dev/null; then + w=$(dms ipc call wallpaper get 2>/dev/null | head -1) + case $w in /*) ok "wallpaper set in DMS ($(basename "$w"))";; *) warn "no wallpaper chosen in DMS yet (firstrun.sh sets one at the next sway start)";; esac +fi section "Session / portals" if systemctl --user is-active sway-session.target >/dev/null 2>&1; then ok "sway-session.target active" @@ -46,7 +50,7 @@ done section "Per-machine config" [ -f "$CFG/sway/config.d/05-outputs.conf" ] && ok "monitor layout (05-outputs.conf)" || warn "no monitor layout yet: run ~/.config/sway/outputs-setup.sh inside sway" -for t in grim swappy jq swaylock swayidle brightnessctl wl-copy notify-send; do have "$t" && ok "$t" || warn "$t missing"; done +for t in nautilus grim swappy jq swaylock swayidle brightnessctl wl-copy notify-send; do have "$t" && ok "$t" || warn "$t missing"; done printf '\n'; [ "$fails" -eq 0 ] && echo "No failures." || echo "$fails failure(s)." exit "$fails" diff --git a/.config/sway/firstrun.sh b/.config/sway/firstrun.sh new file mode 100755 index 0000000..737b910 --- /dev/null +++ b/.config/sway/firstrun.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# Runs at every sway start; does something only on a fresh machine (idempotent): +# - picks the shipped wallpaper in DMS when none is chosen yet +# - generates the monitor layout when this machine has none +cfg=${XDG_CONFIG_HOME:-$HOME/.config} +walls=$HOME/.local/share/backgrounds + +# wait until DMS has registered its IPC targets (up to ~40 s) +i=0 +while [ "$i" -lt 40 ]; do + dms ipc show 2>/dev/null | grep -q '^target wallpaper' && break + i=$((i+1)); sleep 1 +done +cur=$(dms ipc call wallpaper get 2>/dev/null | head -1) + +# DMS prints the path when a wallpaper is set; anything else means "none yet" +case "$cur" in + /*) ;; + *) [ -f "$walls/kitty.jpg" ] && dms ipc call wallpaper set "$walls/kitty.jpg" >/dev/null 2>&1 ;; +esac + +# monitor layout (laptop panel left, the rest to the right); the file is per machine +[ -e "$cfg/sway/config.d/05-outputs.conf" ] || "$cfg/sway/outputs-setup.sh" --auto >/dev/null 2>&1 +exit 0 diff --git a/README.md b/README.md index e494cc4..8c8d5f2 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ | `.config/sway/config.d/60-autostart.conf` | автозапуск Nextcloud, Remmina и Geary (xdg-autostart в sway не работает) | | `.config/sway/screenshot.sh` | все режимы скриншотов (см. ниже) | | `.config/sway/{lock,idle,cheatsheet}.sh` | блокировка (DMS, запасной swaylock), swayidle, шпаргалка по хоткеям | -| `.config/sway/outputs-setup.sh`, `doctor.sh` | настройка мониторов под новое железо; проверка здоровья системы | +| `.config/sway/outputs-setup.sh`, `firstrun.sh`, `doctor.sh` | раскладка мониторов под новое железо; первый запуск (обои, мониторы); проверка здоровья системы | | `.config/dms/settings.json` | настройки DMS: виджеты бара (раскладка, VPN, температура, приватность), шрифты, панель управления | | `.config/kitty/kitty.conf` | JetBrains Mono, палитра Tokyo Night, прозрачность, вкладки (`Ctrl+Shift+←/→`) и сплиты (`Ctrl+Alt+стрелки`); `Ctrl+C` копирует выделенное (без выделения прерывает), `Ctrl+V` вставляет | | `.config/swappy/config` | редактор скриншотов (стрелки, текст, размытие) | @@ -74,30 +74,33 @@ На свежей Fedora (Workstation или любой вариант с `git`): ```sh -git clone git@git.ibrash.duckdns.org:aibrash/sway-rising.git && cd sway-rising && ./install.sh +git clone git@git.ibrash.duckdns.org:aibrash/sway-rising.git && cd sway-rising && ./install.sh --with-apps ``` Репозиторий клонируется по ssh, поэтому на новой машине сначала нужен ваш ключ (`~/.ssh/id_ed25519`) или ключ, добавленный на git-сервер. -Скрипт спрашивает подтверждение перед каждым COPR и больше ни о чём не спрашивает. Для полностью автоматического режима: `./install.sh --yes`. +Скрипт спрашивает подтверждение перед каждым COPR и больше ни о чём не спрашивает. Без вопросов вообще: добавьте `--yes`. Без `--with-apps` ставится только сам райс и инструменты терминала. Что он делает: -1. Ставит пакеты через `dnf`: сессия sway (`sway-systemd`, порталы), kitty, swaylock/swayidle, grim, swappy (аннотации скриншотов), шрифты JetBrains Mono и Font Awesome, тема `adw-gtk3`. +1. Ставит пакеты через `dnf`: сессия sway (`sway-systemd`, порталы), kitty, nautilus, swaylock/swayidle, grim, swappy (аннотации скриншотов), шрифты JetBrains Mono и Font Awesome, тема `adw-gtk3`. 2. Подключает COPR `swayfx/swayfx` и `avengemedia/dms` и ставит SwayFX и DankMaterialShell. 3. Ставит CLI: zsh, tmux, fzf, zoxide, eza, bat, fd, ripgrep, ncdu, fastfetch, lazygit (бинарник с проверкой суммы), клонирует oh-my-zsh с плагинами. Опция `--with-tools` добавляет nmap, tcpdump, mtr, jq, btop, ansible. -4. **Делает бэкап** ваших конфигов в `~/rice-backup-<дата>` и копирует конфиги, обои (в `~/.local/share/backgrounds`), tmux и алиасы. Ваш `~/.zshrc` не трогает (его заменит только `--force-shell`). -5. Включает тему `adw-gtk3-dark` и проверяет конфиг (`sway -C`). +4. С `--with-apps`: gimp, keepassxc, libreoffice, mpv, obs-studio, qbittorrent, shotcut, yt-dlp, godot, rclone, gparted, geary и ваши flatpak (Telegram, Chrome, Nextcloud, Remmina, DBeaver, Discord и другие). +5. **Делает бэкап** ваших конфигов в `~/rice-backup-<дата>` и копирует конфиги, обои (в `~/.local/share/backgrounds`), tmux и алиасы. Ваш `~/.zshrc` не трогает (его заменит только `--force-shell`). +6. Включает тему `adw-gtk3-dark` и проверяет конфиг (`sway -C`). -После установки: выйти и выбрать на экране входа сессию **Sway**. Внутри сессии один раз выполнить +После установки: выйти и выбрать на экране входа сессию **Sway**. При первом запуске `firstrun.sh` сам выберет обои в DMS и сгенерирует раскладку мониторов (ноутбук слева, внешние справа, масштаб подбирается по разрешению). Результат можно поправить: `~/.config/sway/outputs-setup.sh` (с вопросами) или файл `~/.config/sway/config.d/05-outputs.conf`. -```sh -~/.config/sway/outputs-setup.sh # раскладка и масштаб мониторов (ноутбук слева, внешний справа) -``` +Тема DMS (цвета, шрифты, виджеты бара, прозрачность) хранится в `.config/dms/settings.json`: если вы меняете её в интерфейсе DMS, скопируйте файл обратно в репозиторий, чтобы изменения переехали на другие машины. -Файл раскладки мониторов намеренно не копируется: на другом железе другие имена выходов. В репозитории лежит только пример `05-outputs.conf.example`. +**Что не переезжает** (личное или с отдельными репозиториями): +- `~/.ssh/config` и ключи, база KeePassXC, входы в Nextcloud, Telegram и браузеры; +- `docker-ce` и VS Code (ставятся из сторонних репозиториев), `tailscale`; +- город для виджета погоды в DMS, подключения NetworkManager и VPN; +- файл `05-outputs.conf` (свой на каждой машине). -Проверка здоровья в любой момент: `./install.sh --check` (то же самое: `~/.config/sway/doctor.sh`). Показывает, что установлено, что работает, а что нет (DMS, порталы, шрифты, инструменты, раскладка мониторов). +Проверка здоровья в любой момент: `./install.sh --check` (то же самое: `~/.config/sway/doctor.sh`). Показывает, что установлено, что работает, а что нет (DMS, порталы, шрифты, инструменты, раскладка мониторов, обои). -Флаги: `--yes`, `--dry-run` (показать действия, ничего не менять), `--check`, `--no-packages`, `--no-dms`, `--no-shell`, `--with-tools`, `--force-shell`. Можно запускать повторно. +Флаги: `--yes`, `--dry-run` (показать действия, ничего не менять), `--check`, `--no-packages`, `--no-dms`, `--no-shell`, `--with-tools`, `--with-apps`, `--force-shell`. Можно запускать повторно. DMS запускается из `config.d/50-dms.conf`, руками его запускать не нужно. Диагностика самого DMS: `dms doctor`. diff --git a/install.sh b/install.sh index a49d02d..22c2cfb 100755 --- a/install.sh +++ b/install.sh @@ -10,6 +10,7 @@ # --no-dms do not install DankMaterialShell # --no-shell skip zsh / oh-my-zsh / tmux / CLI tools # --with-tools also install sysadmin tools (nmap, tcpdump, mtr, jq, ansible, btop) +# --with-apps also install the everyday apps (gimp, keepassxc, obs, ... and the flatpaks) # --force-shell overwrite an existing ~/.zshrc (the old one is backed up) # -h, --help set -euo pipefail @@ -20,7 +21,7 @@ WALLS=$HOME/.local/share/backgrounds STAMP=$(date +%F-%H%M%S) BACKUP=$HOME/rice-backup-$STAMP -YES=0; DRY=0; CHECK=0; PACKAGES=1; DMS=1; SHELLSETUP=1; TOOLS=0; FORCE_SHELL=0 +YES=0; DRY=0; CHECK=0; PACKAGES=1; DMS=1; SHELLSETUP=1; TOOLS=0; APPS=0; FORCE_SHELL=0 for a in "$@"; do case $a in -y|--yes) YES=1 ;; @@ -30,8 +31,9 @@ for a in "$@"; do --no-dms) DMS=0 ;; --no-shell) SHELLSETUP=0 ;; --with-tools) TOOLS=1 ;; + --with-apps) APPS=1 ;; --force-shell) FORCE_SHELL=1 ;; - -h|--help) sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + -h|--help) sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; *) echo "unknown option: $a (try --help)" >&2; exit 1 ;; esac done @@ -47,15 +49,22 @@ NOTES=() # follow-up hints for the user # ---------------------------------------------------------------- packages (Fedora names, all verified with dnf) CORE_PKGS=( - sway-systemd # session target + env for portals + sway-systemd dbus-tools # session target + env for portals kitty swaylock swayidle grim swappy jq wl-clipboard brightnessctl libnotify - pavucontrol network-manager-applet wireplumber pipewire-pulseaudio + pavucontrol network-manager-applet nm-connection-editor wireplumber pipewire-pulseaudio nautilus # file manager (Super+O) xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk jetbrains-mono-fonts fontawesome-6-free-fonts adw-gtk3-theme ) SHELL_PKGS=(zsh tmux git curl fzf zoxide eza bat fd-find ripgrep ncdu fastfetch) TOOLS_PKGS=(nmap tcpdump mtr jq btop ansible) +# --with-apps: everyday apps. docker-ce and VS Code come from third-party repos and are not installed here. +APP_PKGS=(geary gimp keepassxc libreoffice-writer libreoffice-calc libreoffice-impress mpv obs-studio + qbittorrent shotcut yt-dlp godot rclone gparted) +APP_FLATPAKS=(org.telegram.desktop com.google.Chrome com.nextcloud.desktopclient.nextcloud org.remmina.Remmina + com.github.tchx84.Flatseal io.dbeaver.DBeaverCommunity com.discordapp.Discord + com.moonlight_stream.Moonlight org.prismlauncher.PrismLauncher com.freerdp.FreeRDP + com.mattjakeman.ExtensionManager) check_fedora() { local ID="" ID_LIKE="" @@ -109,6 +118,15 @@ install_lazygit() { rm -rf "$tmp" } +install_apps() { + say "Installing everyday apps (${#APP_PKGS[@]} rpm, ${#APP_FLATPAKS[@]} flatpak)" + dnf_install "${APP_PKGS[@]}" + if ! have flatpak; then dnf_install flatpak; fi + run sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true + run sudo flatpak install -y --noninteractive flathub "${APP_FLATPAKS[@]}" || FAILED+=("some flatpaks") + NOTES+=("Not installed (third-party repos): docker-ce, VS Code, tailscale. Add their repos if you need them.") +} + # ---------------------------------------------------------------- zsh / oh-my-zsh install_shell_extras() { local zsh_custom=$HOME/.oh-my-zsh/custom p @@ -157,19 +175,13 @@ backup_and_copy_configs() { install_wallpapers } -# Wallpapers are managed by DMS (Settings > Wallpaper); we only drop the shipped favourites into its folder +# Wallpapers are managed by DMS; we only drop the shipped favourites into its folder. +# The first sway start (firstrun.sh) picks one in DMS if none is chosen yet. install_wallpapers() { compgen -G "$REPO/wallpapers/*" >/dev/null || return 0 say "Copying wallpapers to $WALLS" run mkdir -p "$WALLS" if [ "$DRY" = 1 ]; then echo " [dry-run] cp -n wallpapers/* $WALLS/"; else cp -n "$REPO"/wallpapers/* "$WALLS/"; fi - local cur="" - if [ -n "${SWAYSOCK:-}" ] && have dms && pgrep -x dms >/dev/null; then cur=$(dms ipc call wallpaper get 2>/dev/null | head -1); fi - if [ "$DRY" = 0 ] && [ -n "${SWAYSOCK:-}" ] && pgrep -x dms >/dev/null && [ -z "$cur" ] && [ -f "$WALLS/kitty.jpg" ]; then - dms ipc call wallpaper set "$WALLS/kitty.jpg" >/dev/null 2>&1 || true # only when no wallpaper is chosen yet - elif [ -z "$cur" ]; then - NOTES+=("Wallpaper: pick one in DMS (Super+N > settings > Wallpaper); the shipped ones are in $WALLS") - fi } # GTK theme: adw-gtk3 (DMS recolors it); only when the user has no choice of their own yet @@ -222,6 +234,7 @@ if [ "$PACKAGES" = 1 ]; then install_lazygit fi if [ "$TOOLS" = 1 ]; then say "Installing sysadmin tools"; dnf_install "${TOOLS_PKGS[@]}"; fi + if [ "$APPS" = 1 ]; then install_apps; fi fi backup_and_copy_configs