bos-settings moves to git.breadway.dev/Breadway/bos-settings (full history preserved via git-filter-repo) so its release cadence is decoupled from BOS's own. breadhelp takes its place as this repo's workspace member: a GTK4 onboarding/help center replacing the old bos-welcome/bos-keybinds bash scripts with searchable guides, an interactive keybind viewer (sourced from the new keybinds.toml, not parsed out of hyprland.lua or hardcoded), a troubleshooting wizard with one-click fixes, and a proper first-run tour. bos-netcheck extracts bos-welcome's network-check half, which still needs to run every login independent of breadhelp's own first-run gating. hyprland.lua's keybinds/settings/monitors/autostart are now JSON-driven (binds.json/settings.json/monitors.json/autostart.json) with every loader pcall-wrapped and falling back to hardcoded defaults per field on bad or missing config, so bread* apps (bos-settings' new editors, and breadhelp's keybind viewer) can read/write this config without ever being able to leave the compositor unable to start. CI's package.yml now builds breadhelp instead of bos-settings on tag push; bos-settings needs its own equivalent workflow in its new repo (not yet set up).
170 lines
9.7 KiB
Lua
170 lines
9.7 KiB
Lua
-- BOS Hyprland configuration — native Lua config (Hyprland 0.55+).
|
|
-- hyprlang (.conf) is deprecated; this uses the built-in `hl` API.
|
|
-- Mostly single-file by design (reference: https://wiki.hypr.land/) — the
|
|
-- exceptions are keybinds, appearance settings, monitor layout, and the
|
|
-- extra autostart list, each loaded from a JSON file (binds.json,
|
|
-- settings.json, monitors.json, autostart.json) so bread* apps can read/edit
|
|
-- them as structured data instead of parsing this Lua file.
|
|
--
|
|
-- Every loader below is wrapped in `pcall`: this file is loaded as a single
|
|
-- Lua chunk, so an uncaught error partway through would abort everything
|
|
-- *after* it too (no keybinds, no window rules, no autostart) — a bad or
|
|
-- hand-edited JSON file must degrade to that one section's hardcoded
|
|
-- defaults, never take down the rest of the session.
|
|
local script_dir = os.getenv("HOME") .. "/.config/hypr/scripts/"
|
|
local config_home = os.getenv("HOME") .. "/.config/hypr/"
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Monitors — from monitors.json, always falls back to a generic
|
|
-- any-hardware default (see scripts/display/monitors.lua).
|
|
-- ---------------------------------------------------------------------------
|
|
pcall(dofile, script_dir .. "display/monitors.lua")
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Core appearance/input settings — from settings.json (see
|
|
-- scripts/ui/settings.lua).
|
|
-- ---------------------------------------------------------------------------
|
|
pcall(dofile, script_dir .. "ui/settings.lua")
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Animations — snappy curves + per-leaf speeds (matches the reference laptop;
|
|
-- the hl.config default above is much slower).
|
|
-- ---------------------------------------------------------------------------
|
|
local curves = {
|
|
easeOutQuint = { type = "bezier", points = { { 0.23, 1 }, { 0.32, 1 } } },
|
|
easeInOutCubic = { type = "bezier", points = { { 0.65, 0.05 }, { 0.36, 1 } } },
|
|
almostLinear = { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1 } } },
|
|
quick = { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1 } } },
|
|
}
|
|
for name, curve in pairs(curves) do
|
|
hl.curve(name, curve)
|
|
end
|
|
|
|
local animations = {
|
|
{ leaf = "global", enabled = true, speed = 10, bezier = "default" },
|
|
{ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" },
|
|
{ leaf = "windows", enabled = true, speed = 4.79, bezier = "easeOutQuint" },
|
|
{ leaf = "windowsIn", enabled = true, speed = 4.1, bezier = "easeOutQuint", style = "popin 87%" },
|
|
{ leaf = "windowsOut", enabled = true, speed = 1.49, bezier = "linear", style = "popin 87%" },
|
|
{ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" },
|
|
{ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" },
|
|
{ leaf = "workspaces", enabled = true, speed = 1.94, bezier = "almostLinear", style = "fade" },
|
|
}
|
|
for _, animation in ipairs(animations) do
|
|
hl.animation(animation)
|
|
end
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Window rules — float + centre the onboarding/help popups.
|
|
-- breadhelp replaces the old bos-welcome/bos-keybinds kitty+less popups.
|
|
-- bos-netsetup (nmtui, from bos-netcheck) is unrelated to breadhelp and
|
|
-- still floats the same way.
|
|
-- ---------------------------------------------------------------------------
|
|
hl.window_rule({ name = "breadhelp", match = { class = "^(com\\.breadway\\.breadhelp)$" }, float = true, size = { 880, 600 } })
|
|
hl.window_rule({ name = "bos-netsetup", match = { class = "^(bos-netsetup)$" }, float = true, size = { 700, 560 } })
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Environment (vendor-neutral; no GPU-specific vars so it works on Intel/AMD).
|
|
-- ---------------------------------------------------------------------------
|
|
hl.env("XCURSOR_SIZE", "24")
|
|
hl.env("HYPRCURSOR_SIZE", "24")
|
|
hl.env("XCURSOR_THEME", "Bibata-Modern-Ice")
|
|
hl.env("MOZ_ENABLE_WAYLAND", "1")
|
|
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
|
|
hl.env("QT_QPA_PLATFORMTHEME", "qt5ct")
|
|
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
|
|
hl.env("SDL_VIDEODRIVER", "wayland")
|
|
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "auto")
|
|
hl.env("_JAVA_AWT_WM_NONREPARENTING", "1")
|
|
|
|
-- kitty sets its own background_opacity (see kitty.conf), so the global blur
|
|
-- above blurs behind the terminal while keeping text fully opaque.
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Standard BOS keybinds — data-driven from binds.json (apps, windows,
|
|
-- screenshots, focus/move/resize, workspaces, mouse, media keys), loaded via
|
|
-- scripts/input/{binds,keybinds}.lua. breadhelp's keybind viewer reads
|
|
-- binds.json directly as its source of truth (no separately-maintained
|
|
-- cheatsheet to keep in sync), and a future bos-settings editor can
|
|
-- read/write the same file.
|
|
pcall(function()
|
|
local binds = dofile(script_dir .. "input/binds.lua")(config_home .. "binds.json")
|
|
dofile(script_dir .. "input/keybinds.lua")({
|
|
default_mods = binds.default_mods,
|
|
bindings = binds.bindings,
|
|
})
|
|
end)
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Autostart. Core bootstrap sequence (polkit agent, dark theme, wallpaper
|
|
-- daemon, breadd's Wayland-env fix, breadclipd) stays hardcoded here — it's
|
|
-- timing/order-sensitive infrastructure, not something a settings UI should
|
|
-- expose for a user to disable or reorder. The extra, genuinely toggleable
|
|
-- apps (breadbar, hypridle, bos-netcheck, breadhelp) come from
|
|
-- autostart.json via scripts/system/autostart.lua, appended after.
|
|
-- (bos-live-setup appends the live-installer launch below this on the ISO.)
|
|
-- ---------------------------------------------------------------------------
|
|
hl.on("hyprland.start", function()
|
|
local core_startup = {
|
|
-- Generate the shared bread GUI stylesheet first, so breadbar/breadbox/
|
|
-- bos-settings load it on start (they also live-reload if it changes).
|
|
"bread-theme generate",
|
|
-- Global dark theme: GTK4/libadwaita + GTK3 theme + icon + cursor.
|
|
"gsettings set org.gnome.desktop.interface color-scheme prefer-dark",
|
|
"gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark",
|
|
"gsettings set org.gnome.desktop.interface icon-theme Papirus-Dark",
|
|
"gsettings set org.gnome.desktop.interface cursor-theme Bibata-Modern-Ice",
|
|
"gsettings set org.gnome.desktop.interface cursor-size 24",
|
|
-- Clipboard history is breadclipd, a bakery-managed systemd --user
|
|
-- service (auto-started via skel — see build-local.sh's service bake)
|
|
-- rather than an exec-once here.
|
|
"/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1",
|
|
"awww-daemon",
|
|
-- Set the default wallpaper once the daemon is up (retry until ready).
|
|
-- Raw `awww img`, NOT `breadpaper set` — breadpaper set also runs real
|
|
-- pywal against the image, which would clobber the curated black-base
|
|
-- colors.json baked into skel (.cache/wal/colors.json: #0c0c0c bg,
|
|
-- bread-toned browns reserved for accent slots only) with colors
|
|
-- actually extracted from bread-background.png — which is an all-beige
|
|
-- photo, so every bread-theme app (breadbar included) turns brown.
|
|
-- `breadpaper get` still works on a fresh install without ever running
|
|
-- pywal: .cache/wal/wal (pywal's own "last image" marker, which is all
|
|
-- breadpaper reads) is baked into skel too, right beside colors.json.
|
|
-- pywal only runs for real once the user picks a wallpaper themselves.
|
|
[[bash -c 'until awww img /usr/share/backgrounds/bos/bread-background.png 2>/dev/null; do sleep 0.3; done']],
|
|
-- breadd runs as a systemd user service (~/.config/systemd/user/breadd.service,
|
|
-- enabled in skel). It autostarts at login but before Hyprland exists, so
|
|
-- push the compositor's Wayland env into the user manager and restart breadd
|
|
-- to pick it up — that's how it gets HYPRLAND_INSTANCE_SIGNATURE to talk to Hyprland.
|
|
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE",
|
|
"systemctl --user restart breadd",
|
|
-- graphical-session.target ships with RefuseManualStart=yes (systemd
|
|
-- convention — only a session manager like uwsm is meant to activate
|
|
-- it), confirmed on real hardware: `systemctl --user start
|
|
-- graphical-session.target` fails outright ("Operation refused").
|
|
-- BOS doesn't use uwsm, and nothing else activates that target, so
|
|
-- breadclipd (WantedBy=graphical-session.target) never started.
|
|
-- Start it directly instead. If more graphical-session.target
|
|
-- services show up later, add them here too.
|
|
"systemctl --user start breadclipd.service",
|
|
}
|
|
for _, cmd in ipairs(core_startup) do
|
|
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
|
end
|
|
|
|
-- breadbox-sync is a Type=oneshot systemd --user service
|
|
-- (WantedBy=default.target, no Hyprland IPC dependency) — it already
|
|
-- runs on login via the unit baked into skel, independent of this list.
|
|
local ok, extra = pcall(function()
|
|
return dofile(script_dir .. "system/autostart.lua")()
|
|
end)
|
|
if not ok or type(extra) ~= "table" then
|
|
-- autostart.json/its loader broke — fall back to the same apps BOS
|
|
-- has always started, so a bad JSON edit degrades to "normal
|
|
-- desktop" rather than "no bar, no idle lock, no onboarding".
|
|
extra = { "breadbar", "hypridle", "bos-netcheck", "breadhelp --autostart" }
|
|
end
|
|
for _, cmd in ipairs(extra) do
|
|
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
|
end
|
|
end)
|