Thirty settings pages is the opposite of the usual problem: a person arriving from GNOME, macOS or Windows cannot tell which few things matter. This is those few, once, on the first start. Not a tour. Nobody reads a tour, and a multi-step wizard on a desktop somebody just installed is one more thing between them and using it. One card, five keys, and a way out. The chords come from the live keymap rather than being written here, so a machine whose owner has already rebound something teaches what they actually have. A welcome screen is the one surface read by somebody with no way to tell it is wrong, which is exactly why it must not be. Two deliberate departures from how every other surface behaves. It does not close on a click outside, because a stray click in the first thirty seconds would throw away the only explanation on offer. And dismissing by any route marks it seen, Escape included, because a desktop that reintroduces itself every login has failed to take no for an answer. It stays reachable from the launcher afterwards, since the moment somebody wants it again is exactly when a one-shot has thrown it away. Also teaches the keymap to spell punctuation: slash, period, comma and the rest were rendering as their raw keysym names, so the welcome screen offered "Super + slash" and the cheatsheet agreed with it.
159 lines
6.9 KiB
Bash
Executable File
159 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
commands_dir="$repo_dir/config/local/share/vicinae/scripts"
|
|
work="$(mktemp -d /tmp/panama-commands.XXXXXX)"
|
|
dispatch_log="$work/dispatch.log"
|
|
|
|
fail() {
|
|
printf 'Panama commands contract: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
cleanup() {
|
|
rm -rf "$work"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
declare -A expected=(
|
|
[open-control-center]=control-center
|
|
[open-notifications]=notifications
|
|
[open-calendar]=calendar
|
|
[open-clipboard]=clipboard
|
|
[open-mission-control]=overview
|
|
[open-settings]=settings
|
|
[check-system-health]=health
|
|
[toggle-dnd]=dnd
|
|
[toggle-caffeine]=caffeine
|
|
[toggle-night-light]=night-light
|
|
[start-focus]=focus-start
|
|
[end-focus]=focus-end
|
|
[capture]=capture
|
|
[screen-intelligence]=intelligence
|
|
[quick-screenshot]=screenshot
|
|
[toggle-microphone]=microphone
|
|
[open-prism-gallery]=gallery
|
|
[restart-shell]=restart-shell
|
|
)
|
|
|
|
# The per-page settings commands are generated from the settings page list, so
|
|
# they are enumerated from that list rather than restated here -- a hand-written
|
|
# copy would have to be edited every time a page is added, which is exactly the
|
|
# kind of second list this generator exists to avoid.
|
|
sidebar="$repo_dir/config/dot/quickshell/modules/settings/SettingsSidebar.qml"
|
|
while read -r page; do
|
|
[[ -n "$page" ]] || continue
|
|
[[ "$page" == "home" ]] && continue
|
|
expected[settings-$page]="settings-page $page"
|
|
done < <(grep -oE '\{ page: "[a-z-]+"' "$sidebar" | sed 's/.*"\([a-z-]*\)"/\1/')
|
|
|
|
(( ${#expected[@]} > 18 )) || fail 'no generated per-page commands were found; run scripts/panama-settings-commands'
|
|
|
|
# Commands that do not go through panama-action, and should not.
|
|
#
|
|
# Every command above asks the shell to do something, so routing them through
|
|
# one dispatcher is what keeps that surface small. search-web is a different
|
|
# animal: it takes a query and opens a browser, and neither half needs the
|
|
# shell. Sending it through panama-action would mean a web search stops working
|
|
# when Quickshell is down -- which is exactly when somebody is reaching for the
|
|
# launcher to look up what went wrong.
|
|
#
|
|
# The project commands are the same shape: they record or restore a window
|
|
# layout, which is panama-project's job and involves the shell not at all.
|
|
#
|
|
# They are still commands, so everything else below applies to them: a title,
|
|
# a description, search vocabulary, the Panama icon, and closing quietly.
|
|
#
|
|
# The OS-parity commands are standalone for the same reason. A power menu that
|
|
# needs the shell running is a power menu you cannot reach when the shell is
|
|
# what broke; the pick-lists render through `vicinae dmenu` and act through
|
|
# hyprctl; reminders are systemd timers. None of them has anything to ask the
|
|
# shell for, and routing them through panama-action would only add a way for
|
|
# them to stop working.
|
|
declare -a standalone=(
|
|
search-web save-project open-project
|
|
lock-screen suspend-system log-out reboot-system power-off
|
|
remind-me list-reminders pick-color
|
|
switch-window force-quit-window kill-process ssh-hosts recent-files
|
|
copy-password keyboard-shortcuts show-welcome
|
|
)
|
|
|
|
# Generated commands must match their source. A stale command dispatches to a
|
|
# page that has been renamed or removed, and the launcher reports nothing wrong.
|
|
"$repo_dir/config/dot/quickshell/scripts/panama-settings-commands" --check >/dev/null \
|
|
|| fail 'the generated per-page commands are stale; run scripts/panama-settings-commands'
|
|
|
|
mkdir -p "$work/home/.config/quickshell/scripts"
|
|
cat >"$work/home/.config/quickshell/scripts/panama-action" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
printf '%s\n' "$*" >>"$PANAMA_COMMAND_TEST_LOG"
|
|
EOF
|
|
chmod +x "$work/home/.config/quickshell/scripts/panama-action"
|
|
|
|
[[ -d "$commands_dir" ]] || fail 'Vicinae command directory is missing'
|
|
|
|
# Every file in the directory, not a glob on an extension. These scripts carry
|
|
# none: a shebang and the executable bit already select the interpreter, and an
|
|
# extension is one more thing that has to stay in sync -- which it did not.
|
|
mapfile -t actual_files < <(find "$commands_dir" -maxdepth 1 -type f -printf '%f\n' | sort)
|
|
declared=$(( ${#expected[@]} + ${#standalone[@]} ))
|
|
[[ ${#actual_files[@]} -eq $declared ]] \
|
|
|| fail "expected $declared commands, found ${#actual_files[@]}"
|
|
|
|
declare -A seen_titles=()
|
|
for script_name in "${!expected[@]}" "${standalone[@]}"; do
|
|
script="$commands_dir/$script_name"
|
|
[[ -x "$script" ]] || fail "$script_name is missing or not executable"
|
|
|
|
vicinae script check "$script" >/dev/null \
|
|
|| fail "$script_name is rejected by Vicinae"
|
|
|
|
title="$(sed -n 's/^# @vicinae.title //p' "$script")"
|
|
# No product prefix: this is the desktop's own settings, not a third-party
|
|
# add-on announcing itself in someone else's launcher. Uniqueness still
|
|
# matters, because two commands with one title are indistinguishable there.
|
|
[[ -n $title ]] || fail "$script_name has no title"
|
|
[[ $title != Panama* ]] || fail "$script_name still carries the product prefix: $title"
|
|
[[ -z ${seen_titles[$title]+x} ]] || fail "duplicate launcher title: $title"
|
|
seen_titles[$title]=1
|
|
|
|
grep -Fxq '# @vicinae.mode silent' "$script" \
|
|
|| fail "$script_name does not close quietly after success"
|
|
grep -Fq '# @vicinae.description ' "$script" \
|
|
|| fail "$script_name has no searchable description"
|
|
grep -Fq '# @vicinae.keywords ' "$script" \
|
|
|| fail "$script_name has no search vocabulary"
|
|
grep -Fxq '# @vicinae.icon ../../icons/hicolor/scalable/apps/panama-settings.svg' "$script" \
|
|
|| fail "$script_name does not use the Panama application identity"
|
|
|
|
if [[ $script_name == check-system-health ]]; then
|
|
[[ $title == 'Check System Health' ]] \
|
|
|| fail "health command has the wrong title: $title"
|
|
grep -Fxq '# @vicinae.schemaVersion 1' "$script" \
|
|
|| fail 'health command does not use schema version 1'
|
|
grep -Fxq '# @vicinae.keywords ["health", "doctor", "repair", "services"]' "$script" \
|
|
|| fail 'health command has the wrong search vocabulary'
|
|
grep -Fxq 'exec "$HOME/.config/quickshell/scripts/panama-action" health' "$script" \
|
|
|| fail 'health command bypasses the stable dispatcher path'
|
|
fi
|
|
|
|
# A standalone command has nothing to dispatch, and running it would open a
|
|
# browser at whoever is running the tests.
|
|
if [[ -z ${expected[$script_name]+x} ]]; then
|
|
if grep -Fq 'panama-action' "$script"; then
|
|
fail "$script_name is listed as standalone but goes through panama-action"
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
: >"$dispatch_log"
|
|
HOME="$work/home" PANAMA_COMMAND_TEST_LOG="$dispatch_log" "$script"
|
|
dispatched="$(cat "$dispatch_log")"
|
|
[[ $dispatched == "${expected[$script_name]}" ]] \
|
|
|| fail "$script_name dispatched [$dispatched], expected [${expected[$script_name]}]"
|
|
done
|
|
|
|
printf 'Panama commands contract: PASS (%d commands)\n' "$declared"
|