feat(menu): Recovery scopes (#111), System IA (#105), drop Control Center (#110)
Some checks failed
Check / eval (push) Has been cancelled
Some checks failed
Check / eval (push) Has been cancelled
System is Connectivity / Devices / Recovery / Preferences under the same six-entry root. Recovery lists desktop (HM), system boot, and BTRFS files once each with cost labels. Control Center is gone: blur/gaps live in Look & Feel; update checks and Bluetooth/Printing package toggles in Preferences (with rebuilds). docs/RECOVERY paths updated.
This commit is contained in:
@@ -75,7 +75,6 @@ Flat on purpose. Two module trees, one options file each, no hidden layers.
|
||||
│ ├── nomarchy-state-sync/ # state writer + rebuild dispatcher (Python)
|
||||
│ ├── nomarchy-install/ # live-ISO installer (gum + disko + mkFlake)
|
||||
│ ├── nomarchy-doctor/ # read-only health sheet, one command per failure
|
||||
│ ├── nomarchy-control-center/ # TUI settings front-end over nomarchy-state-sync (gum)
|
||||
│ └── nomarchy-battery-notify/ # low-battery toast watcher backing battery-notify.nix
|
||||
├── templates/downstream/ # machine flake SoT (`flake init` + installer copy/patch)
|
||||
├── docs/ # human docs — map: docs/README.md
|
||||
|
||||
@@ -169,44 +169,6 @@ a suspended machine hibernates after the configured delay and resumes, and a
|
||||
machine without hibernate support hides the row instead of offering a
|
||||
suspend that never wakes.
|
||||
|
||||
### 105. `[big]` System-menu information architecture
|
||||
|
||||
Keep exactly six root menu entries while reorganizing System into
|
||||
Connectivity, Devices, Recovery, and Preferences. This item must be split into
|
||||
scoped implementation/verification tasks before work starts. Pass = every
|
||||
current route has one deliberate home, navigation remains shallow, and no
|
||||
root-level entry is added or lost.
|
||||
|
||||
### 110. `[big]` Retire Control Center safely
|
||||
|
||||
Split this into two phases before implementation: first build a migration/drop
|
||||
matrix for every unique setting, then remove the package and all references.
|
||||
Keyboard and terminal replacements must reject unsafe free-text values. Pass =
|
||||
no supported setting silently disappears and the second phase leaves no stale
|
||||
launcher, menu, package, documentation, or generated-artifact reference.
|
||||
|
||||
**Facts for the matrix, from #116 (2026-07-14):** its Bluetooth and Printing
|
||||
rows write `settings.{bluetooth,printing}.enable`, and those keys became live
|
||||
bridges to the NixOS config in a9f3a64 — until then they wrote JSON nothing
|
||||
read, so *these two toggles have never actually worked for any user*. That
|
||||
cuts both ways: "preserve existing behavior" is not a reason to keep them
|
||||
(there is no behavior to preserve), but the state keys and their bridges are
|
||||
real now and outlive the TUI — dropping the rows must not drop the keys, or a
|
||||
machine whose state.json already says `bluetooth.enable = false` will
|
||||
silently flip back on at the next rebuild. `checks.state-bridges` covers those
|
||||
two keys and will fail loudly if the bridges go with the tool; keep it green,
|
||||
and if a key is deliberately retired, remove its case in the same commit.
|
||||
Whatever inherits the rows should rebuild on toggle rather than print
|
||||
"requires rebuild" (#117). Updates (`settings.updates.enable`) is HM-side,
|
||||
where `nomarchy.settings` genuinely exists, and needs none of this.
|
||||
|
||||
### 111. Scope-first Recovery menu
|
||||
|
||||
Replace confusing Rollback/Snapshots duplication with explicit Desktop
|
||||
generation, System boot generation, and Files/root BTRFS scopes. Pass = labels
|
||||
state what is restored and from where before action, with destructive or reboot
|
||||
effects made clear and each existing recovery path represented once.
|
||||
|
||||
## LATER
|
||||
|
||||
- **Wallpapers artifact split** (ROADMAP § Faster switches — decided,
|
||||
@@ -219,8 +181,7 @@ effects made clear and each existing recovery path represented once.
|
||||
- **MIPI/IPU software-ISP camera** support (no-UVC machines).
|
||||
- **NixOS release bump → v2** `[human]`: deliberate, hand-edited, never
|
||||
automated; the previous attempt was discarded (2026-06-22) over a
|
||||
Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should
|
||||
also soften that blocker class).
|
||||
Hyprland OOM blocker — see MEMORY.md before retrying.
|
||||
|
||||
## FUTURE (decided deferred — not the agent queue head)
|
||||
|
||||
@@ -255,25 +216,6 @@ high-ROI, etc.) live in the journal + ROADMAP — not here.*
|
||||
|
||||
### Product / day-2
|
||||
|
||||
### 117. Control Center says "requires rebuild" and leaves the user to do it
|
||||
|
||||
**Filed as an input to #110 (Retire Control Center safely), not as standalone
|
||||
work** — Bernardo 2026-07-14: the Control Center is going away, so fixing its
|
||||
toggles would be building on a condemned surface. Recorded because the
|
||||
observation outlives the tool: it is a fact the #110 migration matrix needs,
|
||||
and whatever menu inherits these settings must not repeat it.
|
||||
|
||||
Noticed while fixing #116 (2026-07-14). `nomarchy-control-center.sh`'s
|
||||
Bluetooth, Printing and Updates toggles set the state and print "… (requires
|
||||
rebuild)", so the setting only lands whenever the user next thinks to run
|
||||
`nomarchy-rebuild`. Every menu toggle written since does the rebuild itself
|
||||
and toasts the outcome (`nomarchy-autologin`, `nomarchy-fingerprint`,
|
||||
`nomarchy-autotimezone`) — the state-write-then-rebuild shape. A user who
|
||||
toggles Bluetooth off and sees Bluetooth still running cannot tell "needs a
|
||||
rebuild" from "the toggle is broken again", which is exactly the symptom #116
|
||||
removed. Migrating these rows into the rofi menu resolves it for free, since
|
||||
that shape is the convention there.
|
||||
|
||||
### 114. Greeter ignores per-device keyboard layouts
|
||||
|
||||
Found by Bernardo 2026-07-14: logging out while docked lands on tuigreet,
|
||||
@@ -321,7 +263,6 @@ See **VISION**. Open PROPOSED: post-install hardware hints; NVIDIA
|
||||
deferred past v1; IR portal (b)/(c) need T14s (HARDWARE-QUEUE § T14s).
|
||||
Standing calls: browser = Chromium; power = PPD.
|
||||
|
||||
|
||||
## Decisions `[human]`
|
||||
|
||||
Open calls only Bernardo can make; agents add options/evidence but never
|
||||
|
||||
@@ -19,6 +19,18 @@ Template:
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-15 — #111 Recovery + #105 System IA + #110 retire Control Center
|
||||
- **Task:** Scope-first Recovery, System submenu IA, retire Control Center.
|
||||
- **Did:** System → Connectivity / Devices / Recovery / Preferences. Recovery:
|
||||
Desktop gen (HM list+activate), System boot (toast + RECOVERY.md), Files
|
||||
BTRFS, What changed. Migrated CC: blur/gaps presets in Look & Feel; update
|
||||
checks + Bluetooth/Printing package toggles in Preferences (rebuild in
|
||||
terminal). Removed `pkgs/nomarchy-control-center` + menu entry. Docs
|
||||
RECOVERY/HARDWARE/VISION updated. Closed #111 #105 #110 #117.
|
||||
- **Verified:** V0 menu-back; HM gen builds; flake check --no-build.
|
||||
- **Pending:** V3 eyeball the new menu tree on a real session.
|
||||
- **Next suggestion:** #115/#120 human decisions, or hardware queue.
|
||||
|
||||
## 2026-07-15 — V2 permanent checks for #104 / #122
|
||||
- **Task:** V2 everything VM-checkable from the #104/#122 batch.
|
||||
- **Did:** Extracted `pkgs/nomarchy-airplane` (overlay). Added
|
||||
|
||||
@@ -136,10 +136,9 @@ confirm → `fwupdmgr update`. It never auto-flashes — `fwupdmgr update`
|
||||
confirms each device and prompts for the reboot a capsule needs; pillar 1
|
||||
(rock-stable) forbids silent BIOS writes.
|
||||
|
||||
**Hints (#43 / #73):** MOTD cheat-sheet line + `nomarchy-control-center
|
||||
--first-boot` tip when `fwupdmgr` is on PATH. Fingerprint / doctor tips
|
||||
follow the same pattern (fingerprint MOTD only when
|
||||
`nomarchy.hardware.fingerprint.enable`).
|
||||
**Hints (#43 / #73):** MOTD cheat-sheet line when `fwupdmgr` is on PATH.
|
||||
Fingerprint / doctor tips follow the same pattern (fingerprint MOTD only
|
||||
when `nomarchy.hardware.fingerprint.enable`).
|
||||
|
||||
**Still queued:** a Doctor “updates available” check, and
|
||||
Waybar/updates-panel integration.
|
||||
|
||||
@@ -21,8 +21,10 @@ home-manager generations # newest first, one per theme/HM change
|
||||
/nix/store/…-home-manager-generation/activate # run the one you want
|
||||
```
|
||||
|
||||
The same picker lives in the menu: **System › Rollback** lists the
|
||||
recent desktop generations — pick one and it activates.
|
||||
The same picker lives in the menu: **System › Recovery › Desktop
|
||||
generation** lists the recent Home Manager generations — pick one and
|
||||
it activates. System-level undo is **System › Recovery › System boot
|
||||
generation** (boot menu) or **Files (BTRFS)** (snapper).
|
||||
|
||||
Or simply apply a theme you know is good: `nomarchy-state-sync apply
|
||||
boreal` (or any preset). If a switch failed halfway, the state file is written
|
||||
@@ -69,8 +71,8 @@ With `nomarchy.system.snapper.enable` (the installer's default on
|
||||
BTRFS), the root filesystem has hourly/daily history, and
|
||||
`nixos-rebuild-snap` leaves a snapshot right before a rebuild:
|
||||
|
||||
- **GUI:** menu › System › Snapshots (btrfs-assistant; expects a polkit
|
||||
password prompt).
|
||||
- **GUI:** menu › System › Recovery › Files (BTRFS) (btrfs-assistant;
|
||||
expects a polkit password prompt).
|
||||
- **Terminal/SSH:** `sudo nomarchy-snapshots` — browse a snapshot's
|
||||
diff, **restore changed files** (snapper `undochange`), or **roll the
|
||||
whole root back** to a snapshot and reboot. Both destructive actions
|
||||
|
||||
@@ -427,6 +427,13 @@ Design/decision records and a running log of shipped work (items marked
|
||||
default `$TERMINAL` / SUPER+Return, doctor + calendar + what-changed use
|
||||
`kitty --class=com.nomarchy.*`. Ghostty module and install-time GL probe
|
||||
removed. V3: Acer SUPER+Return + doctor float.
|
||||
- ✓ **Recovery + System IA + Control Center retired (#111 / #105 / #110):**
|
||||
System menu is Connectivity / Devices / Recovery / Preferences (root still
|
||||
six entries). Recovery is scope-first: Desktop generation (HM), System boot
|
||||
generation (how), Files BTRFS, What changed. Control Center package removed;
|
||||
blur/gaps (presets) in Look & Feel; update checks + Bluetooth/Printing
|
||||
package toggles in Preferences (system toggles run `nomarchy-rebuild`).
|
||||
#117 absorbed (rebuild no longer left to the user for those rows).
|
||||
- ✓ **Airplane mode (#104):** System › Airplane mode + SUPER+CTRL+R +
|
||||
Waybar plane glyph (self-hides when off). Runtime `nomarchy-airplane`
|
||||
softs Wi-Fi (nmcli) + Bluetooth (rfkill/bluetoothctl), remembers prior
|
||||
|
||||
@@ -74,7 +74,7 @@ Reference: [HARDWARE.md](HARDWARE.md) §4–§5, §11 (doctor).
|
||||
| **Silent first-week card** ✓ | One dismissible “you’re set” (menu, themes, keys, network) — not a wizard | ✓ shipped #81 — `settings.firstBootShown` + notify; live ISO keeps its own toast |
|
||||
| **Boreal as default** ✓ | Identity on first boot | ✓ seed `state.json` + install path use Boreal (2026-07-09) |
|
||||
| **Generation readability** ✓ | “What changed last rebuild” in plain language | ✓ shipped #82 — nvd toast + System › What changed? |
|
||||
| **Post-install hints** | One-shot MOTD/notify for fwupd / fprintd when relevant | Partial: MOTD + control-center tips; still no self-gated *first-session* toast when hardware is present (see BACKLOG PROPOSED) |
|
||||
| **Post-install hints** | One-shot MOTD/notify for fwupd / fprintd when relevant | Partial: MOTD tips; first-session toast is #81; still refine self-gated hardware hints if needed |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
themesDir = ./themes;
|
||||
};
|
||||
nomarchy-doctor = final.callPackage ./pkgs/nomarchy-doctor { };
|
||||
nomarchy-control-center = final.callPackage ./pkgs/nomarchy-control-center { };
|
||||
nomarchy-battery-notify = final.callPackage ./pkgs/nomarchy-battery-notify { };
|
||||
nomarchy-first-boot = final.callPackage ./pkgs/nomarchy-first-boot { };
|
||||
nomarchy-what-changed = final.callPackage ./pkgs/nomarchy-what-changed { };
|
||||
@@ -136,7 +135,6 @@
|
||||
# (maintainer/CI convenience — modules install them via the overlay).
|
||||
nomarchy-doctor = pkgs.nomarchy-doctor;
|
||||
nomarchy-lifecycle = pkgs.nomarchy-lifecycle;
|
||||
nomarchy-control-center = pkgs.nomarchy-control-center;
|
||||
nomarchy-battery-notify = pkgs.nomarchy-battery-notify;
|
||||
nomarchy-first-boot = pkgs.nomarchy-first-boot;
|
||||
nomarchy-what-changed = pkgs.nomarchy-what-changed;
|
||||
|
||||
@@ -341,7 +341,7 @@ let
|
||||
done
|
||||
back
|
||||
} | rofi_menu -show-icons -p "profile (now: $cur)") || exit 0
|
||||
[ "$choice" = "$BACK" ] && exec "$0" system
|
||||
[ "$choice" = "$BACK" ] && exec "$0" system-preferences
|
||||
[ -n "$choice" ] && powerprofilesctl set "$choice" ;;
|
||||
|
||||
powermgmt)
|
||||
@@ -548,7 +548,7 @@ ${themeRows}
|
||||
back
|
||||
} | rofi_menu -show-icons -p Audio) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
"$BACK") exec "$0" system-devices ;;
|
||||
"Send output"*)
|
||||
nomarchy-dock-audio select menu ;;
|
||||
*Output*) exec rofi-pulse-select sink ;;
|
||||
@@ -567,7 +567,7 @@ ${themeRows}
|
||||
done
|
||||
back
|
||||
} | rofi_menu -p "Keyboard") || exit 0
|
||||
[ "$picked" = "$BACK" ] && exec "$0" system
|
||||
[ "$picked" = "$BACK" ] && exec "$0" system-devices
|
||||
device=''${picked%% ·*}
|
||||
saved=$(nomarchy-keyboard-layout saved "$device")
|
||||
layout=$( {
|
||||
@@ -627,7 +627,7 @@ ${themeRows}
|
||||
printf '%s' "$mons" | jq -r '.[] | "\(.name) · \(.width)x\(.height)@\(.refreshRate|round)Hz"'
|
||||
printf '%s\n' "$BACK"
|
||||
} | rofi_menu -p Display ) || exit 0
|
||||
[ "$name" = "$BACK" ] && exec "$0" system
|
||||
[ "$name" = "$BACK" ] && exec "$0" system-devices
|
||||
[ "$name" = "Profiles ›" ] && exec "$0" display-profile
|
||||
case "$name" in
|
||||
"Dock mode"*)
|
||||
@@ -754,16 +754,13 @@ ${themeRows}
|
||||
esac ;;
|
||||
|
||||
lookfeel)
|
||||
# Look & Feel — appearance: Theme, wallpapers, night light.
|
||||
# Root stays six entries (Apps / Look & Feel / Tools / System /
|
||||
# Power / Keybindings). SUPER+T / SUPER+SHIFT+T still hit leaves.
|
||||
# Look & Feel — appearance: Theme, wallpapers, night light, blur/gaps
|
||||
# (#110 moved blur/gaps out of Control Center — presets only, no
|
||||
# free-text). Root stays six entries.
|
||||
choice=$( {
|
||||
row "Theme${menuHint "theme"}" preferences-desktop-theme
|
||||
row "Next wallpaper${hintForAction "exec, nomarchy-state-sync bg next"}" preferences-desktop-wallpaper
|
||||
row "Reset wallpaper (auto)" preferences-desktop-wallpaper
|
||||
# Use the toggle script (knows hyprsunset vs wlsunset); a hard-coded
|
||||
# hyprsunset-only check always showed (off) in geo mode and when
|
||||
# the unit was still the empty HM mask from a disabled package unit.
|
||||
if [ "$(nomarchy-nightlight is-active 2>/dev/null)" = on ]
|
||||
then row "Night light (on)" weather-clear-night
|
||||
else row "Night light (off)" weather-clear-night
|
||||
@@ -772,6 +769,12 @@ ${themeRows}
|
||||
then row "Auto theme (on)" preferences-desktop-theme
|
||||
else row "Auto theme (off)" preferences-desktop-theme
|
||||
fi
|
||||
case "$(nomarchy-state-sync get ui.blur 2>/dev/null)" in
|
||||
true|True) row "Blur (on)" preferences-desktop-effects ;;
|
||||
*) row "Blur (off)" preferences-desktop-effects ;;
|
||||
esac
|
||||
gaps=$(nomarchy-state-sync get ui.gapsOut 2>/dev/null || echo 12)
|
||||
row "Gaps (now $gaps px)" preferences-desktop-display
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p "Look & Feel") || exit 0
|
||||
case "$choice" in
|
||||
@@ -781,8 +784,43 @@ ${themeRows}
|
||||
*"Next wallpaper"*) exec nomarchy-state-sync bg next ;;
|
||||
*"Reset wallpaper"*) exec nomarchy-state-sync bg auto ;;
|
||||
*"Night light"*) exec "$0" nightlight ;;
|
||||
*Blur*) exec "$0" blur ;;
|
||||
*Gaps*) exec "$0" gaps ;;
|
||||
esac ;;
|
||||
|
||||
blur)
|
||||
# ui.blur → Hyprland decoration; needs a home switch to bake.
|
||||
case "$(nomarchy-state-sync get ui.blur 2>/dev/null)" in
|
||||
true|True)
|
||||
nomarchy-state-sync --quiet set ui.blur false
|
||||
notify-send "Blur" "Off — desktop rebuilt." ;;
|
||||
*)
|
||||
nomarchy-state-sync --quiet set ui.blur true
|
||||
notify-send "Blur" "On — desktop rebuilt." ;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
|
||||
gaps)
|
||||
# Preset-only (no free-text) — #110 keyboard/gaps free-text was unsafe.
|
||||
cur=$(nomarchy-state-sync get ui.gapsOut 2>/dev/null || echo 12)
|
||||
choice=$( {
|
||||
for g in 0 4 8 12 16 24; do
|
||||
if [ "$g" = "$cur" ]; then row "$g px (current)" preferences-desktop-display
|
||||
else row "$g px" preferences-desktop-display
|
||||
fi
|
||||
done
|
||||
back
|
||||
} | rofi_menu -show-icons -p "Outer gaps (now $cur px)") || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" lookfeel ;;
|
||||
*)
|
||||
g=''${choice%% *}
|
||||
case "$g" in *[!0-9]*) exit 0 ;; esac
|
||||
nomarchy-state-sync --quiet set ui.gapsOut "$g"
|
||||
notify-send "Gaps" "Outer gaps $g px — desktop rebuilt." ;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
|
||||
display-profile)
|
||||
# Named multi-output layouts (nomarchy.displayProfiles). Applying is
|
||||
# instant (hyprctl per entry, via nomarchy-display-profile) and
|
||||
@@ -1039,7 +1077,7 @@ ${themeRows}
|
||||
back
|
||||
} | rofi_menu -show-icons -p Fingerprint) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
"$BACK") exec "$0" system-devices ;;
|
||||
*Enroll*)
|
||||
exec ${cfg.terminal} -e sh -c '
|
||||
echo "== Enroll fingerprint for $USER =="
|
||||
@@ -1076,10 +1114,6 @@ ${themeRows}
|
||||
exec ${cfg.terminal} -e nomarchy-fingerprint toggle ;;
|
||||
esac ;;
|
||||
|
||||
controlcenter)
|
||||
# Nomarchy TUI Control Center.
|
||||
exec ${cfg.terminal} -e nomarchy-control-center ;;
|
||||
|
||||
whatchanged)
|
||||
# Plain-language last rebuild (system + desktop nvd). Toast the
|
||||
# one-liners; open a floating terminal for the full report when
|
||||
@@ -1094,46 +1128,66 @@ ${themeRows}
|
||||
-e sh -c "nomarchy-what-changed
|
||||
printf '\nEnter to close.'; read -r _" ;;
|
||||
|
||||
rollback)
|
||||
# Undo, one menu away (informative + rock-stable). Desktop =
|
||||
# Home Manager generations: theme/config history is already one
|
||||
# generation per change, and running an older generation's
|
||||
# activate script is the supported HM rollback — reversible by
|
||||
# activating a newer one again, so no typed-yes gate here.
|
||||
# System-level undo deliberately LINKS OUT instead of putting
|
||||
# destructive flows in rofi: boot-menu generations and snapper
|
||||
# rollback have their own homes and gates (docs/RECOVERY.md,
|
||||
# nomarchy-snapshots).
|
||||
# #111 Scope-first Recovery — one menu for every undo path.
|
||||
# Desktop = Home Manager generations (themes/home config).
|
||||
# System boot = NixOS generations in the firmware boot menu.
|
||||
# Files = BTRFS snapper (files on disk / whole-root roll).
|
||||
# Each path is listed once; labels say what is restored and the cost
|
||||
# (instant / reboot / confirm) before the action.
|
||||
recovery)
|
||||
choice=$( {
|
||||
row "Desktop generation — themes & home config (instant, reversible)" document-open-recent
|
||||
row "System boot generation — older NixOS (reboot, then pick in boot menu)" system-reboot
|
||||
command -v nomarchy-snapshots >/dev/null 2>&1 \
|
||||
&& row "Files (BTRFS) — restore files or roll root (password + confirm)" timeshift
|
||||
command -v nomarchy-what-changed >/dev/null 2>&1 \
|
||||
&& row "What changed? — last system & desktop rebuild" view-refresh
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p Recovery) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
*Desktop*) exec "$0" recovery-desktop ;;
|
||||
*System\ boot*)
|
||||
notify-send "System boot generation" \
|
||||
"Reboot and pick an older NixOS generation in the boot menu (last 10 kept). That boot is temporary — make it stick: revert in ~/.nomarchy, then nomarchy-rebuild. Details: docs/RECOVERY.md §3." ;;
|
||||
*Files*) exec "$0" snapshot ;;
|
||||
*"What changed"*) exec "$0" whatchanged ;;
|
||||
esac ;;
|
||||
|
||||
recovery-desktop)
|
||||
# Home Manager generations only — desktop half of RECOVERY.md §1.
|
||||
gens=$(home-manager generations 2>/dev/null | head -10)
|
||||
choice=$( {
|
||||
if [ -n "$gens" ]; then
|
||||
printf '%s\n' "$gens" | awk '{
|
||||
printf "Desktop gen %s — %s %s%s\n", $5, $1, $2, (NR==1 ? " (current)" : "")
|
||||
printf "Gen %s — %s %s%s\n", $5, $1, $2, (NR==1 ? " (current)" : "")
|
||||
}' | while IFS= read -r line; do row "$line" document-open-recent; done
|
||||
else
|
||||
row "(no Home Manager generations found)" dialog-information
|
||||
fi
|
||||
command -v nomarchy-snapshots >/dev/null 2>&1 \
|
||||
&& row "System files → Snapshots" timeshift
|
||||
row "System config → boot an older generation (how)" help-about
|
||||
back
|
||||
} | rofi_menu -show-icons -p Rollback) || exit 0
|
||||
} | rofi_menu -show-icons -p "Desktop generation") || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
"Desktop gen "*)
|
||||
num=''${choice#Desktop gen }; num=''${num%% *}
|
||||
"$BACK"|"(no "*) exec "$0" recovery ;;
|
||||
"Gen "*)
|
||||
num=''${choice#Gen }; num=''${num%% *}
|
||||
path=$(printf '%s\n' "$gens" | awk -v n="$num" '$5 == n { print $7 }')
|
||||
[ -x "$path/activate" ] \
|
||||
|| { notify-send "Rollback" "Generation $num not found on disk."; exit 1; }
|
||||
|| { notify-send "Desktop generation" "Generation $num not found on disk."; exit 1; }
|
||||
exec ${cfg.terminal} -e sh -c "
|
||||
echo \"Activating Home Manager generation $num…\"; echo
|
||||
echo \"Activating Home Manager generation $num (desktop only)…\"
|
||||
echo \"This does not change the NixOS system or BTRFS files.\"
|
||||
echo
|
||||
\"$path/activate\"
|
||||
echo; echo \"Desktop rolled back to generation $num.\"
|
||||
echo \"(Roll forward the same way — newer generations stay listed.)\"
|
||||
echo
|
||||
echo \"Desktop is now generation $num.\"
|
||||
echo \"Roll forward the same way — newer generations stay listed.\"
|
||||
printf 'Enter to close.'; read -r _" ;;
|
||||
*Snapshots*) exec "$0" snapshot ;;
|
||||
*"older generation"*)
|
||||
notify-send "System rollback" "Reboot and pick an older NixOS generation in the boot menu (the last 10 are kept). Make it stick: revert the change in ~/.nomarchy, then nomarchy-rebuild. Details: docs/RECOVERY.md §3." ;;
|
||||
esac ;;
|
||||
|
||||
# Compat aliases — old menu ids and muscle memory.
|
||||
rollback) exec "$0" recovery ;;
|
||||
|
||||
tools)
|
||||
# Tools submenu — utilities you invoke. Each leaf is also reachable
|
||||
# directly (SUPER+CTRL+<mnemonic>); this just keeps the root short.
|
||||
@@ -1170,37 +1224,79 @@ ${themeRows}
|
||||
esac ;;
|
||||
|
||||
system)
|
||||
# System submenu — connectivity and machine state. Snapshots and the
|
||||
# power-profile picker self-gate (BTRFS+snapper / laptop on ppd), so
|
||||
# the submenu shrinks to match the hardware, like the Waybar modules.
|
||||
# #105 System IA — four groups under the same System entry so the
|
||||
# root menu stays at six items (Apps / Look & Feel / Tools / System /
|
||||
# Power / Keybindings). Leaves keep SUPER+CTRL mnemonics via their
|
||||
# own modules; this only organizes the picker.
|
||||
choice=$( {
|
||||
row "Connectivity" network-wireless
|
||||
row "Devices" preferences-desktop-peripherals
|
||||
row "Recovery${menuHint "recovery"}" edit-undo
|
||||
row "Preferences" preferences-system
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p System) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" ;;
|
||||
*Connectivity*) exec "$0" system-connectivity ;;
|
||||
*Devices*) exec "$0" system-devices ;;
|
||||
*Recovery*) exec "$0" recovery ;;
|
||||
*Preferences*) exec "$0" system-preferences ;;
|
||||
esac ;;
|
||||
|
||||
system-connectivity)
|
||||
choice=$( {
|
||||
row "Network${menuHint "network"}" network-wireless
|
||||
row "VPN" network-vpn
|
||||
# Airplane mode (#104): runtime Wi-Fi+BT kill-switch. Label
|
||||
# tracks the session flag; tool is always on PATH via airplane.nix.
|
||||
if [ "$(nomarchy-airplane is-active 2>/dev/null)" = on ]
|
||||
then row "Airplane mode (on)${menuHint "airplane"}" network-wireless-offline
|
||||
else row "Airplane mode (off)${menuHint "airplane"}" network-wireless-offline
|
||||
fi
|
||||
command -v blueman-manager >/dev/null 2>&1 \
|
||||
&& row "Bluetooth${menuHint "bluetooth"}" bluetooth
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p Connectivity) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
*Network*) exec "$0" network ;;
|
||||
*VPN*) exec "$0" vpn ;;
|
||||
*"Airplane mode"*) exec "$0" airplane ;;
|
||||
*Bluetooth*) exec "$0" bluetooth ;;
|
||||
esac ;;
|
||||
|
||||
system-devices)
|
||||
choice=$( {
|
||||
[ -e "''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/pulse/native" ] \
|
||||
&& row "Audio" audio-volume-high
|
||||
row "Display" video-display
|
||||
command -v nomarchy-keyboard-layout >/dev/null 2>&1 \
|
||||
&& row "Keyboard${menuHint "keyboard"}" preferences-desktop-keyboard
|
||||
command -v system-config-printer >/dev/null 2>&1 && row "Printers" printer
|
||||
command -v fprintd-list >/dev/null 2>&1 \
|
||||
&& row "Fingerprint" preferences-desktop-user-password
|
||||
command -v fwupdmgr >/dev/null 2>&1 && row "Firmware" firmware-manager
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p Devices) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
*Audio*) exec "$0" audio ;;
|
||||
*Display*) exec "$0" display ;;
|
||||
*Keyboard*) exec "$0" keyboard ;;
|
||||
*Printers*) exec "$0" printers ;;
|
||||
*Fingerprint*) exec "$0" fingerprint ;;
|
||||
*Firmware*) exec "$0" firmware ;;
|
||||
esac ;;
|
||||
|
||||
system-preferences)
|
||||
# Preferences + former Control Center system toggles (#110).
|
||||
# Bluetooth/Printing flip NixOS bridges → rebuild in a terminal.
|
||||
# Updates is HM-side (state-sync rebuilds home).
|
||||
choice=$( {
|
||||
row "Do Not Disturb${menuHint "dnd"}" notification-disabled
|
||||
if [ "$(nomarchy-state-sync get settings.autoTimezone 2>/dev/null)" = true ]
|
||||
then row "Auto timezone (on)" preferences-system-time
|
||||
else row "Auto timezone (off)" preferences-system-time
|
||||
fi
|
||||
# Auto-login — self-gated on the tool (greeter.enable). Off = the
|
||||
# greeter asks; that's the prompt the Fingerprint switch feeds.
|
||||
if command -v nomarchy-autologin >/dev/null 2>&1; then
|
||||
# Unset (get exits 1, empty) and null both read as off. "None" is
|
||||
# what an older state-sync printed for null — accepted so a menu
|
||||
# from a newer generation can't misreport against an older tool.
|
||||
case "$(nomarchy-state-sync get settings.greeter.autoLogin 2>/dev/null)" in
|
||||
null|""|None) row "Auto-login (off)" system-users ;;
|
||||
*) row "Auto-login (on)" system-users ;;
|
||||
@@ -1212,57 +1308,83 @@ ${themeRows}
|
||||
else row "Auto-commit (off)" git
|
||||
fi
|
||||
fi
|
||||
command -v nomarchy-snapshots >/dev/null 2>&1 && row "Snapshots" timeshift
|
||||
row "Rollback" edit-undo
|
||||
# Plain-language last-rebuild summary (nvd; BACKLOG #82).
|
||||
command -v nomarchy-what-changed >/dev/null 2>&1 \
|
||||
&& row "What changed?" view-refresh
|
||||
command -v nomarchy-doctor >/dev/null 2>&1 && row "Doctor" utilities-system-monitor
|
||||
# Firmware/LVFS updates — self-gated on fwupd (default-on, but off
|
||||
# on VMs/headless via services.fwupd.enable=false), like Printers.
|
||||
command -v fwupdmgr >/dev/null 2>&1 && row "Firmware" firmware-manager
|
||||
# Fingerprint — self-gated on fprintd CLI (services.fprintd; BACKLOG #55).
|
||||
command -v fprintd-list >/dev/null 2>&1 && row "Fingerprint" preferences-desktop-user-password
|
||||
command -v nomarchy-control-center >/dev/null 2>&1 && row "Control Center" preferences-desktop
|
||||
case "$(nomarchy-state-sync get settings.updates.enable 2>/dev/null)" in
|
||||
true|True) row "Update checks (on)" system-software-update ;;
|
||||
*) row "Update checks (off)" system-software-update ;;
|
||||
esac
|
||||
case "$(nomarchy-state-sync get settings.bluetooth.enable 2>/dev/null)" in
|
||||
false|False) row "Bluetooth package (off)" bluetooth ;;
|
||||
*) row "Bluetooth package (on)" bluetooth ;;
|
||||
esac
|
||||
case "$(nomarchy-state-sync get settings.printing.enable 2>/dev/null)" in
|
||||
true|True) row "Printing (on)" printer ;;
|
||||
*) row "Printing (off)" printer ;;
|
||||
esac
|
||||
if has_system_battery && command -v powerprofilesctl >/dev/null 2>&1; then
|
||||
row "Power profile" preferences-system-power
|
||||
fi
|
||||
# Gated on a battery (like Power profile), NOT on the
|
||||
# charge-threshold sysfs node: firmware without the control must
|
||||
# get the leaf's explanation, not a silently missing row that
|
||||
# reads as a broken feature (BACKLOG #96, Acer M5-481T).
|
||||
has_system_battery && row "Battery limit" battery-080
|
||||
command -v nomarchy-doctor >/dev/null 2>&1 && row "Doctor" utilities-system-monitor
|
||||
back
|
||||
} | rofi_menu -show-icons -markup-rows -p System) || exit 0
|
||||
} | rofi_menu -show-icons -markup-rows -p Preferences) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" ;;
|
||||
*Network*) exec "$0" network ;;
|
||||
*VPN*) exec "$0" vpn ;;
|
||||
*"Airplane mode"*) exec "$0" airplane ;;
|
||||
*Bluetooth*) exec "$0" bluetooth ;;
|
||||
*Audio*) exec "$0" audio ;;
|
||||
*Display*) exec "$0" display ;;
|
||||
*Keyboard*) exec "$0" keyboard ;;
|
||||
*Printers*) exec "$0" printers ;;
|
||||
"$BACK") exec "$0" system ;;
|
||||
*"Do Not Disturb"*) exec "$0" dnd ;;
|
||||
*"Auto timezone"*) exec "$0" autotimezone ;;
|
||||
*"Auto-login"*) exec "$0" autologin ;;
|
||||
*"Auto-commit"*) exec "$0" autocommit ;;
|
||||
*Snapshots*) exec "$0" snapshot ;;
|
||||
*Rollback*) exec "$0" rollback ;;
|
||||
*"What changed"*) exec "$0" whatchanged ;;
|
||||
*Doctor*) exec "$0" doctor ;;
|
||||
*Firmware*) exec "$0" firmware ;;
|
||||
*Fingerprint*) exec "$0" fingerprint ;;
|
||||
*"Control Center"*) exec "$0" controlcenter ;;
|
||||
*"Update checks"*) exec "$0" updates-toggle ;;
|
||||
*"Bluetooth package"*) exec "$0" bluetooth-package ;;
|
||||
*Printing*) exec "$0" printing-toggle ;;
|
||||
*"Power profile"*) exec "$0" power-profile ;;
|
||||
*"Battery limit"*) exec "$0" batterylimit ;;
|
||||
*Doctor*) exec "$0" doctor ;;
|
||||
esac ;;
|
||||
|
||||
updates-toggle)
|
||||
# settings.updates.enable → HM nomarchy.updates (Waybar checker).
|
||||
case "$(nomarchy-state-sync get settings.updates.enable 2>/dev/null)" in
|
||||
true|True)
|
||||
nomarchy-state-sync --quiet set settings.updates.enable false
|
||||
notify-send "Update checks" "Off — desktop rebuilt." ;;
|
||||
*)
|
||||
nomarchy-state-sync --quiet set settings.updates.enable true
|
||||
notify-send "Update checks" "On — desktop rebuilt." ;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
|
||||
bluetooth-package)
|
||||
# settings.bluetooth.enable → NixOS hardware.bluetooth (state bridge).
|
||||
# Needs a system rebuild; run it in a terminal with a clear story.
|
||||
case "$(nomarchy-state-sync get settings.bluetooth.enable 2>/dev/null)" in
|
||||
false|False) new=true; label=On ;;
|
||||
*) new=false; label=Off ;;
|
||||
esac
|
||||
exec ${cfg.terminal} -e sh -c "
|
||||
nomarchy-state-sync --quiet set settings.bluetooth.enable $new --no-switch
|
||||
echo \"Bluetooth package → $label (system rebuild)…\"
|
||||
echo
|
||||
nomarchy-rebuild
|
||||
echo
|
||||
printf 'Enter to close.'; read -r _" ;;
|
||||
|
||||
printing-toggle)
|
||||
case "$(nomarchy-state-sync get settings.printing.enable 2>/dev/null)" in
|
||||
true|True) new=false; label=Off ;;
|
||||
*) new=true; label=On ;;
|
||||
esac
|
||||
exec ${cfg.terminal} -e sh -c "
|
||||
nomarchy-state-sync --quiet set settings.printing.enable $new --no-switch
|
||||
echo \"Printing → $label (system rebuild)…\"
|
||||
echo
|
||||
nomarchy-rebuild
|
||||
echo
|
||||
printf 'Enter to close.'; read -r _" ;;
|
||||
|
||||
batterylimit)
|
||||
# Battery charge-limit preset picker — the rofi-System counterpart of
|
||||
# the control-center's toggle (Bernardo: he wanted this in the menu,
|
||||
# not buried in the gum TUI). Writes the baked NixOS option
|
||||
# (Bernardo: charge limit belongs in the menu, not a raw TUI). Writes
|
||||
# the baked NixOS option
|
||||
# Persist + live sysfs apply (same as powermgmt). Boot/AC re-apply
|
||||
# stays with the oneshot in power.nix.
|
||||
has_charge_threshold \
|
||||
@@ -1322,7 +1444,7 @@ ${themeRows}
|
||||
fi
|
||||
}
|
||||
case "$sel" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
"$BACK") exec "$0" system-preferences ;;
|
||||
# Order: Off (100%) before 90/80/60 so "100%" does not hit *0%* patterns.
|
||||
*Off*|*100%*) set_limit null "Off — charges to 100%" ;;
|
||||
*90%*) set_limit 90 "Set to 90%" ;;
|
||||
@@ -1363,7 +1485,7 @@ ${themeRows}
|
||||
esac ;;
|
||||
|
||||
*)
|
||||
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|airplane|audio|display|display-profile|keyboard|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autologin|autocommit|vpn|snapshot|doctor|firmware|fingerprint|controlcenter|rollback|whatchanged]" >&2
|
||||
echo "usage: nomarchy-menu [lookfeel|tools|system|system-connectivity|system-devices|system-preferences|recovery|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|airplane|audio|display|display-profile|keyboard|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autologin|autocommit|vpn|snapshot|doctor|firmware|fingerprint|rollback|whatchanged|blur|gaps|updates-toggle|bluetooth-package|printing-toggle]" >&2
|
||||
exit 64 ;;
|
||||
esac
|
||||
'';
|
||||
|
||||
@@ -21,7 +21,7 @@ let
|
||||
install -Dm444 ${./branding/Nomarchy.ttf} $out/share/fonts/truetype/Nomarchy.ttf
|
||||
'';
|
||||
|
||||
# Control Center's Bluetooth toggle writes settings.bluetooth.enable; read
|
||||
# Menu Preferences › Bluetooth package writes settings.bluetooth.enable; read
|
||||
# it from the state file, the only place it exists on the NixOS side (the
|
||||
# hardware.nix/timezone.nix bridge). Missing/invalid JSON fails closed via
|
||||
# state-read.nix rather than a raw stack. null = key absent, which
|
||||
@@ -375,7 +375,6 @@ in
|
||||
environment.systemPackages = with pkgs; [
|
||||
nomarchy-state-sync # provided by overlays.default
|
||||
nomarchy-doctor # read-only health check (System › Doctor)
|
||||
nomarchy-control-center # TUI control center
|
||||
nomarchy-detect-hw # post-install hardware re-probe (HARDWARE.md §8)
|
||||
|
||||
# Day-to-day lifecycle (README §3): nomarchy-pull / -rebuild / -home
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
audio.enable = lib.mkEnableOption "the Pipewire audio stack" // { default = true; };
|
||||
# default stays a plain `true` here; ./default.nix mkDefaults it from
|
||||
# settings.bluetooth.enable (Control Center's Bluetooth toggle). Reading
|
||||
# settings.bluetooth.enable (menu Preferences › Bluetooth package). Reading
|
||||
# the state in the option default is the trap ROADMAP § "NixOS-side state
|
||||
# bridges (#116)" documents: `config.nomarchy.settings` does not exist on
|
||||
# the NixOS side, and `or true` silently swallowed that for years.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
let
|
||||
cfg = config.nomarchy.services;
|
||||
|
||||
# Control Center's Printing toggle writes settings.printing.enable; read it
|
||||
# Menu Preferences › Printing writes settings.printing.enable; read it
|
||||
# from the state file, the only place it exists on the NixOS side (the
|
||||
# hardware.nix/timezone.nix bridge). Missing/invalid JSON fails closed via
|
||||
# state-read.nix rather than a raw stack. null = key absent, which
|
||||
@@ -88,7 +88,7 @@ in
|
||||
`services.ollama.acceleration` natively for GPU offload'';
|
||||
|
||||
# default stays a plain `false` here; the state bridge is a mkDefault
|
||||
# below, from settings.printing.enable (Control Center's Printing
|
||||
# below, from settings.printing.enable (menu Preferences › Printing
|
||||
# toggle) — see ROADMAP § state bridges (#116) for why the old read of
|
||||
# `config.nomarchy.settings` never worked.
|
||||
printing.enable = lib.mkEnableOption ''
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{ writeShellApplication, coreutils, gawk, jq, gum }:
|
||||
|
||||
writeShellApplication {
|
||||
name = "nomarchy-control-center";
|
||||
runtimeInputs = [ coreutils gawk jq gum ];
|
||||
text = builtins.readFile ./nomarchy-control-center.sh;
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Nomarchy Control Center — TUI frontend over nomarchy-state-sync and tools
|
||||
# Uses charmbracelet/gum for rendering.
|
||||
|
||||
trap 'exit 0' SIGINT
|
||||
|
||||
function get_state() {
|
||||
nomarchy-state-sync get "$1" 2>/dev/null || echo ""
|
||||
}
|
||||
|
||||
function set_state() {
|
||||
nomarchy-state-sync --quiet set "$1" "$2" --no-switch
|
||||
}
|
||||
|
||||
function first_boot() {
|
||||
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "Welcome to Nomarchy!"
|
||||
|
||||
echo "Pick a Theme Preset:"
|
||||
themes=$(nomarchy-state-sync list)
|
||||
chosen_theme=$(printf "%s" "$themes" | gum choose)
|
||||
if [ -n "$chosen_theme" ]; then
|
||||
echo "Applying theme $chosen_theme..."
|
||||
nomarchy-state-sync apply "$chosen_theme"
|
||||
fi
|
||||
|
||||
if gum confirm "Enable auto-commit for your config? (settings changes + a sweep of pending edits before each rebuild)"; then
|
||||
set_state "settings.autoCommit" "true"
|
||||
else
|
||||
set_state "settings.autoCommit" "false"
|
||||
fi
|
||||
|
||||
if command -v nomarchy-autotimezone >/dev/null 2>&1; then
|
||||
if gum confirm "Enable automatic timezone detection?"; then
|
||||
set_state "settings.autoTimezone" "true"
|
||||
else
|
||||
set_state "settings.autoTimezone" "false"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Post-install hardware/day-2 tips (#43 Firmware; #73 fingerprint +
|
||||
# doctor). Self-gated on the same CLI presence the System menu uses;
|
||||
# first-boot is once, so no dismiss state file is needed.
|
||||
if command -v fwupdmgr >/dev/null 2>&1; then
|
||||
gum style --foreground 245 \
|
||||
"Tip: SUPER+M → System › Firmware checks LVFS updates (never auto-flashes)."
|
||||
fi
|
||||
if command -v fprintd-list >/dev/null 2>&1; then
|
||||
gum style --foreground 245 \
|
||||
"Tip: SUPER+M → System › Fingerprint to enroll a finger (or fprintd-enroll)."
|
||||
fi
|
||||
if command -v nomarchy-doctor >/dev/null 2>&1; then
|
||||
gum style --foreground 245 \
|
||||
"Tip: run nomarchy-doctor (or SUPER+M → System › Doctor) for a read-only health check."
|
||||
fi
|
||||
|
||||
gum style --foreground 212 "First boot configuration complete!"
|
||||
echo "You can always change these later in the Control Center."
|
||||
read -r -n 1 -s -p "Press any key to exit..."
|
||||
echo
|
||||
}
|
||||
|
||||
function main_menu() {
|
||||
while true; do
|
||||
choice=$(gum choose "Appearance" "System Toggles" "Health (Doctor)" "Rollback" "Exit")
|
||||
case "$choice" in
|
||||
"Appearance") appearance_menu ;;
|
||||
"System Toggles") toggles_menu ;;
|
||||
"Health (Doctor)")
|
||||
if command -v nomarchy-doctor >/dev/null 2>&1; then
|
||||
nomarchy-doctor || true
|
||||
else
|
||||
echo "nomarchy-doctor not found."
|
||||
fi
|
||||
echo
|
||||
read -r -n 1 -s -p "Press any key to return..."
|
||||
echo
|
||||
;;
|
||||
"Rollback")
|
||||
gens=$(home-manager generations 2>/dev/null | head -10)
|
||||
if [ -z "$gens" ]; then
|
||||
echo "No Home Manager generations found."
|
||||
else
|
||||
tmp=$(mktemp)
|
||||
printf "%s\n" "$gens" | awk '{ printf "Desktop gen %s — %s %s%s\n", $5, $1, $2, (NR==1 ? " (current)" : "") }' > "$tmp"
|
||||
sel=$(gum choose < "$tmp" || true)
|
||||
rm -f "$tmp"
|
||||
if [ -n "$sel" ]; then
|
||||
num=${sel#Desktop gen }
|
||||
num=${num%% *}
|
||||
path=$(printf "%s\n" "$gens" | awk -v n="$num" '$5 == n { print $7 }')
|
||||
if [ -x "$path/activate" ]; then
|
||||
echo "Activating Home Manager generation $num..."
|
||||
"$path/activate"
|
||||
echo "Desktop rolled back to generation $num."
|
||||
else
|
||||
echo "Generation $num not found."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
read -r -n 1 -s -p "Press any key to return..."
|
||||
echo
|
||||
;;
|
||||
"Exit"|*) break ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function appearance_menu() {
|
||||
while true; do
|
||||
choice=$(gum choose "Pick Theme" "Toggle Blur" "Set Gaps" "Back")
|
||||
case "$choice" in
|
||||
"Pick Theme")
|
||||
themes=$(nomarchy-state-sync list)
|
||||
chosen=$(printf "%s" "$themes" | gum choose)
|
||||
if [ -n "$chosen" ]; then
|
||||
nomarchy-state-sync apply "$chosen"
|
||||
fi
|
||||
;;
|
||||
"Toggle Blur")
|
||||
blur=$(get_state "ui.blur")
|
||||
if [ "$blur" = "true" ]; then
|
||||
set_state "ui.blur" "false"
|
||||
else
|
||||
set_state "ui.blur" "true"
|
||||
fi
|
||||
echo "Blur setting saved (requires rebuild)."
|
||||
sleep 1
|
||||
;;
|
||||
"Set Gaps")
|
||||
gaps=$(gum input --prompt "Enter gaps in pixels: " --placeholder "$(get_state ui.gapsOut)")
|
||||
if [ -n "$gaps" ]; then
|
||||
set_state "ui.gapsOut" "$gaps"
|
||||
echo "Gaps set to $gaps (requires rebuild)."
|
||||
sleep 1
|
||||
fi
|
||||
;;
|
||||
"Back"|*) break ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function toggles_menu() {
|
||||
while true; do
|
||||
choice=$(gum choose "Auto-commit" "Auto-timezone" "Night Light" "Updates" "Bluetooth" "Printing" "Terminal" "Keyboard Layout" "Auto-Login" "Back")
|
||||
case "$choice" in
|
||||
"Auto-commit")
|
||||
cur=$(get_state "settings.autoCommit")
|
||||
if [ "$cur" = "true" ]; then
|
||||
set_state "settings.autoCommit" "false"
|
||||
echo "Auto-commit disabled."
|
||||
else
|
||||
set_state "settings.autoCommit" "true"
|
||||
echo "Auto-commit enabled."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Auto-timezone")
|
||||
cur=$(get_state "settings.autoTimezone")
|
||||
if [ "$cur" = "true" ]; then
|
||||
set_state "settings.autoTimezone" "false"
|
||||
echo "Auto-timezone disabled."
|
||||
else
|
||||
set_state "settings.autoTimezone" "true"
|
||||
echo "Auto-timezone enabled."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Night Light")
|
||||
if command -v nomarchy-nightlight >/dev/null 2>&1; then
|
||||
nomarchy-nightlight toggle
|
||||
sleep 1
|
||||
else
|
||||
echo "nomarchy-nightlight not found."
|
||||
sleep 1
|
||||
fi
|
||||
;;
|
||||
"Updates")
|
||||
cur=$(get_state "settings.updates.enable")
|
||||
if [ "$cur" = "true" ]; then
|
||||
set_state "settings.updates.enable" "false"
|
||||
echo "Updates checker disabled (requires rebuild)."
|
||||
else
|
||||
set_state "settings.updates.enable" "true"
|
||||
echo "Updates checker enabled (requires rebuild)."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Bluetooth")
|
||||
cur=$(get_state "settings.bluetooth.enable")
|
||||
if [ "$cur" = "true" ]; then
|
||||
set_state "settings.bluetooth.enable" "false"
|
||||
echo "Bluetooth disabled (requires rebuild)."
|
||||
else
|
||||
set_state "settings.bluetooth.enable" "true"
|
||||
echo "Bluetooth enabled (requires rebuild)."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Printing")
|
||||
cur=$(get_state "settings.printing.enable")
|
||||
if [ "$cur" = "true" ]; then
|
||||
set_state "settings.printing.enable" "false"
|
||||
echo "Printing services disabled (requires rebuild)."
|
||||
else
|
||||
set_state "settings.printing.enable" "true"
|
||||
echo "Printing services enabled (requires rebuild)."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Terminal")
|
||||
echo "Kitty is Nomarchy's terminal (themed from theme-state)."
|
||||
echo "Override nomarchy.terminal in home.nix only if you install another yourself."
|
||||
sleep 2
|
||||
;;
|
||||
"Keyboard Layout")
|
||||
layout=$(gum input --prompt "Enter keyboard layout (e.g. us, de, es): " --placeholder "$(get_state settings.keyboard.layout | tr -d '"')")
|
||||
if [ -n "$layout" ]; then
|
||||
set_state "settings.keyboard.layout" "\"$layout\""
|
||||
echo "Keyboard layout set to $layout (requires rebuild)."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Auto-Login")
|
||||
user=$(gum input --prompt "Enter auto-login username (or empty to disable): " --placeholder "$(get_state settings.greeter.autoLogin | tr -d '"')")
|
||||
if [ -n "$user" ]; then
|
||||
set_state "settings.greeter.autoLogin" "\"$user\""
|
||||
echo "Auto-login set to $user (requires rebuild)."
|
||||
else
|
||||
set_state "settings.greeter.autoLogin" "null"
|
||||
echo "Auto-login disabled (requires rebuild)."
|
||||
fi
|
||||
sleep 1
|
||||
;;
|
||||
"Back"|*) break ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--first-boot" ]; then
|
||||
first_boot
|
||||
else
|
||||
main_menu
|
||||
fi
|
||||
Reference in New Issue
Block a user