Fix all issues from code/UX review
ISO structural:
- Move post-install.sh → airootfs/etc/calamares/ (it was never in the squashfs)
- Create airootfs/etc/skel/.config/ with all dotfiles (deploy path now works)
- Add iso/pacman.conf with [breadway] custom repo stub for calamares + bakery
- Add Calamares branding component (bos/branding.desc + show.qml)
- Add missing unpackfs.conf and mount.conf modules
- Add live-session autostart: getty autologin → bash_profile → Hyprland → calamares
- Add polkit rule for wheel-group snapper rollback (pkexec path)
- Remove wlroots from packages (bundled with Hyprland); add bakery to package list
- Fix modules-search path in settings.conf
Dotfiles:
- Rename dotfiles/hyprland/ → dotfiles/hypr/ (Hyprland reads ~/.config/hypr/)
- Fix deprecated shadow options: drop_shadow/shadow_range → shadow { } block
bos-settings Rust:
- Replace glib::MainContext::channel (removed in glib 0.19) with async_channel
- Stream bakery update output line-by-line instead of buffering all at once
- Fix zombie processes: per-package update buttons now wait() in a thread
- Fix sidebar/stack mismatch at startup: select snapshots row to match default view
- Replace deprecated MessageDialog with AlertDialog (GTK 4.10+) throughout
- Use pkexec for snapper rollback so polkit handles privilege escalation
- Add confirmation dialog before delete snapshot (was missing, rollback had one)
- Add refresh button + repopulate after delete in snapshots view
- Add "Saved" / "Error: …" status label to every config view save button
- Add "Remove" buttons to breadbox contexts and breadcrumbs profiles
- Remove hardcoded model string from breadpad defaults
- Drop unused state mod; fix config_dir HOME fallback; fix zombie in editor launches
https://claude.ai/code/session_01WszGHvCmxgcyTwNSkfLF9P
This commit is contained in:
parent
0ff3998c84
commit
d5913da277
32 changed files with 720 additions and 288 deletions
29
iso/airootfs/etc/calamares/branding/bos/branding.desc
Normal file
29
iso/airootfs/etc/calamares/branding/bos/branding.desc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
componentName: bos
|
||||
|
||||
strings:
|
||||
productName: "Bread Operating System"
|
||||
shortProductName: "BOS"
|
||||
version: "rolling"
|
||||
shortVersion: "rolling"
|
||||
versionedName: "BOS (rolling)"
|
||||
shortVersionedName: "BOS"
|
||||
bootloaderEntryName: "BOS"
|
||||
productUrl: "https://github.com/Breadway/bos"
|
||||
supportUrl: "https://github.com/Breadway/bos/issues"
|
||||
knownIssuesUrl: "https://github.com/Breadway/bos/issues"
|
||||
releaseNotesUrl: "https://github.com/Breadway/bos/releases"
|
||||
|
||||
images:
|
||||
productLogo: "logo.png"
|
||||
productIcon: "logo.png"
|
||||
productWelcome: "languages.png"
|
||||
|
||||
slideshow: "show.qml"
|
||||
slideshowAPI: 2
|
||||
|
||||
style:
|
||||
sidebarBackground: "#3b4252"
|
||||
sidebarText: "#eceff4"
|
||||
sidebarTextSelect: "#5e81ac"
|
||||
sidebarTextHighlight:"#eceff4"
|
||||
43
iso/airootfs/etc/calamares/branding/bos/show.qml
Normal file
43
iso/airootfs/etc/calamares/branding/bos/show.qml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* BOS installer slideshow */
|
||||
import QtQuick 2.15
|
||||
import io.calamares.ui 1.0
|
||||
|
||||
Presentation {
|
||||
id: presentation
|
||||
|
||||
Slide {
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#2e3440"
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 20
|
||||
|
||||
Text {
|
||||
text: "Bread Operating System"
|
||||
color: "#eceff4"
|
||||
font.pointSize: 28
|
||||
font.bold: true
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Installing your system…"
|
||||
color: "#88c0d0"
|
||||
font.pointSize: 16
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Hyprland · bread · bakery · snapshots"
|
||||
color: "#616e88"
|
||||
font.pointSize: 12
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
iso/airootfs/etc/calamares/modules/mount.conf
Normal file
10
iso/airootfs/etc/calamares/modules/mount.conf
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
# Extra mount options applied by filesystem type.
|
||||
# Btrfs subvolume mounts are already configured in partition.conf.
|
||||
mountOptions:
|
||||
- filesystem: default
|
||||
options: [noatime]
|
||||
- filesystem: btrfs
|
||||
options: [noatime, "compress=zstd", "space_cache=v2"]
|
||||
- filesystem: vfat
|
||||
options: [umask=0077]
|
||||
7
iso/airootfs/etc/calamares/modules/unpackfs.conf
Normal file
7
iso/airootfs/etc/calamares/modules/unpackfs.conf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
# Unpack the live squashfs onto the target partition.
|
||||
# "arch" matches profiledef.sh install_dir; adjust if that changes.
|
||||
unpack:
|
||||
- source: "/run/archiso/bootmnt/arch/x86_64/airootfs.sfs"
|
||||
sourcefs: "squashfs"
|
||||
destination: ""
|
||||
|
|
@ -9,7 +9,7 @@ sed -i 's/NUMBER_MIN_AGE="[^"]*"/NUMBER_MIN_AGE="1800"/' /etc/snapper/configs/ro
|
|||
sed -i 's/NUMBER_LIMIT="[^"]*"/NUMBER_LIMIT="10"/' /etc/snapper/configs/root
|
||||
sed -i 's/NUMBER_LIMIT_IMPORTANT="[^"]*"/NUMBER_LIMIT_IMPORTANT="5"/' /etc/snapper/configs/root
|
||||
|
||||
# Allow main user to use snapper without sudo
|
||||
# Allow main user to list/create/delete snapshots without sudo
|
||||
MAIN_USER=$(getent passwd 1000 | cut -d: -f1)
|
||||
sed -i "s/ALLOW_USERS=\"\"/ALLOW_USERS=\"$MAIN_USER\"/" /etc/snapper/configs/root
|
||||
|
||||
|
|
@ -19,18 +19,19 @@ systemctl enable bluetooth
|
|||
systemctl enable snapper-cleanup.timer
|
||||
systemctl enable grub-btrfs.path
|
||||
|
||||
# --- Bakery install ---
|
||||
# --- Bakery: install bread ecosystem ---
|
||||
# Requires [breadway] repo in /etc/pacman.conf — see iso/pacman.conf
|
||||
if command -v bakery &>/dev/null; then
|
||||
sudo -u "$MAIN_USER" bakery install bread breadbar breadbox breadcrumbs breadpad bos-settings
|
||||
fi
|
||||
|
||||
# --- Deploy dotfiles (skip existing files) ---
|
||||
DOTFILES_SRC="/etc/skel/.config"
|
||||
# --- Deploy dotfiles into user home (skip any file that already exists) ---
|
||||
SKEL_SRC="/etc/skel/.config"
|
||||
DOTFILES_DEST="/home/$MAIN_USER/.config"
|
||||
|
||||
if [[ -d "$DOTFILES_SRC" ]]; then
|
||||
if [[ -d "$SKEL_SRC" ]]; then
|
||||
mkdir -p "$DOTFILES_DEST"
|
||||
cp -rn "$DOTFILES_SRC/." "$DOTFILES_DEST/"
|
||||
cp -rn "$SKEL_SRC/." "$DOTFILES_DEST/"
|
||||
chown -R "$MAIN_USER:$MAIN_USER" "$DOTFILES_DEST"
|
||||
fi
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
modules-search: [local, /usr/lib/calamares/modules]
|
||||
modules-search: [/etc/calamares/modules, /usr/lib/calamares/modules]
|
||||
|
||||
sequence:
|
||||
- show:
|
||||
|
|
|
|||
11
iso/airootfs/etc/polkit-1/rules.d/10-snapper.rules
Normal file
11
iso/airootfs/etc/polkit-1/rules.d/10-snapper.rules
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Allow members of the wheel group to perform snapper rollback via pkexec
|
||||
// without a password prompt. Other snapper operations (list/create/delete)
|
||||
// are controlled by ALLOW_USERS in /etc/snapper/configs/root.
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "io.opensuse.Snapper.Rollback" &&
|
||||
subject.local &&
|
||||
subject.active &&
|
||||
subject.isInGroup("wheel")) {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
8
iso/airootfs/etc/skel/.config/bread/breadd.toml
Normal file
8
iso/airootfs/etc/skel/.config/bread/breadd.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
log_level = "info"
|
||||
|
||||
[adapters]
|
||||
keyboard = true
|
||||
mouse = true
|
||||
touchpad = true
|
||||
bluetooth = true
|
||||
gamepad = true
|
||||
1
iso/airootfs/etc/skel/.config/bread/init.lua
Normal file
1
iso/airootfs/etc/skel/.config/bread/init.lua
Normal file
|
|
@ -0,0 +1 @@
|
|||
bread.activate_profile("default")
|
||||
3
iso/airootfs/etc/skel/.config/breadbox/config.toml
Normal file
3
iso/airootfs/etc/skel/.config/breadbox/config.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[[context]]
|
||||
name = "default"
|
||||
apps = ["firefox", "foot", "nautilus", "code"]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[[profile]]
|
||||
name = "home"
|
||||
ssids = []
|
||||
56
iso/airootfs/etc/skel/.config/hypr/hyprland.conf
Normal file
56
iso/airootfs/etc/skel/.config/hypr/hyprland.conf
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
monitor=,preferred,auto,1
|
||||
|
||||
exec-once = breadd
|
||||
exec-once = breadbar
|
||||
exec-once = breadbox-sync
|
||||
|
||||
source = ~/.config/hypr/keybinds.conf
|
||||
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 10
|
||||
border_size = 2
|
||||
col.active_border = rgba(88c0d0ff)
|
||||
col.inactive_border = rgba(4c566aff)
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = 8
|
||||
blur {
|
||||
enabled = true
|
||||
size = 6
|
||||
passes = 2
|
||||
}
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 12
|
||||
render_power = 3
|
||||
}
|
||||
}
|
||||
|
||||
animations {
|
||||
enabled = true
|
||||
bezier = ease, 0.25, 0.1, 0.25, 1.0
|
||||
animation = windows, 1, 4, ease
|
||||
animation = fade, 1, 4, ease
|
||||
animation = workspaces, 1, 5, ease
|
||||
}
|
||||
|
||||
input {
|
||||
kb_layout = us
|
||||
follow_mouse = 1
|
||||
touchpad {
|
||||
natural_scroll = true
|
||||
}
|
||||
}
|
||||
|
||||
dwindle {
|
||||
pseudotile = true
|
||||
preserve_split = true
|
||||
}
|
||||
|
||||
misc {
|
||||
disable_hyprland_logo = true
|
||||
disable_splash_rendering = true
|
||||
}
|
||||
58
iso/airootfs/etc/skel/.config/hypr/keybinds.conf
Normal file
58
iso/airootfs/etc/skel/.config/hypr/keybinds.conf
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
$mod = SUPER
|
||||
|
||||
# App launchers
|
||||
bind = $mod, Space, exec, breadbox
|
||||
bind = $mod, N, exec, breadpad
|
||||
bind = $mod, M, exec, breadman
|
||||
bind = $mod, S, exec, bos-settings
|
||||
|
||||
# Core
|
||||
bind = $mod, Return, exec, foot
|
||||
bind = $mod, Q, killactive
|
||||
bind = $mod SHIFT, E, exit
|
||||
bind = $mod, F, fullscreen
|
||||
|
||||
# Focus
|
||||
bind = $mod, H, movefocus, l
|
||||
bind = $mod, L, movefocus, r
|
||||
bind = $mod, K, movefocus, u
|
||||
bind = $mod, J, movefocus, d
|
||||
|
||||
# Move windows
|
||||
bind = $mod SHIFT, H, movewindow, l
|
||||
bind = $mod SHIFT, L, movewindow, r
|
||||
bind = $mod SHIFT, K, movewindow, u
|
||||
bind = $mod SHIFT, J, movewindow, d
|
||||
|
||||
# Workspaces
|
||||
bind = $mod, 1, workspace, 1
|
||||
bind = $mod, 2, workspace, 2
|
||||
bind = $mod, 3, workspace, 3
|
||||
bind = $mod, 4, workspace, 4
|
||||
bind = $mod, 5, workspace, 5
|
||||
|
||||
bind = $mod SHIFT, 1, movetoworkspace, 1
|
||||
bind = $mod SHIFT, 2, movetoworkspace, 2
|
||||
bind = $mod SHIFT, 3, movetoworkspace, 3
|
||||
bind = $mod SHIFT, 4, movetoworkspace, 4
|
||||
bind = $mod SHIFT, 5, movetoworkspace, 5
|
||||
|
||||
# Scroll through workspaces
|
||||
bind = $mod, mouse_down, workspace, e+1
|
||||
bind = $mod, mouse_up, workspace, e-1
|
||||
|
||||
# Mouse binds
|
||||
bindm = $mod, mouse:272, movewindow
|
||||
bindm = $mod, mouse:273, resizewindow
|
||||
|
||||
# Volume
|
||||
bind = , XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bind = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bind = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
|
||||
# Brightness
|
||||
bind = , XF86MonBrightnessUp, exec, brightnessctl set 5%+
|
||||
bind = , XF86MonBrightnessDown, exec, brightnessctl set 5%-
|
||||
|
||||
# Screenshot
|
||||
bind = , Print, exec, grimblast copy area
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin root - $TERM
|
||||
4
iso/airootfs/root/.bash_profile
Normal file
4
iso/airootfs/root/.bash_profile
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Auto-start Hyprland on tty1 in the live session
|
||||
if [[ "$(tty)" == "/dev/tty1" ]] && [[ -z "$WAYLAND_DISPLAY" ]]; then
|
||||
exec Hyprland
|
||||
fi
|
||||
28
iso/airootfs/root/.config/hypr/hyprland.conf
Normal file
28
iso/airootfs/root/.config/hypr/hyprland.conf
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Live-session Hyprland config — launches Calamares on start.
|
||||
# This is NOT the installed system config; that lives in dotfiles/hypr/.
|
||||
|
||||
monitor=,preferred,auto,1
|
||||
|
||||
exec-once = calamares
|
||||
|
||||
general {
|
||||
border_size = 2
|
||||
col.active_border = rgba(88c0d0ff)
|
||||
col.inactive_border = rgba(4c566aff)
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = 4
|
||||
}
|
||||
|
||||
input {
|
||||
kb_layout = us
|
||||
follow_mouse = 1
|
||||
}
|
||||
|
||||
misc {
|
||||
disable_hyprland_logo = true
|
||||
disable_splash_rendering = true
|
||||
# Keep compositor running if calamares exits (user can relaunch)
|
||||
exit_window_request_force = false
|
||||
}
|
||||
|
|
@ -47,10 +47,9 @@ gtk4-layer-shell
|
|||
librsvg
|
||||
libpulse
|
||||
|
||||
# Display
|
||||
# Display (wlroots is bundled with Hyprland; don't list separately)
|
||||
wayland
|
||||
wayland-protocols
|
||||
wlroots
|
||||
|
||||
# Fonts
|
||||
noto-fonts
|
||||
|
|
@ -63,10 +62,13 @@ foot
|
|||
# File manager
|
||||
nautilus
|
||||
|
||||
# Installer
|
||||
# Installer — sourced from [breadway] repo (see pacman.conf)
|
||||
calamares
|
||||
calamares-qt6
|
||||
|
||||
# Bread ecosystem — sourced from [breadway] repo
|
||||
bakery
|
||||
|
||||
# Utilities
|
||||
sudo
|
||||
git
|
||||
|
|
|
|||
38
iso/pacman.conf
Normal file
38
iso/pacman.conf
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#
|
||||
# BOS pacman.conf — used during ISO build and installed to the target system.
|
||||
# Based on the standard Arch Linux pacman.conf.
|
||||
#
|
||||
|
||||
[options]
|
||||
HoldPkg = pacman glibc
|
||||
Architecture = auto
|
||||
CheckSpace
|
||||
ParallelDownloads = 5
|
||||
|
||||
Color
|
||||
VerbosePkgLists
|
||||
ILoveCandy
|
||||
|
||||
SigLevel = Required DatabaseOptional
|
||||
LocalFileSigLevel = Optional
|
||||
|
||||
[core]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[extra]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[multilib]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Breadway custom repo — provides: bakery, calamares (pre-built), and the
|
||||
# bread ecosystem packages (bread, breadbar, breadbox, breadcrumbs, breadpad,
|
||||
# bos-settings).
|
||||
#
|
||||
# TODO: Replace this URL with the actual hosted repo before building.
|
||||
# See: https://github.com/Breadway/repo for setup instructions.
|
||||
# -----------------------------------------------------------------------
|
||||
[breadway]
|
||||
SigLevel = Optional TrustAll
|
||||
Server = https://repo.breadway.dev/$arch
|
||||
Loading…
Add table
Add a link
Reference in a new issue