diff --git a/iso/airootfs/etc/calamares/post-install.sh b/iso/airootfs/etc/calamares/post-install.sh index 66ba35b..2076dcf 100644 --- a/iso/airootfs/etc/calamares/post-install.sh +++ b/iso/airootfs/etc/calamares/post-install.sh @@ -33,6 +33,32 @@ rm -f /usr/local/bin/bos-live-setup /usr/local/bin/bos-launch-calamares rm -f /etc/sudoers.d/99-bos-live userdel -r liveuser 2>/dev/null || true +# unpackfs copies the entire live squashfs onto the target. Remove live-only +# packages (Calamares + archiso boot chain + memtest/EFI-shell payloads) so +# they do not stay on disk forever. pacman -Rs (not -Rns) keeps /etc configs +# and reaps newly-orphaned KF6/Qt6 deps. Each name is independent so one +# missing package cannot abort the rest. Offline-safe: never touches the +# network. qt6-declarative is NOT reaped — qt6-wayland still needs it. +LIVE_ONLY_PKGS=( + calamares + squashfs-tools + mkinitcpio-archiso + mkinitcpio-nfs-utils + memtest86+ + memtest86+-efi + edk2-shell + syslinux +) +for pkg in "${LIVE_ONLY_PKGS[@]}"; do + pacman -Qq "$pkg" &>/dev/null || continue + pacman -Rs --noconfirm "$pkg" &>/dev/null \ + || echo "WARN: could not remove live-only package $pkg" +done +while orphans="$(pacman -Qtdq 2>/dev/null)" && [[ -n "$orphans" ]]; do + # shellcheck disable=SC2086 + pacman -Rs --noconfirm $orphans &>/dev/null || break +done + # Root used a passwordless entry on the live medium; lock it (sudo model). passwd -l root || true @@ -344,15 +370,39 @@ fi # greetd — graphical login (shipped disabled; live uses tty autologin) # grub-btrfsd — regenerates GRUB snapshot entries (the unit is grub-btrfsd.service, # NOT grub-btrfs.path, which no longer exists) +# avahi-daemon.service → avahi-daemon.socket: the package ships both; socket +# activation still answers nss-mdns and CUPS discovery but stays off the idle +# RSS until something asks. The host stops announcing itself over mDNS until +# the socket is first touched. # --------------------------------------------------------------------------- for unit in NetworkManager.service bluetooth.service systemd-timesyncd.service \ tlp.service greetd.service snapper-cleanup.timer grub-btrfsd.service \ - fstrim.timer cups.socket avahi-daemon.service ufw.service \ + fstrim.timer cups.socket avahi-daemon.socket ufw.service \ fwupd-refresh.timer reflector.timer; do systemctl enable "$unit" || echo "WARN: failed to enable $unit" done systemctl set-default graphical.target || echo "WARN: set-default graphical failed" +# Arch's 90-systemd.preset enables systemd-homed / userdbd / nsresourced. +# BOS creates classic /etc/passwd accounts and never calls homectl. Mask +# (not disable) so preset-all or a systemd upgrade cannot re-enable them. +for unit in systemd-homed.service systemd-homed-activate.service \ + systemd-userdbd.service systemd-userdbd.socket \ + systemd-nsresourced.service systemd-nsresourced.socket; do + systemctl mask "$unit" || echo "WARN: failed to mask $unit" +done + +# journald defaults SystemMaxUse to 10% of the filesystem holding /var/log. +# /var/log is the @log subvolume of the root pool, so that ceiling is tens +# of GB. Cap it; less history for postmortems. +install -d -m 0755 /etc/systemd/journald.conf.d +cat >/etc/systemd/journald.conf.d/90-bos-journal.conf <<'JOURNALEOF' +[Journal] +SystemMaxUse=256M +SystemMaxFileSize=32M +RuntimeMaxUse=32M +JOURNALEOF + # --------------------------------------------------------------------------- # mDNS resolution (nss-mdns): insert mdns_minimal into the hosts: line so the # resolver answers *.local (network printers, other hosts) via avahi. Idempotent. diff --git a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua index 41c807f..5262654 100644 --- a/iso/airootfs/etc/skel/.config/hypr/hyprland.lua +++ b/iso/airootfs/etc/skel/.config/hypr/hyprland.lua @@ -94,6 +94,12 @@ pcall(function() bindings = binds.bindings, }) end) +-- 3-finger horizontal trackpad swipe → workspace switch (1:1 gesture) +hl.gesture({ + fingers = 3, + direction = "horizontal", + action = "workspace", +}) -- --------------------------------------------------------------------------- -- Autostart. Core bootstrap sequence (polkit agent, dark theme, wallpaper @@ -168,10 +174,3 @@ hl.on("hyprland.start", function() hl.dispatch(hl.dsp.exec_cmd(cmd)) end end) - - -hl.gesture({ - fingers = 3, - direction = "horizontal", - action = "workspace", -}) diff --git a/iso/packages.x86_64 b/iso/packages.x86_64 index ad76c71..cc8e2e2 100644 --- a/iso/packages.x86_64 +++ b/iso/packages.x86_64 @@ -1,9 +1,26 @@ # Base system base -base-devel linux -linux-firmware -linux-headers +# linux-firmware metapackage pulls every mandatory vendor blob (incl. nvidia). +# List the subpackages we actually need so nvidia (~103 MiB, nouveau-only — +# BOS ships no NVIDIA driver) can stay off the image. Turing+ nouveau needs +# the GSP blobs; reinstall linux-firmware-nvidia when lspci sees NVIDIA. +# linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-realtek +linux-firmware-radeon +linux-firmware-other +# linux-firmware-nvidia +# base-devel + linux-headers are for AUR/DKMS builds. yay needs base-devel, +# but those builds need network anyway — pacman -S base-devel at that point. +# linux-headers is DKMS-only and BOS ships no DKMS packages. +# base-devel +# linux-headers # CPU microcode — applied early by GRUB on the installed system (picked up by # the bootloader module). amd-ucode for the dev laptop's Ryzen; intel-ucode for # Intel targets. bos-copy-kernel also stages these into the live target /boot. @@ -44,7 +61,7 @@ sbctl squashfs-tools # rsync: unpackfs copies the unpacked rootfs onto the target with rsync. rsync -# Live-ISO boot (archiso bootmodes: bios.syslinux + uefi.systemd-boot) +# Live-ISO boot (archiso bootmodes: bios.syslinux + uefi.grub) # mkinitcpio-archiso provides the initramfs hooks that find and mount # airootfs.sfs and switch root into it — without it the live ISO drops # to emergency mode on boot. @@ -131,7 +148,9 @@ wayland-protocols # Fonts noto-fonts -noto-fonts-cjk +# noto-fonts-cjk is ~299 MiB installed / ~196 MiB on the ISO and only useful +# to CJK-locale users. Install on first run for zh/ja/ko. +# noto-fonts-cjk noto-fonts-emoji ttf-jetbrains-mono # Nerd font variant — icons in terminal tools (eza --icons, fastfetch, yazi) @@ -157,13 +176,12 @@ file-roller # GUI applications a general desktop is expected to have out of the box. # gnome-text-editor: graphical editor (terminal editors aside); gnome-calculator: -# calculator; loupe: Wayland-native image viewer (default for image files); -# zathura(+pdf-mupdf): lightweight Wayland PDF viewer (BOS had no PDF reader). +# calculator; loupe: Wayland-native image viewer (default for image files). +# PDF is handled by Zen (skel mimeapps.list maps application/pdf to zen.desktop); +# zathura+zathura-pdf-mupdf would pull libmupdf (~56 MiB) as a never-default viewer. gnome-text-editor gnome-calculator loupe -zathura -zathura-pdf-mupdf # Media player — BOS ships gstreamer codecs but otherwise has no player app. vlc # Web browser (served from the [Breadway] repo; AUR zen-browser-bin republished diff --git a/iso/pacman.conf b/iso/pacman.conf index 7e15c7a..506b4bb 100644 --- a/iso/pacman.conf +++ b/iso/pacman.conf @@ -9,6 +9,23 @@ Architecture = auto CheckSpace ParallelDownloads = 5 +# Optional NoExtract size levers — left disabled. This file is both the ISO +# build config AND the installed system's pacman.conf, so enabling any line +# also stops future pacman -Syu from restoring those files. +# Measured against the 844-package closure (xz squashfs, profiledef.sh opts): +# usr/share/locale (non-en) 405.0 MiB raw -> 92.28 MiB ISO +# usr/share/doc 130.5 MiB raw -> 26.54 MiB ISO +# usr/share/man 41.5 MiB raw -> 38.77 MiB ISO +# usr/share/info 12.9 MiB raw -> 11.12 MiB ISO +# usr/share/gtk-doc 16.0 MiB raw -> 1.18 MiB ISO +# usr/include 193.6 MiB raw -> 25.26 MiB ISO +# Non-en locales make every GUI English-only until the package is reinstalled +# without this NoExtract; dropping man/info means `man` returns nothing. +#NoExtract = usr/share/locale/* !usr/share/locale/en* !usr/share/locale/locale.alias +#NoExtract = usr/share/doc/* usr/share/gtk-doc/* usr/share/info/* +#NoExtract = usr/share/man/* +#NoExtract = usr/include/* + Color VerbosePkgLists ILoveCandy diff --git a/iso/profiledef.sh b/iso/profiledef.sh index aa92318..c438138 100644 --- a/iso/profiledef.sh +++ b/iso/profiledef.sh @@ -8,7 +8,12 @@ iso_application="Bread Operating System" iso_version="$(date +%Y.%m.%d)" install_dir="arch" buildmodes=('iso') -bootmodes=('bios.syslinux' 'uefi.systemd-boot') +# systemd-boot can only read files from the ESP it was launched from, so +# mkarchiso's _make_bootmode_uefi.systemd-boot copies vmlinuz + initramfs +# INTO the FAT efiboot.img on top of the copy already on ISO9660 (~244 MiB +# duplicate). uefi.grub's ESP is only EFI + shell*.efi — GRUB reads ISO9660 +# directly. iso/grub/{grub,loopback}.cfg are already BOS-branded. +bootmodes=('bios.syslinux' 'uefi.grub') arch="x86_64" pacman_conf="pacman.conf" airootfs_image_type="squashfs" diff --git a/packaging/bibata/PKGBUILD b/packaging/bibata/PKGBUILD index b49e382..b713436 100644 --- a/packaging/bibata/PKGBUILD +++ b/packaging/bibata/PKGBUILD @@ -16,7 +16,13 @@ options=('!strip') source=("${pkgname%-bin}-$pkgver.tar.xz::$url/releases/download/v$pkgver/Bibata.tar.xz") sha256sums=('172e33c4ae415278384dcecc7d1a9b7a024266bc944bc751fd86532be1cc6251') +# Upstream tarball has all 12 variants (~322 MiB). BOS only ever selects +# Bibata-Modern-Ice (hyprland.lua XCURSOR_THEME, gsettings, gtk settings.ini). +# Ship that plus its -Right sibling. +_variants=(Bibata-Modern-Ice Bibata-Modern-Ice-Right) package() { install -d "$pkgdir/usr/share/icons" - cp -r Bibata* "$pkgdir/usr/share/icons" + for v in "${_variants[@]}"; do + cp -r "$v" "$pkgdir/usr/share/icons/" + done }