mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-06 12:39:35 +02:00
229 lines
5.0 KiB
Bash
Executable File
229 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Measure Quickshell Omarchy menu response times
|
|
# omarchy:args=[--repeat=<count>] [--no-ui]
|
|
# omarchy:examples=omarchy dev benchmark menu | omarchy dev benchmark menu --repeat=10
|
|
|
|
set -euo pipefail
|
|
|
|
OMARCHY_BIN_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
|
OMARCHY_PATH=${OMARCHY_PATH:-$(cd -- "$OMARCHY_BIN_DIR/.." && pwd)}
|
|
REPEAT=5
|
|
NO_UI=false
|
|
|
|
show_help() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
omarchy dev benchmark menu [--repeat=<count>] [--no-ui]
|
|
|
|
Measure the Omarchy menu startup path:
|
|
- static JSONC menu parsing
|
|
- Quickshell socket startup
|
|
- cold open/close roundtrip (unless --no-ui)
|
|
- warm open/close roundtrip against the resident Quickshell process
|
|
|
|
Options:
|
|
--repeat=<count> Number of UI open/close runs to measure (default: 5)
|
|
--no-ui Skip cases that briefly open the menu
|
|
EOF
|
|
}
|
|
|
|
now_us() {
|
|
local now="${EPOCHREALTIME/./}"
|
|
printf '%s' "$now"
|
|
}
|
|
|
|
format_ms() {
|
|
local us="$1"
|
|
printf '%d.%03d' "$(( us / 1000 ))" "$(( us % 1000 ))"
|
|
}
|
|
|
|
measure_once() {
|
|
local start_us end_us
|
|
start_us=$(now_us)
|
|
"$@" >/dev/null
|
|
end_us=$(now_us)
|
|
printf '%s' "$(( end_us - start_us ))"
|
|
}
|
|
|
|
run_case() {
|
|
local label="$1"
|
|
shift
|
|
local total_us=0
|
|
local min_us=0
|
|
local max_us=0
|
|
local elapsed_us=0
|
|
|
|
for (( i = 1; i <= REPEAT; i++ )); do
|
|
elapsed_us=$(measure_once "$@")
|
|
total_us=$(( total_us + elapsed_us ))
|
|
|
|
if (( i == 1 || elapsed_us < min_us )); then
|
|
min_us=$elapsed_us
|
|
fi
|
|
|
|
if (( elapsed_us > max_us )); then
|
|
max_us=$elapsed_us
|
|
fi
|
|
done
|
|
|
|
printf '%-34s avg %8s ms min %8s ms max %8s ms\n' \
|
|
"$label" \
|
|
"$(format_ms "$(( total_us / REPEAT ))")" \
|
|
"$(format_ms "$min_us")" \
|
|
"$(format_ms "$max_us")"
|
|
}
|
|
|
|
socket_path() {
|
|
printf '%s/omarchy-menu.sock' "${XDG_RUNTIME_DIR:-/run/user/$UID}"
|
|
}
|
|
|
|
menu_qml() {
|
|
printf '%s/default/quickshell/menu.qml' "$OMARCHY_PATH"
|
|
}
|
|
|
|
kill_menu_shell() {
|
|
quickshell kill -p "$(menu_qml)" >/dev/null 2>&1 || true
|
|
|
|
for (( i = 0; i < 200; i++ )); do
|
|
if ! pgrep -f "[q]uickshell .*$(menu_qml)" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 0.01
|
|
done
|
|
|
|
rm -f "$(socket_path)" "${XDG_RUNTIME_DIR:-/run/user/$UID}/omarchy-menu.state" "${XDG_RUNTIME_DIR:-/run/user/$UID}/omarchy-menu.lock"
|
|
}
|
|
|
|
build_menu_json() {
|
|
env OMARCHY_PATH="$OMARCHY_PATH" PATH="$OMARCHY_BIN_DIR:$PATH" \
|
|
"$OMARCHY_BIN_DIR/omarchy-menu" --json
|
|
}
|
|
|
|
start_quickshell_socket() {
|
|
local menu_file
|
|
local selection_file
|
|
local done_file
|
|
|
|
kill_menu_shell
|
|
menu_file=$(mktemp)
|
|
selection_file=$(mktemp)
|
|
done_file=$(mktemp)
|
|
printf '{"items":[]}' >"$menu_file"
|
|
rm -f "$done_file"
|
|
|
|
env \
|
|
OMARCHY_PATH="$OMARCHY_PATH" \
|
|
OMARCHY_MENU_JSON_FILE="$menu_file" \
|
|
OMARCHY_MENU_INITIAL_MENU="root" \
|
|
OMARCHY_MENU_SELECTION_FILE="$selection_file" \
|
|
OMARCHY_MENU_DONE_FILE="$done_file" \
|
|
quickshell -n -d -p "$(menu_qml)" >/dev/null
|
|
|
|
for (( i = 0; i < 200; i++ )); do
|
|
[[ -S $(socket_path) ]] && break
|
|
sleep 0.01
|
|
done
|
|
|
|
[[ -S $(socket_path) ]]
|
|
kill_menu_shell
|
|
rm -f "$menu_file" "$selection_file" "$done_file"
|
|
}
|
|
|
|
menu_layer_visible() {
|
|
hyprctl layers -j 2>/dev/null | jq -e '.. | objects | select(.namespace? == "omarchy-menu")' >/dev/null
|
|
}
|
|
|
|
open_close_menu() {
|
|
local pid
|
|
|
|
env OMARCHY_PATH="$OMARCHY_PATH" PATH="$OMARCHY_BIN_DIR:$PATH" \
|
|
"$OMARCHY_BIN_DIR/omarchy-menu" >/dev/null &
|
|
pid=$!
|
|
|
|
for (( i = 0; i < 300; i++ )); do
|
|
if menu_layer_visible && [[ -S $(socket_path) ]]; then
|
|
break
|
|
fi
|
|
sleep 0.01
|
|
done
|
|
|
|
if [[ ! -S $(socket_path) ]]; then
|
|
kill "$pid" 2>/dev/null || true
|
|
kill_menu_shell
|
|
return 1
|
|
fi
|
|
|
|
printf 'close\n' | socat -u - "UNIX-CONNECT:$(socket_path)" >/dev/null 2>&1 || true
|
|
|
|
for (( i = 0; i < 500; i++ )); do
|
|
if ! kill -0 "$pid" 2>/dev/null; then
|
|
break
|
|
fi
|
|
sleep 0.01
|
|
done
|
|
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null || true
|
|
kill_menu_shell
|
|
return 1
|
|
fi
|
|
|
|
wait "$pid" || true
|
|
}
|
|
|
|
cold_open_close_menu() {
|
|
kill_menu_shell
|
|
open_close_menu
|
|
kill_menu_shell
|
|
}
|
|
|
|
warm_open_close_menu() {
|
|
open_close_menu
|
|
}
|
|
|
|
while (( $# > 0 )); do
|
|
case "$1" in
|
|
--repeat=*) REPEAT="${1#*=}" ;;
|
|
--no-ui) NO_UI=true ;;
|
|
--help | -h)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
show_help >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [[ ! $REPEAT =~ ^[0-9]+$ ]] || (( REPEAT < 1 )); then
|
|
echo "--repeat must be a positive integer" >&2
|
|
exit 2
|
|
fi
|
|
|
|
cleanup() {
|
|
kill_menu_shell
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
run_label="runs"
|
|
(( REPEAT == 1 )) && run_label="run"
|
|
printf 'Omarchy menu benchmark (%d %s each)\n\n' "$REPEAT" "$run_label"
|
|
|
|
run_case "menu JSON build" build_menu_json
|
|
|
|
if [[ $NO_UI != true ]]; then
|
|
if omarchy-cmd-present quickshell socat hyprctl jq && [[ -n ${WAYLAND_DISPLAY:-} ]]; then
|
|
printf '%-34s %s ms\n' "quickshell socket startup" "$(format_ms "$(measure_once start_quickshell_socket)")"
|
|
run_case "cold open/close" cold_open_close_menu
|
|
kill_menu_shell
|
|
open_close_menu >/dev/null
|
|
run_case "warm open/close" warm_open_close_menu
|
|
else
|
|
printf 'Skipping UI cases: quickshell/socat/hyprctl/jq/Wayland unavailable\n'
|
|
fi
|
|
fi
|