mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-02 04:37:49 +02:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b4219727f | ||
|
|
b5671cb0cc | ||
|
|
860c0ab0d8 | ||
|
|
4ae55d61cd | ||
|
|
3ae0915092 | ||
|
|
8387a575aa | ||
|
|
44915b9a5e | ||
|
|
c336de6b5b |
Executable
+228
@@ -0,0 +1,228 @@
|
||||
#!/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
|
||||
+933
-828
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Set Hyprland, Hyprlock, Mako, and Walker corners to sharp or round
|
||||
# omarchy:summary=Set Hyprland, Hyprlock, Mako, Walker, and Quickshell corners to sharp or round
|
||||
# omarchy:args=<sharp|round>
|
||||
# omarchy:examples=omarchy style corners round | omarchy style corners sharp
|
||||
|
||||
@@ -13,6 +13,7 @@ omarchy-style-corners-hyprland "$1"
|
||||
omarchy-style-corners-hyprlock "$1"
|
||||
omarchy-style-corners-mako "$1"
|
||||
omarchy-style-corners-walker "$1"
|
||||
omarchy-style-corners-quickshell "$1"
|
||||
|
||||
case $1 in
|
||||
sharp) omarchy-notification-send "Sharp corners enabled" -g ;;
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Set Quickshell Omarchy menu corners
|
||||
# omarchy:args=<sharp|round>
|
||||
# omarchy:examples=omarchy style corners quickshell round | omarchy style corners quickshell sharp
|
||||
|
||||
set_radius() {
|
||||
local radius="$1"
|
||||
local toggles_dir="$HOME/.local/state/omarchy/toggles"
|
||||
|
||||
mkdir -p "$toggles_dir"
|
||||
printf '{ "radius": %s }\n' "$radius" >"$toggles_dir/quickshell-menu.json"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
sharp) set_radius 0 ;;
|
||||
round) set_radius 6 ;;
|
||||
*)
|
||||
echo "Usage: omarchy-style-corners-quickshell <sharp|round>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,20 +0,0 @@
|
||||
# Overwrite parts of the omarchy-menu with user-specific submenus.
|
||||
# See $OMARCHY_PATH/bin/omarchy-menu for functions that can be overwritten.
|
||||
#
|
||||
# WARNING: Overwritten functions will obviously not be updated when Omarchy changes.
|
||||
#
|
||||
# Example of minimal system menu:
|
||||
#
|
||||
# show_system_menu() {
|
||||
# case $(menu "System" " Lock\n Shutdown") in
|
||||
# *Lock*) omarchy-system-lock ;;
|
||||
# *Shutdown*) omarchy-system-shutdown ;;
|
||||
# *) back_to show_main_menu ;;
|
||||
# esac
|
||||
# }
|
||||
#
|
||||
# Example of overriding just the about menu action: (Using zsh instead of bash (default))
|
||||
#
|
||||
# show_about() {
|
||||
# exec omarchy-launch-or-focus-tui "zsh -c 'fastfetch; read -k 1'"
|
||||
# }
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
// Extend the Quickshell Omarchy menu with JSONC.
|
||||
//
|
||||
// IDs are object keys. The parent is inferred from the dotted id, so
|
||||
// "personal.notes" appears under "personal", and "personal" appears on the
|
||||
// root menu. Reuse an existing id to override/extend it.
|
||||
//
|
||||
// Fields:
|
||||
// icon Nerd Font glyph shown in the icon column.
|
||||
// label Visible row title.
|
||||
// action Shell command to run. If omitted, the row is a submenu.
|
||||
// target Existing submenu id to open. Use for links/aliases.
|
||||
// provider Runtime provider function/command returning JSON rows.
|
||||
// aliases Alternate `omarchy-menu <name>` routes; also searchable.
|
||||
// keywords Extra search terms beyond id/label/aliases.
|
||||
// description Optional subtitle and extra search text.
|
||||
// when Shell condition; hide row when it fails.
|
||||
// checked Shell condition; append ✓ when it succeeds.
|
||||
//
|
||||
// Examples:
|
||||
// "personal": {"icon":"","label":"Personal","keywords":"notes projects"},
|
||||
// "personal.notes": {"icon":"","label":"Notes","action":"omarchy-launch-editor ~/notes","keywords":"notes"},
|
||||
// "personal.files": {"icon":"","label":"Files","action":"uwsm-app -- nautilus ~/Documents","keywords":"files documents"},
|
||||
//
|
||||
// Only use provider when a provider_name function or command named "name"
|
||||
// returns JSON rows. Static submenus only need dotted ids.
|
||||
//
|
||||
// Example: replace the default About action by reusing the same id. Existing
|
||||
// fields are kept unless overridden.
|
||||
// "about": {"icon":"","label":"About","action":"omarchy-launch-or-focus-tui \"zsh -c 'fastfetch; read -k 1'\""},
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
-- Remove 1px border around hyprshot screenshots.
|
||||
hl.layer_rule({ match = { namespace = "selection" }, no_anim = true })
|
||||
hl.layer_rule({ match = { namespace = "selection" }, no_anim = true, animation = "none" })
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Keep the menu instant: no layer-shell fade/slide animation.
|
||||
hl.layer_rule({ match = { namespace = "omarchy-menu" }, no_anim = true, animation = "none" })
|
||||
@@ -15,4 +15,4 @@ o.window({ tag = "pop" }, { rounding = 8 })
|
||||
o.window({ tag = "noidle" }, { idle_inhibit = "always" })
|
||||
|
||||
-- Disable animations for image selector overlay.
|
||||
hl.layer_rule({ match = { namespace = "omarchy-image-selector" }, no_anim = true })
|
||||
hl.layer_rule({ match = { namespace = "omarchy-image-selector" }, no_anim = true, animation = "none" })
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-- Application-specific animation.
|
||||
hl.layer_rule({ match = { namespace = "walker" }, no_anim = true })
|
||||
hl.layer_rule({ match = { namespace = "walker" }, no_anim = true, animation = "none" })
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
decoration {
|
||||
rounding = 6
|
||||
rounding_power = 3
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Use round window corners.
|
||||
hl.config({
|
||||
decoration = {
|
||||
rounding = 6,
|
||||
rounding_power = 3,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,333 @@
|
||||
{
|
||||
// Omarchy menu definition.
|
||||
// JSONC is used for Neovim-friendly highlighting, comments, and trailing commas.
|
||||
// IDs are object keys. Dotted IDs imply hierarchy: trigger.share.file belongs
|
||||
// under trigger.share.
|
||||
// Kind is inferred: action -> action, target -> link, otherwise submenu.
|
||||
// Dotted IDs define the tree. Use provider:"name" only when the submenu
|
||||
// calls provider_name() or a command named "name" to return JSON rows.
|
||||
// Optional fields:
|
||||
// aliases alternate `omarchy-menu <name>` routes; also searchable
|
||||
// keywords extra search terms beyond id/label/aliases
|
||||
// when shell condition; hide row when it fails
|
||||
// checked shell condition; append ✓ when it succeeds
|
||||
|
||||
// Root Menu
|
||||
"apps": {"icon":"","label":"Apps","aliases":["app","applications"],"keywords":"launch launcher","action":"omarchy-launch-walker -p 'Launch…'"},
|
||||
"learn": {"icon":"","label":"Learn","keywords":"manual docs help reference"},
|
||||
"trigger": {"icon":"","label":"Trigger","keywords":"actions capture share toggle hardware reminder"},
|
||||
"style": {"icon":"","label":"Style","keywords":"theme background font waybar hyprland appearance"},
|
||||
"setup": {"icon":"","label":"Setup","aliases":["settings"],"keywords":"configure defaults wifi bluetooth audio"},
|
||||
"install": {"icon":"","label":"Install","keywords":"package app service browser editor terminal development gaming"},
|
||||
"remove": {"icon":"","label":"Remove","aliases":["uninstall"],"keywords":"package app browser development gaming"},
|
||||
"update": {"icon":"","label":"Update","aliases":["restart","refresh"],"keywords":"upgrade channel firmware timezone"},
|
||||
"about": {"icon":"","label":"About","keywords":"omarchy system information","action":"omarchy-launch-about"},
|
||||
"system": {"icon":"","label":"System","aliases":["power-menu"],"keywords":"lock logout restart shutdown suspend hibernate"},
|
||||
|
||||
// System
|
||||
"system.screensaver": {"icon":"","label":"Screensaver","action":"omarchy-launch-screensaver force"},
|
||||
"system.lock": {"icon":"","label":"Lock","keywords":"screen","action":"omarchy-system-lock"},
|
||||
"system.suspend": {"icon":"","label":"Suspend","keywords":"sleep","when":"! omarchy-toggle-enabled suspend-off","action":"systemctl suspend"},
|
||||
"system.hibernate": {"icon":"","label":"Hibernate","keywords":"sleep","when":"omarchy-hibernation-available","action":"systemctl hibernate"},
|
||||
"system.logout": {"icon":"","label":"Logout","keywords":"sign out","action":"omarchy-system-logout"},
|
||||
"system.restart": {"icon":"","label":"Restart","keywords":"reboot","action":"omarchy-system-reboot"},
|
||||
"system.shutdown": {"icon":"","label":"Shutdown","keywords":"power off","action":"omarchy-system-shutdown"},
|
||||
|
||||
// Learn
|
||||
"learn.keybindings": {"icon":"","label":"Keybindings","keywords":"keyboard shortcuts bindings","action":"omarchy-menu-keybindings"},
|
||||
"learn.tmux-keybindings": {"icon":"","label":"Tmux keybindings","keywords":"keyboard shortcuts bindings terminal","action":"omarchy-menu-tmux-keybindings"},
|
||||
"learn.omarchy": {"icon":"","label":"Omarchy","keywords":"manual documentation","action":"omarchy-launch-webapp 'https://learn.omacom.io/2/the-omarchy-manual'"},
|
||||
"learn.hyprland": {"icon":"","label":"Hyprland","keywords":"wiki docs","action":"omarchy-launch-webapp 'https://wiki.hypr.land/'"},
|
||||
"learn.arch": {"icon":"","label":"Arch","keywords":"linux wiki docs","action":"omarchy-launch-webapp 'https://wiki.archlinux.org/title/Main_page'"},
|
||||
"learn.neovim": {"icon":"","label":"Neovim","keywords":"lazyvim keymaps docs","action":"omarchy-launch-webapp 'https://www.lazyvim.org/keymaps'"},
|
||||
"learn.bash": {"icon":"","label":"Bash","keywords":"shell cheatsheet","action":"omarchy-launch-webapp 'https://devhints.io/bash'"},
|
||||
|
||||
// Trigger
|
||||
"trigger.reminder": {"icon":"","label":"Reminder","aliases":["reminder"],"keywords":"timer notification remind"},
|
||||
"trigger.capture": {"icon":"","label":"Capture","aliases":["capture","screenshot","screenrecord","screen-record","screenrecording"],"keywords":"color text extraction"},
|
||||
"trigger.capture.screenshot": {"icon":"","label":"Screenshot","keywords":"picture","action":"omarchy-capture-screenshot"},
|
||||
"trigger.capture.screenrecord.stop": {"icon":"","label":"Stop Screenrecording","keywords":"recording video","when":"pgrep -f '^gpu-screen-recorder' >/dev/null","action":"stop_active_screenrecording"},
|
||||
"trigger.capture.screenrecord": {"icon":"","label":"Screenrecord","keywords":"record screen video"},
|
||||
"trigger.capture.text": {"icon":"","label":"Text Extraction","keywords":"ocr","action":"omarchy-capture-text-extraction"},
|
||||
"trigger.capture.color": {"icon":"","label":"Color","keywords":"picker hyprpicker","action":"pkill hyprpicker || hyprpicker -a"},
|
||||
"trigger.capture.screenrecord.no-audio": {"icon":"","label":"With no audio","action":"omarchy-capture-screenrecording"},
|
||||
"trigger.capture.screenrecord.desktop-audio": {"icon":"","label":"With desktop audio","action":"omarchy-capture-screenrecording --with-desktop-audio"},
|
||||
"trigger.capture.screenrecord.microphone": {"icon":"","label":"With desktop + microphone audio","keywords":"mic","action":"omarchy-capture-screenrecording --with-desktop-audio --with-microphone-audio"},
|
||||
"trigger.capture.screenrecord.webcam": {"icon":"","label":"With desktop + microphone audio + webcam","keywords":"camera","action":"screenrecord_with_webcam"},
|
||||
"trigger.transcode": {"icon":"","label":"Transcode","keywords":"convert image video","action":"omarchy-transcode"},
|
||||
"trigger.share": {"icon":"","label":"Share","aliases":["share"],"keywords":"clipboard file folder localsend"},
|
||||
"trigger.toggle": {"icon":"","label":"Toggle","aliases":["toggle","toggles"],"keywords":"screensaver nightlight idle notifications waybar"},
|
||||
"trigger.hardware": {"icon":"","label":"Hardware","aliases":["hardware","hw"],"keywords":"monitor touchpad touchscreen gpu"},
|
||||
"trigger.hardware.laptop-display": {"icon":"","label":"Laptop Display","keywords":"monitor","action":"omarchy-hyprland-monitor-internal toggle"},
|
||||
"trigger.hardware.mirror-display": {"icon":"","label":"Mirror Display","keywords":"monitor","action":"omarchy-hyprland-monitor-internal-mirror toggle"},
|
||||
"trigger.hardware.hybrid-gpu": {"icon":"","label":"Hybrid GPU","keywords":"graphics","when":"omarchy-hw-hybrid-gpu >/dev/null","action":"present_terminal omarchy-toggle-hybrid-gpu"},
|
||||
"trigger.hardware.touchpad": {"icon":"","label":"Touchpad","keywords":"trackpad","when":"omarchy-hw-touchpad >/dev/null","action":"omarchy-toggle-touchpad"},
|
||||
"trigger.hardware.touchpad-haptics": {"icon":"","label":"Touchpad Haptics","when":"omarchy-hw-dell-xps-haptic-touchpad >/dev/null && omarchy-cmd-present dell-xps-touchpad-haptics"},
|
||||
"trigger.hardware.touchpad-haptics.low": {"icon":"","label":"low","when":"omarchy-hw-dell-xps-haptic-touchpad >/dev/null && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"haptic_touchpad_is low","action":"dell-xps-touchpad-haptics set low"},
|
||||
"trigger.hardware.touchpad-haptics.mid": {"icon":"","label":"mid","keywords":"medium","when":"omarchy-hw-dell-xps-haptic-touchpad >/dev/null && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"haptic_touchpad_is mid","action":"dell-xps-touchpad-haptics set mid"},
|
||||
"trigger.hardware.touchpad-haptics.high": {"icon":"","label":"high","when":"omarchy-hw-dell-xps-haptic-touchpad >/dev/null && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"haptic_touchpad_is high","action":"dell-xps-touchpad-haptics set high"},
|
||||
"trigger.hardware.touchscreen": {"icon":"","label":"Touchscreen","keywords":"tablet","when":"omarchy-hw-touchscreen >/dev/null","action":"omarchy-toggle-touchscreen"},
|
||||
"trigger.reminder.set": {"icon":"","label":"Set one","aliases":["reminder-set","remind"],"keywords":"timer","action":"show_custom_reminder_input"},
|
||||
"trigger.reminder.show": {"icon":"","label":"Show all","keywords":"list","action":"omarchy-reminder show"},
|
||||
"trigger.reminder.clear": {"icon":"","label":"Clear all","keywords":"delete","action":"omarchy-reminder clear"},
|
||||
"trigger.share.clipboard": {"icon":"","label":"Clipboard","action":"omarchy-menu-share clipboard"},
|
||||
"trigger.share.file": {"icon":"","label":"File","action":"terminal bash -c 'omarchy-menu-share file'"},
|
||||
"trigger.share.folder": {"icon":"","label":"Folder","keywords":"directory","action":"terminal bash -c 'omarchy-menu-share folder'"},
|
||||
"trigger.share.receive": {"icon":"","label":"Receive","keywords":"localsend","action":"uwsm-app -- localsend"},
|
||||
"trigger.toggle.screensaver": {"icon":"","label":"Screensaver","action":"omarchy-toggle-screensaver"},
|
||||
"trigger.toggle.nightlight": {"icon":"","label":"Nightlight","keywords":"night light hyprsunset","action":"omarchy-toggle-nightlight"},
|
||||
"trigger.toggle.idle-lock": {"icon":"","label":"Idle Lock","keywords":"hypridle","action":"omarchy-toggle-idle"},
|
||||
"trigger.toggle.notifications": {"icon":"","label":"Notifications","keywords":"mako silence","action":"omarchy-toggle-notification-silencing"},
|
||||
"trigger.toggle.top-bar": {"icon":"","label":"Top Bar","keywords":"waybar","action":"omarchy-toggle-waybar"},
|
||||
"trigger.toggle.workspace-layout": {"icon":"","label":"Workspace Layout","action":"omarchy-hyprland-workspace-layout-toggle"},
|
||||
"trigger.toggle.window-gaps": {"icon":"","label":"Window Gaps","action":"omarchy-hyprland-window-gaps-toggle"},
|
||||
"trigger.toggle.one-window-ratio": {"icon":"","label":"1-Window Ratio","keywords":"square","action":"omarchy-hyprland-window-single-square-aspect-toggle"},
|
||||
"trigger.toggle.monitor-scaling": {"icon":"","label":"Monitor Scaling","keywords":"display","action":"omarchy-hyprland-monitor-scaling-cycle"},
|
||||
"trigger.toggle.direct-boot": {"icon":"","label":"Direct Boot","action":"present_terminal omarchy-config-direct-boot"},
|
||||
"trigger.toggle.passwordless-sudo": {"icon":"","label":"Passwordless Sudo","action":"present_terminal omarchy-sudo-passwordless"},
|
||||
|
||||
// Style
|
||||
"style.theme": {"icon":"","label":"Theme","aliases":["theme","themes"],"keywords":"colors","action":"theme=$(omarchy-theme-switcher); [[ -n $theme ]] && omarchy-theme-set \"$theme\""},
|
||||
"style.unlock": {"icon":"","label":"Unlock","keywords":"themes","action":"omarchy-launch-walker -m menus:omarchyunlocks --width 800 --minheight 400"},
|
||||
"style.font": {"icon":"","label":"Font","keywords":"typeface","provider":"fonts"},
|
||||
"style.background": {"icon":"","label":"Background","aliases":["background","wallpaper"],"action":"background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""},
|
||||
"style.waybar": {"icon":"","label":"Waybar","keywords":"bar top bottom left right"},
|
||||
"style.corners": {"icon":"","label":"Corners","keywords":"sharp round rounded"},
|
||||
"style.hyprland": {"icon":"","label":"Hyprland","keywords":"look feel","action":"open_in_editor \"$(hypr_config_file looknfeel)\""},
|
||||
"style.screensaver": {"icon":"","label":"Screensaver","keywords":"branding"},
|
||||
"style.about": {"icon":"","label":"About","keywords":"branding"},
|
||||
"style.install": {"icon":"","label":"Install","keywords":"theme background font"},
|
||||
"style.waybar.top": {"icon":"","label":"Top","keywords":"position","action":"omarchy-style-waybar-position top"},
|
||||
"style.waybar.bottom": {"icon":"","label":"Bottom","keywords":"position","action":"omarchy-style-waybar-position bottom"},
|
||||
"style.waybar.left": {"icon":"","label":"Left","keywords":"position","action":"omarchy-style-waybar-position left"},
|
||||
"style.waybar.right": {"icon":"","label":"Right","keywords":"position","action":"omarchy-style-waybar-position right"},
|
||||
"style.corners.sharp": {"icon":"","label":"Sharp","keywords":"square","action":"omarchy-style-corners sharp"},
|
||||
"style.corners.round": {"icon":"","label":"Round","keywords":"rounded","action":"omarchy-style-corners round"},
|
||||
"style.about.text": {"icon":"","label":"Edit Text","keywords":"branding","action":"omarchy-branding-about text"},
|
||||
"style.about.image": {"icon":"","label":"Set From Image","keywords":"branding","action":"omarchy-branding-about image"},
|
||||
"style.about.default": {"icon":"","label":"Restore Default","keywords":"branding","action":"omarchy-branding-about reset"},
|
||||
"style.screensaver.text": {"icon":"","label":"Edit Text","keywords":"branding","action":"omarchy-branding-screensaver text"},
|
||||
"style.screensaver.image": {"icon":"","label":"Set From Image","keywords":"branding","action":"omarchy-branding-screensaver image"},
|
||||
"style.screensaver.default": {"icon":"","label":"Restore Default","keywords":"branding","action":"omarchy-branding-screensaver reset"},
|
||||
"style.install.theme": {"icon":"","label":"Theme","action":"present_terminal omarchy-theme-install"},
|
||||
"style.install.background": {"icon":"","label":"Background","keywords":"wallpaper","action":"omarchy-theme-bg-install"},
|
||||
"style.install.font": {"icon":"","label":"Font"},
|
||||
"style.install.font.cascadia": {"icon":"","label":"Cascadia Mono","action":"install_font 'Cascadia Mono' ttf-cascadia-mono-nerd 'CaskaydiaMono Nerd Font'"},
|
||||
"style.install.font.meslo": {"icon":"","label":"Meslo LG Mono","action":"install_font 'Meslo LG Mono' ttf-meslo-nerd 'MesloLGL Nerd Font'"},
|
||||
"style.install.font.fira": {"icon":"","label":"Fira Code","action":"install_font 'Fira Code' ttf-firacode-nerd 'FiraCode Nerd Font'"},
|
||||
"style.install.font.victor": {"icon":"","label":"Victor Code","action":"install_font 'Victor Code' ttf-victor-mono-nerd 'VictorMono Nerd Font'"},
|
||||
"style.install.font.bitstream": {"icon":"","label":"Bitstream Vera Mono","action":"install_font 'Bitstream Vera Code' ttf-bitstream-vera-mono-nerd 'BitstromWera Nerd Font'"},
|
||||
"style.install.font.iosevka": {"icon":"","label":"Iosevka","action":"install_font Iosevka ttf-iosevka-nerd 'Iosevka Nerd Font Mono'"},
|
||||
|
||||
// Setup
|
||||
"setup.audio": {"icon":"","label":"Audio","keywords":"sound","action":"omarchy-launch-audio"},
|
||||
"setup.wifi": {"icon":"","label":"Wifi","keywords":"wireless network","action":"omarchy-launch-wifi"},
|
||||
"setup.bluetooth": {"icon":"","label":"Bluetooth","action":"omarchy-launch-bluetooth"},
|
||||
"setup.power": {"icon":"","label":"Power Profile","aliases":["power","power-profile","power-profiles"],"keywords":"performance battery","provider":"power-profiles"},
|
||||
"setup.sleep": {"icon":"","label":"System Sleep","keywords":"suspend hibernate"},
|
||||
"setup.sleep.suspend-enable": {"icon":"","label":"Enable Suspend","when":"omarchy-toggle-enabled suspend-off","action":"omarchy-toggle-suspend"},
|
||||
"setup.sleep.suspend-disable": {"icon":"","label":"Disable Suspend","when":"! omarchy-toggle-enabled suspend-off","action":"omarchy-toggle-suspend"},
|
||||
"setup.sleep.hibernate-enable": {"icon":"","label":"Enable Hibernate","when":"! omarchy-hibernation-available","action":"present_terminal omarchy-hibernation-setup"},
|
||||
"setup.sleep.hibernate-disable": {"icon":"","label":"Disable Hibernate","when":"omarchy-hibernation-available","action":"present_terminal omarchy-hibernation-remove"},
|
||||
"setup.monitors": {"icon":"","label":"Monitors","keywords":"monitor display hyprland","action":"open_in_editor \"$(hypr_config_file monitors)\""},
|
||||
"setup.keybindings": {"icon":"","label":"Keybindings","keywords":"keyboard shortcuts","when":"[[ -f $(hypr_config_file bindings) ]]","action":"open_in_editor \"$(hypr_config_file bindings)\""},
|
||||
"setup.input": {"icon":"","label":"Input","keywords":"keyboard touchpad mouse","when":"[[ -f $(hypr_config_file input) ]]","action":"open_in_editor \"$(hypr_config_file input)\""},
|
||||
"setup.default": {"icon":"","label":"Defaults","aliases":["default","defaults"],"keywords":"browser terminal editor"},
|
||||
"setup.default.browser": {"icon":"","label":"Browser"},
|
||||
"setup.default.browser.chromium": {"icon":"","label":"Chromium","when":"omarchy-cmd-present chromium","checked":"default_browser_is chromium","action":"omarchy-default-browser chromium"},
|
||||
"setup.default.browser.chrome": {"icon":"","label":"Chrome","keywords":"google","when":"omarchy-cmd-present google-chrome-stable","checked":"default_browser_is chrome","action":"omarchy-default-browser chrome"},
|
||||
"setup.default.browser.brave": {"icon":"","label":"Brave","when":"omarchy-cmd-present brave","checked":"default_browser_is brave","action":"omarchy-default-browser brave"},
|
||||
"setup.default.browser.brave-origin": {"icon":"","label":"Brave Origin","when":"omarchy-cmd-present brave-origin-beta","checked":"default_browser_is brave-origin","action":"omarchy-default-browser brave-origin"},
|
||||
"setup.default.browser.edge": {"icon":"","label":"Edge","when":"omarchy-cmd-present microsoft-edge-stable","checked":"default_browser_is edge","action":"omarchy-default-browser edge"},
|
||||
"setup.default.browser.firefox": {"icon":"","label":"Firefox","when":"omarchy-cmd-present firefox","checked":"default_browser_is firefox","action":"omarchy-default-browser firefox"},
|
||||
"setup.default.browser.zen": {"icon":"","label":"Zen","when":"omarchy-cmd-present zen-browser","checked":"default_browser_is zen","action":"omarchy-default-browser zen"},
|
||||
"setup.default.terminal": {"icon":"","label":"Terminal"},
|
||||
"setup.default.terminal.alacritty": {"icon":"","label":"Alacritty","when":"omarchy-cmd-present alacritty","checked":"default_terminal_is alacritty","action":"omarchy-default-terminal alacritty"},
|
||||
"setup.default.terminal.foot": {"icon":"","label":"Foot","when":"omarchy-cmd-present foot","checked":"default_terminal_is foot","action":"omarchy-default-terminal foot"},
|
||||
"setup.default.terminal.ghostty": {"icon":"","label":"Ghostty","when":"omarchy-cmd-present ghostty","checked":"default_terminal_is ghostty","action":"omarchy-default-terminal ghostty"},
|
||||
"setup.default.terminal.kitty": {"icon":"","label":"Kitty","when":"omarchy-cmd-present kitty","checked":"default_terminal_is kitty","action":"omarchy-default-terminal kitty"},
|
||||
"setup.default.editor": {"icon":"","label":"Editor"},
|
||||
"setup.default.editor.neovim": {"icon":"","label":"Neovim","keywords":"nvim","when":"omarchy-cmd-present nvim","checked":"default_editor_is nvim","action":"omarchy-default-editor nvim"},
|
||||
"setup.default.editor.vscode": {"icon":"","label":"VSCode","keywords":"code","when":"omarchy-cmd-present code","checked":"default_editor_is code","action":"omarchy-default-editor code"},
|
||||
"setup.default.editor.cursor": {"icon":"","label":"Cursor","when":"omarchy-cmd-present cursor","checked":"default_editor_is cursor","action":"omarchy-default-editor cursor"},
|
||||
"setup.default.editor.zed": {"icon":"","label":"Zed","when":"omarchy-cmd-present zeditor","checked":"default_editor_is zeditor","action":"omarchy-default-editor zed"},
|
||||
"setup.default.editor.sublime": {"icon":"","label":"Sublime Text","when":"omarchy-cmd-present sublime_text","checked":"default_editor_is sublime_text","action":"omarchy-default-editor sublime_text"},
|
||||
"setup.default.editor.helix": {"icon":"","label":"Helix","when":"omarchy-cmd-present helix","checked":"default_editor_is helix","action":"omarchy-default-editor helix"},
|
||||
"setup.default.editor.vim": {"icon":"","label":"Vim","when":"omarchy-cmd-present vim","checked":"default_editor_is vim","action":"omarchy-default-editor vim"},
|
||||
"setup.default.editor.emacs": {"icon":"","label":"Emacs","when":"omarchy-cmd-present emacs","checked":"default_editor_is emacs","action":"omarchy-default-editor emacs"},
|
||||
"setup.dns": {"icon":"","label":"DNS","keywords":"network","action":"present_terminal omarchy-setup-dns"},
|
||||
"setup.security": {"icon":"","label":"Security","keywords":"fingerprint fido2"},
|
||||
"setup.config": {"icon":"","label":"Config","keywords":"files hyprland waybar walker"},
|
||||
"setup.security.fingerprint": {"icon":"","label":"Fingerprint","action":"present_terminal omarchy-setup-security-fingerprint"},
|
||||
"setup.security.fido2": {"icon":"","label":"Fido2","keywords":"key","action":"present_terminal omarchy-setup-security-fido2"},
|
||||
"setup.config.hyprland": {"icon":"","label":"Hyprland","action":"open_in_editor \"$(hypr_config_file hyprland)\""},
|
||||
"setup.config.hypridle": {"icon":"","label":"Hypridle","keywords":"idle","action":"open_in_editor ~/.config/hypr/hypridle.conf && omarchy-restart-hypridle"},
|
||||
"setup.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"lock","action":"open_in_editor ~/.config/hypr/hyprlock.conf"},
|
||||
"setup.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"night light","action":"open_in_editor ~/.config/hypr/hyprsunset.conf && omarchy-restart-hyprsunset"},
|
||||
"setup.config.swayosd": {"icon":"","label":"Swayosd","action":"open_in_editor ~/.config/swayosd/config.toml && omarchy-restart-swayosd"},
|
||||
"setup.config.walker": {"icon":"","label":"Walker","keywords":"launcher","action":"open_in_editor ~/.config/walker/config.toml && omarchy-restart-walker"},
|
||||
"setup.config.waybar": {"icon":"","label":"Waybar","keywords":"bar","action":"open_in_editor ~/.config/waybar/config.jsonc && omarchy-restart-waybar"},
|
||||
"setup.config.xcompose": {"icon":"","label":"XCompose","keywords":"compose key","action":"open_in_editor ~/.XCompose && omarchy-restart-xcompose"},
|
||||
|
||||
// Install
|
||||
"install.package": {"icon":"","label":"Package","keywords":"pacman aur","action":"terminal omarchy-pkg-install"},
|
||||
"install.aur": {"icon":"","label":"AUR","keywords":"package","action":"terminal omarchy-pkg-aur-install"},
|
||||
"install.webapp": {"icon":"","label":"Web App","keywords":"pwa","action":"present_terminal omarchy-webapp-install"},
|
||||
"install.tui": {"icon":"","label":"TUI","keywords":"terminal app","action":"present_terminal omarchy-tui-install"},
|
||||
"install.service": {"icon":"","label":"Service","keywords":"dropbox tailscale vpn"},
|
||||
"install.style": {"icon":"","label":"Style","keywords":"theme background font","target":"style.install"},
|
||||
"install.development": {"icon":"","label":"Development","keywords":"languages programming"},
|
||||
"install.editor": {"icon":"","label":"Editor","keywords":"ide"},
|
||||
"install.terminal": {"icon":"","label":"Terminal","keywords":"emulator"},
|
||||
"install.browser": {"icon":"","label":"Browser","keywords":"web"},
|
||||
"install.ai": {"icon":"","label":"AI","keywords":"dictation ollama lm studio crush"},
|
||||
"install.gaming": {"icon":"","label":"Gaming","keywords":"steam retroarch minecraft lutris heroic"},
|
||||
"install.windows": {"icon":"","label":"Windows","keywords":"vm","action":"present_terminal 'omarchy-windows-vm install'"},
|
||||
"install.browser.chrome": {"icon":"","label":"Chrome","action":"present_terminal 'omarchy-install-browser chrome'"},
|
||||
"install.browser.edge": {"icon":"","label":"Edge","action":"present_terminal 'omarchy-install-browser edge'"},
|
||||
"install.browser.brave": {"icon":"","label":"Brave","action":"present_terminal 'omarchy-install-browser brave'"},
|
||||
"install.browser.brave-origin": {"icon":"","label":"Brave Origin","action":"present_terminal 'omarchy-install-browser brave-origin'"},
|
||||
"install.browser.firefox": {"icon":"","label":"Firefox","action":"present_terminal 'omarchy-install-browser firefox'"},
|
||||
"install.browser.zen": {"icon":"","label":"Zen","action":"present_terminal 'omarchy-install-browser zen'"},
|
||||
"install.service.dropbox": {"icon":"","label":"Dropbox","action":"present_terminal omarchy-install-dropbox"},
|
||||
"install.service.tailscale": {"icon":"","label":"Tailscale","keywords":"vpn","action":"present_terminal omarchy-install-tailscale"},
|
||||
"install.service.nordvpn": {"icon":"","label":"NordVPN [AUR]","keywords":"vpn","action":"present_terminal omarchy-install-nordvpn"},
|
||||
"install.service.once": {"icon":"","label":"ONCE","action":"present_terminal omarchy-install-once"},
|
||||
"install.service.bitwarden": {"icon":"","label":"Bitwarden","keywords":"password","action":"install_and_launch Bitwarden 'bitwarden bitwarden-cli' bitwarden"},
|
||||
"install.service.chromium-account": {"icon":"","label":"Chromium Account","keywords":"google","action":"present_terminal omarchy-install-chromium-google-account"},
|
||||
"install.editor.vscode": {"icon":"","label":"VSCode","keywords":"code","action":"present_terminal omarchy-install-vscode"},
|
||||
"install.editor.cursor": {"icon":"","label":"Cursor","action":"install_and_launch Cursor cursor-bin cursor"},
|
||||
"install.editor.zed": {"icon":"","label":"Zed","action":"present_terminal omarchy-install-zed"},
|
||||
"install.editor.sublime": {"icon":"","label":"Sublime Text","action":"install_and_launch 'Sublime Text' sublime-text-4 sublime_text"},
|
||||
"install.editor.helix": {"icon":"","label":"Helix","action":"present_terminal omarchy-install-helix"},
|
||||
"install.editor.vim": {"icon":"","label":"Vim","action":"install Vim vim"},
|
||||
"install.editor.emacs": {"icon":"","label":"Emacs","action":"install Emacs emacs-wayland && systemctl --user enable --now emacs.service"},
|
||||
"install.terminal.alacritty": {"icon":"","label":"Alacritty","action":"install_terminal alacritty"},
|
||||
"install.terminal.foot": {"icon":"","label":"Foot","action":"install_terminal foot"},
|
||||
"install.terminal.ghostty": {"icon":"","label":"Ghostty","action":"install_terminal ghostty"},
|
||||
"install.terminal.kitty": {"icon":"","label":"Kitty","action":"install_terminal kitty"},
|
||||
"install.ai.dictation": {"icon":"","label":"Dictation","keywords":"voice","action":"present_terminal omarchy-voxtype-install"},
|
||||
"install.ai.lm-studio": {"icon":"","label":"LM Studio","action":"install 'LM Studio' lmstudio-bin"},
|
||||
"install.ai.ollama": {"icon":"","label":"Ollama","action":"if omarchy-cmd-present nvidia-smi; then ollama_pkg=ollama-cuda; elif omarchy-cmd-present rocminfo; then ollama_pkg=ollama-rocm; else ollama_pkg=ollama; fi; install Ollama \"$ollama_pkg\""},
|
||||
"install.ai.crush": {"icon":"","label":"Crush","action":"install Crush crush-bin"},
|
||||
"install.gaming.steam": {"icon":"","label":"Steam","action":"present_terminal omarchy-install-gaming-steam"},
|
||||
"install.gaming.retroarch": {"icon":"","label":"RetroArch","action":"present_terminal omarchy-install-gaming-retroarch"},
|
||||
"install.gaming.minecraft": {"icon":"","label":"Minecraft","action":"install_and_launch Minecraft minecraft-launcher minecraft-launcher"},
|
||||
"install.gaming.geforce-now": {"icon":"","label":"NVIDIA GeForce NOW","action":"present_terminal omarchy-install-gaming-geforce-now"},
|
||||
"install.gaming.xbox-cloud": {"icon":"","label":"Xbox Cloud Gaming","action":"present_terminal omarchy-install-gaming-xbox-cloud"},
|
||||
"install.gaming.xbox-controller": {"icon":"","label":"Xbox Controller","action":"present_terminal omarchy-install-gaming-xbox-controllers"},
|
||||
"install.gaming.moonlight": {"icon":"","label":"Moonlight (GameStream)","action":"present_terminal omarchy-install-gaming-moonlight"},
|
||||
"install.gaming.lutris": {"icon":"","label":"Lutris (Battle.net)","action":"present_terminal omarchy-install-gaming-lutris"},
|
||||
"install.gaming.heroic": {"icon":"","label":"Heroic (Epic Games)","action":"present_terminal omarchy-install-gaming-heroic"},
|
||||
"install.gaming.retro-launcher": {"icon":"","label":"RetroArch Game Launcher","action":"omarchy-games-retro-install"},
|
||||
"install.development.rails": {"icon":"","label":"Ruby on Rails","action":"present_terminal 'omarchy-install-dev-env ruby'"},
|
||||
"install.development.docker-dbs": {"icon":"","label":"Docker DB","keywords":"databases","action":"present_terminal omarchy-install-docker-dbs"},
|
||||
"install.development.javascript": {"icon":"","label":"JavaScript","keywords":"node bun deno"},
|
||||
"install.development.go": {"icon":"","label":"Go","keywords":"golang","action":"present_terminal 'omarchy-install-dev-env go'"},
|
||||
"install.development.php": {"icon":"","label":"PHP","keywords":"laravel symfony"},
|
||||
"install.development.python": {"icon":"","label":"Python","action":"present_terminal 'omarchy-install-dev-env python'"},
|
||||
"install.development.elixir": {"icon":"","label":"Elixir","keywords":"phoenix"},
|
||||
"install.development.zig": {"icon":"","label":"Zig","action":"present_terminal 'omarchy-install-dev-env zig'"},
|
||||
"install.development.rust": {"icon":"","label":"Rust","action":"present_terminal 'omarchy-install-dev-env rust'"},
|
||||
"install.development.java": {"icon":"","label":"Java","action":"present_terminal 'omarchy-install-dev-env java'"},
|
||||
"install.development.dotnet": {"icon":"","label":".NET","action":"present_terminal 'omarchy-install-dev-env dotnet'"},
|
||||
"install.development.ocaml": {"icon":"","label":"OCaml","action":"present_terminal 'omarchy-install-dev-env ocaml'"},
|
||||
"install.development.clojure": {"icon":"","label":"Clojure","action":"present_terminal 'omarchy-install-dev-env clojure'"},
|
||||
"install.development.scala": {"icon":"","label":"Scala","action":"present_terminal 'omarchy-install-dev-env scala'"},
|
||||
"install.development.javascript.node": {"icon":"","label":"Node.js","action":"present_terminal 'omarchy-install-dev-env node'"},
|
||||
"install.development.javascript.bun": {"icon":"","label":"Bun","action":"present_terminal 'omarchy-install-dev-env bun'"},
|
||||
"install.development.javascript.deno": {"icon":"","label":"Deno","action":"present_terminal 'omarchy-install-dev-env deno'"},
|
||||
"install.development.php.php": {"icon":"","label":"PHP","action":"present_terminal 'omarchy-install-dev-env php'"},
|
||||
"install.development.php.laravel": {"icon":"","label":"Laravel","action":"present_terminal 'omarchy-install-dev-env laravel'"},
|
||||
"install.development.php.symfony": {"icon":"","label":"Symfony","action":"present_terminal 'omarchy-install-dev-env symfony'"},
|
||||
"install.development.elixir.elixir": {"icon":"","label":"Elixir","action":"present_terminal 'omarchy-install-dev-env elixir'"},
|
||||
"install.development.elixir.phoenix": {"icon":"","label":"Phoenix","action":"present_terminal 'omarchy-install-dev-env phoenix'"},
|
||||
|
||||
// Remove
|
||||
"remove.package": {"icon":"","label":"Package","keywords":"uninstall","action":"terminal omarchy-pkg-remove"},
|
||||
"remove.webapp": {"icon":"","label":"Web App","keywords":"uninstall","action":"present_terminal omarchy-webapp-remove"},
|
||||
"remove.tui": {"icon":"","label":"TUI","keywords":"uninstall terminal app","action":"present_terminal omarchy-tui-remove"},
|
||||
"remove.development": {"icon":"","label":"Development","keywords":"uninstall languages"},
|
||||
"remove.theme": {"icon":"","label":"Theme","keywords":"uninstall","action":"present_terminal omarchy-theme-remove"},
|
||||
"remove.browser": {"icon":"","label":"Browser","keywords":"uninstall"},
|
||||
"remove.dictation": {"icon":"","label":"Dictation","keywords":"uninstall voice","action":"present_terminal omarchy-voxtype-remove"},
|
||||
"remove.gaming": {"icon":"","label":"Gaming","keywords":"uninstall steam retroarch minecraft"},
|
||||
"remove.windows": {"icon":"","label":"Windows","keywords":"uninstall vm","action":"present_terminal 'omarchy-windows-vm remove'"},
|
||||
"remove.preinstalls": {"icon":"","label":"Preinstalls","action":"present_terminal omarchy-remove-preinstalls"},
|
||||
"remove.security": {"icon":"","label":"Security","keywords":"fingerprint fido2"},
|
||||
"remove.security.fingerprint": {"icon":"","label":"Fingerprint","action":"present_terminal omarchy-remove-security-fingerprint"},
|
||||
"remove.security.fido2": {"icon":"","label":"Fido2","action":"present_terminal omarchy-remove-security-fido2"},
|
||||
"remove.browser.chrome": {"icon":"","label":"Chrome","action":"present_terminal 'omarchy-remove-browser chrome'"},
|
||||
"remove.browser.edge": {"icon":"","label":"Edge","action":"present_terminal 'omarchy-remove-browser edge'"},
|
||||
"remove.browser.brave": {"icon":"","label":"Brave","action":"present_terminal 'omarchy-remove-browser brave'"},
|
||||
"remove.browser.brave-origin": {"icon":"","label":"Brave Origin","action":"present_terminal 'omarchy-remove-browser brave-origin'"},
|
||||
"remove.browser.firefox": {"icon":"","label":"Firefox","action":"present_terminal 'omarchy-remove-browser firefox'"},
|
||||
"remove.browser.zen": {"icon":"","label":"Zen","action":"present_terminal 'omarchy-remove-browser zen'"},
|
||||
"remove.gaming.steam": {"icon":"","label":"Steam","action":"present_terminal omarchy-remove-gaming-steam"},
|
||||
"remove.gaming.retroarch": {"icon":"","label":"RetroArch","action":"present_terminal omarchy-remove-gaming-retroarch"},
|
||||
"remove.gaming.minecraft": {"icon":"","label":"Minecraft","action":"present_terminal omarchy-remove-gaming-minecraft"},
|
||||
"remove.gaming.geforce-now": {"icon":"","label":"NVIDIA GeForce NOW","action":"present_terminal omarchy-remove-gaming-geforce-now"},
|
||||
"remove.gaming.xbox-cloud": {"icon":"","label":"Xbox Cloud Gaming","action":"present_terminal omarchy-remove-gaming-xbox-cloud"},
|
||||
"remove.gaming.xbox-controller": {"icon":"","label":"Xbox Controller ()","action":"present_terminal omarchy-remove-gaming-xbox-controllers"},
|
||||
"remove.gaming.moonlight": {"icon":"","label":"Moonlight (GameStream)","action":"present_terminal omarchy-remove-gaming-moonlight"},
|
||||
"remove.gaming.lutris": {"icon":"","label":"Lutris (Battle.net)","action":"present_terminal omarchy-remove-gaming-lutris"},
|
||||
"remove.gaming.heroic": {"icon":"","label":"Heroic (Epic Games)","action":"present_terminal omarchy-remove-gaming-heroic"},
|
||||
"remove.development.rails": {"icon":"","label":"Ruby on Rails","action":"present_terminal 'omarchy-remove-dev-env ruby'"},
|
||||
"remove.development.javascript": {"icon":"","label":"JavaScript","keywords":"node bun deno"},
|
||||
"remove.development.go": {"icon":"","label":"Go","keywords":"golang","action":"present_terminal 'omarchy-remove-dev-env go'"},
|
||||
"remove.development.php": {"icon":"","label":"PHP","keywords":"laravel symfony"},
|
||||
"remove.development.python": {"icon":"","label":"Python","action":"present_terminal 'omarchy-remove-dev-env python'"},
|
||||
"remove.development.elixir": {"icon":"","label":"Elixir","keywords":"phoenix"},
|
||||
"remove.development.zig": {"icon":"","label":"Zig","action":"present_terminal 'omarchy-remove-dev-env zig'"},
|
||||
"remove.development.rust": {"icon":"","label":"Rust","action":"present_terminal 'omarchy-remove-dev-env rust'"},
|
||||
"remove.development.java": {"icon":"","label":"Java","action":"present_terminal 'omarchy-remove-dev-env java'"},
|
||||
"remove.development.dotnet": {"icon":"","label":".NET","action":"present_terminal 'omarchy-remove-dev-env dotnet'"},
|
||||
"remove.development.ocaml": {"icon":"","label":"OCaml","action":"present_terminal 'omarchy-remove-dev-env ocaml'"},
|
||||
"remove.development.clojure": {"icon":"","label":"Clojure","action":"present_terminal 'omarchy-remove-dev-env clojure'"},
|
||||
"remove.development.scala": {"icon":"","label":"Scala","action":"present_terminal 'omarchy-remove-dev-env scala'"},
|
||||
"remove.development.javascript.node": {"icon":"","label":"Node.js","action":"present_terminal 'omarchy-remove-dev-env node'"},
|
||||
"remove.development.javascript.bun": {"icon":"","label":"Bun","action":"present_terminal 'omarchy-remove-dev-env bun'"},
|
||||
"remove.development.javascript.deno": {"icon":"","label":"Deno","action":"present_terminal 'omarchy-remove-dev-env deno'"},
|
||||
"remove.development.php.php": {"icon":"","label":"PHP","action":"present_terminal 'omarchy-remove-dev-env php'"},
|
||||
"remove.development.php.laravel": {"icon":"","label":"Laravel","action":"present_terminal 'omarchy-remove-dev-env laravel'"},
|
||||
"remove.development.php.symfony": {"icon":"","label":"Symfony","action":"present_terminal 'omarchy-remove-dev-env symfony'"},
|
||||
"remove.development.elixir.elixir": {"icon":"","label":"Elixir","action":"present_terminal 'omarchy-remove-dev-env elixir'"},
|
||||
"remove.development.elixir.phoenix": {"icon":"","label":"Phoenix","action":"present_terminal 'omarchy-remove-dev-env phoenix'"},
|
||||
|
||||
// Update
|
||||
"update.omarchy": {"icon":"","label":"Omarchy","keywords":"system","action":"present_terminal omarchy-update"},
|
||||
"update.channel": {"icon":"","label":"Channel","keywords":"stable rc edge dev"},
|
||||
"update.config": {"icon":"","label":"Config","keywords":"refresh default"},
|
||||
"update.themes": {"icon":"","label":"Extra Themes","action":"present_terminal omarchy-theme-update"},
|
||||
"update.process": {"icon":"","label":"Process","keywords":"restart services"},
|
||||
"update.hardware": {"icon":"","label":"Hardware","keywords":"restart audio wifi bluetooth trackpad"},
|
||||
"update.firmware": {"icon":"","label":"Firmware","keywords":"fwupd","action":"present_terminal omarchy-update-firmware"},
|
||||
"update.password": {"icon":"","label":"Password","keywords":"drive user"},
|
||||
"update.timezone": {"icon":"","label":"Timezone","keywords":"time zone","action":"present_terminal omarchy-tz-select"},
|
||||
"update.time": {"icon":"","label":"Time","keywords":"clock ntp","action":"present_terminal omarchy-update-time"},
|
||||
"update.channel.stable": {"icon":"🟢","label":"Stable","action":"present_terminal 'omarchy-channel-set stable'"},
|
||||
"update.channel.rc": {"icon":"🟡","label":"RC","keywords":"release candidate","action":"present_terminal 'omarchy-channel-set rc'"},
|
||||
"update.channel.edge": {"icon":"🟠","label":"Edge","action":"present_terminal 'omarchy-channel-set edge'"},
|
||||
"update.channel.dev": {"icon":"🔴","label":"Dev","keywords":"development","action":"present_terminal 'omarchy-channel-set dev'"},
|
||||
"update.process.hypridle": {"icon":"","label":"Hypridle","keywords":"restart","action":"omarchy-restart-hypridle"},
|
||||
"update.process.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"restart","action":"omarchy-restart-hyprsunset"},
|
||||
"update.process.mako": {"icon":"","label":"Mako","keywords":"restart notifications","action":"omarchy-restart-mako"},
|
||||
"update.process.swayosd": {"icon":"","label":"Swayosd","keywords":"restart","action":"omarchy-restart-swayosd"},
|
||||
"update.process.walker": {"icon":"","label":"Walker","keywords":"restart launcher","action":"omarchy-restart-walker"},
|
||||
"update.process.waybar": {"icon":"","label":"Waybar","keywords":"restart","action":"omarchy-restart-waybar"},
|
||||
"update.config.hyprland": {"icon":"","label":"Hyprland","keywords":"refresh","action":"present_terminal omarchy-refresh-hyprland"},
|
||||
"update.config.hypridle": {"icon":"","label":"Hypridle","keywords":"refresh","action":"present_terminal omarchy-refresh-hypridle"},
|
||||
"update.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"refresh","action":"present_terminal omarchy-refresh-hyprlock"},
|
||||
"update.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"refresh","action":"present_terminal omarchy-refresh-hyprsunset"},
|
||||
"update.config.plymouth": {"icon":"","label":"Plymouth","keywords":"refresh","action":"present_terminal omarchy-refresh-plymouth"},
|
||||
"update.config.swayosd": {"icon":"","label":"Swayosd","keywords":"refresh","action":"present_terminal omarchy-refresh-swayosd"},
|
||||
"update.config.tmux": {"icon":"","label":"Tmux","keywords":"refresh","action":"present_terminal omarchy-refresh-tmux"},
|
||||
"update.config.walker": {"icon":"","label":"Walker","keywords":"refresh","action":"present_terminal omarchy-refresh-walker"},
|
||||
"update.config.waybar": {"icon":"","label":"Waybar","keywords":"refresh","action":"present_terminal omarchy-refresh-waybar"},
|
||||
"update.hardware.audio": {"icon":"","label":"Audio","keywords":"restart pipewire","action":"present_terminal omarchy-restart-pipewire"},
|
||||
"update.hardware.wifi": {"icon":"","label":"Wi-Fi","keywords":"restart wireless","action":"present_terminal omarchy-restart-wifi"},
|
||||
"update.hardware.bluetooth": {"icon":"","label":"Bluetooth","keywords":"restart","action":"present_terminal omarchy-restart-bluetooth"},
|
||||
"update.hardware.trackpad": {"icon":"","label":"Trackpad","keywords":"restart touchpad","action":"present_terminal omarchy-restart-trackpad"},
|
||||
"update.password.drive": {"icon":"","label":"Drive Encryption","action":"present_terminal omarchy-drive-password"},
|
||||
"update.password.user": {"icon":"","label":"User","keywords":"passwd","action":"present_terminal passwd"},
|
||||
}
|
||||
@@ -0,0 +1,892 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
|
||||
ShellRoot {
|
||||
id: root
|
||||
|
||||
property string socketPath: (Quickshell.env("XDG_RUNTIME_DIR") || ("/run/user/" + Quickshell.env("UID"))) + "/omarchy-menu.sock"
|
||||
property string startupMenuJsonFile: Quickshell.env("OMARCHY_MENU_JSON_FILE") || ""
|
||||
property string menuBin: Quickshell.env("OMARCHY_MENU_BIN") || "omarchy-menu"
|
||||
property string startupInitialMenu: Quickshell.env("OMARCHY_MENU_INITIAL_MENU") || "root"
|
||||
property string startupSelectionFile: Quickshell.env("OMARCHY_MENU_SELECTION_FILE") || ""
|
||||
property string startupDoneFile: Quickshell.env("OMARCHY_MENU_DONE_FILE") || ""
|
||||
property string startupColorsRaw: Quickshell.env("OMARCHY_MENU_COLORS_RAW") || ""
|
||||
property string fontFamily: Quickshell.env("OMARCHY_MENU_FONT") || "monospace"
|
||||
property string colorsFile: Quickshell.env("OMARCHY_MENU_COLORS_FILE") || (Quickshell.env("HOME") + "/.config/omarchy/current/theme/menu.json")
|
||||
property string styleFile: Quickshell.env("OMARCHY_MENU_STYLE_FILE") || (Quickshell.env("HOME") + "/.local/state/omarchy/toggles/quickshell-menu.json")
|
||||
property string selectionFile: ""
|
||||
property string doneFile: ""
|
||||
property bool requestActive: false
|
||||
property bool opened: false
|
||||
property bool rowsLoaded: false
|
||||
property string activeMenu: "root"
|
||||
property string filterText: ""
|
||||
property int selectedIndex: 0
|
||||
property int requestSerial: 0
|
||||
property int applySerial: 0
|
||||
property var items: ({})
|
||||
property var itemOrder: []
|
||||
property var navStack: []
|
||||
property var providersLoaded: ({})
|
||||
property var providerQueue: []
|
||||
property var doneFilesToRelease: []
|
||||
property color accent: "#89b4fa"
|
||||
property color background: "#101315"
|
||||
property color foreground: "#cacccc"
|
||||
property color border: foreground
|
||||
property int cornerRadius: 0
|
||||
property int contentMargin: 18
|
||||
property int headerHeight: 34
|
||||
property int contentSpacing: 6
|
||||
property int baseRowHeight: 50
|
||||
property int detailRowHeight: 58
|
||||
property int rowSpacing: 3
|
||||
property int dividerHeight: 17
|
||||
property bool searchDivider: false
|
||||
property int layoutSerial: 0
|
||||
property int cardWidth: Math.min(300, panel.width - 48)
|
||||
property int visibleRowsHeight: rowListHeight(layoutSerial, displayModel.count, filterText, searchDivider)
|
||||
property int cardHeight: Math.min(Math.max(220, contentMargin * 2 + headerHeight + contentSpacing + visibleRowsHeight), panel.height - 48)
|
||||
|
||||
function shellQuote(value) {
|
||||
return "'" + String(value).replace(/'/g, "'\\''") + "'"
|
||||
}
|
||||
|
||||
function decodeField(value) {
|
||||
return String(value || "").replace(/\v/g, "\n").replace(/\f/g, "\t")
|
||||
}
|
||||
|
||||
function withAlpha(color, alpha) {
|
||||
return Qt.rgba(color.r, color.g, color.b, alpha)
|
||||
}
|
||||
|
||||
function rowHeightForDetail(detail) {
|
||||
return root.filterText && detail ? root.detailRowHeight : root.baseRowHeight
|
||||
}
|
||||
|
||||
function rowListHeight(_serial, _count, _filter, _divider) {
|
||||
if (displayModel.count === 0) return root.baseRowHeight
|
||||
|
||||
var count = Math.min(displayModel.count, 10)
|
||||
var total = 0
|
||||
var previousSection = ""
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
var row = displayModel.get(i)
|
||||
if (i > 0) total += root.rowSpacing
|
||||
if (row.section === "drilldown" && previousSection !== "drilldown") total += root.dividerHeight
|
||||
total += root.rowHeightForDetail(row.detail)
|
||||
previousSection = row.section
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
function item(id) {
|
||||
return root.items[id] || null
|
||||
}
|
||||
|
||||
function loadMenuJson(raw) {
|
||||
var nextItems = ({})
|
||||
var nextOrder = []
|
||||
var payload = JSON.parse(raw || "{}")
|
||||
var rows = payload.items || []
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var entry = rows[i]
|
||||
var id = entry.id || ""
|
||||
if (!id) continue
|
||||
|
||||
var order = nextItems[id] ? nextItems[id].order : nextOrder.length
|
||||
if (!nextItems[id]) nextOrder.push(id)
|
||||
|
||||
nextItems[id] = {
|
||||
id: id,
|
||||
parent: entry.parent || "",
|
||||
kind: entry.kind || "action",
|
||||
icon: entry.icon || "",
|
||||
label: entry.label || id,
|
||||
target: entry.target || "",
|
||||
keywords: entry.keywords || "",
|
||||
description: entry.description || "",
|
||||
action: entry.action || "",
|
||||
provider: entry.provider || "",
|
||||
order: order
|
||||
}
|
||||
}
|
||||
|
||||
if (!nextItems.root) {
|
||||
nextItems.root = { id: "root", parent: "", kind: "menu", icon: "", label: "Go", target: "", keywords: "", description: "", order: -1 }
|
||||
}
|
||||
|
||||
root.items = nextItems
|
||||
root.itemOrder = nextOrder
|
||||
root.rowsLoaded = true
|
||||
}
|
||||
|
||||
function mergeProviderJson(raw, menuId) {
|
||||
var payload = ({})
|
||||
try {
|
||||
payload = JSON.parse(raw || "{}")
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
|
||||
var rows = payload.items || []
|
||||
var changed = false
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var entry = rows[i]
|
||||
var id = entry.id || ""
|
||||
if (!id) continue
|
||||
|
||||
if (!root.items[id]) root.itemOrder.push(id)
|
||||
root.items[id] = {
|
||||
id: id,
|
||||
parent: entry.parent || menuId,
|
||||
kind: entry.kind || "action",
|
||||
icon: entry.icon || "",
|
||||
label: entry.label || id,
|
||||
target: entry.target || "",
|
||||
keywords: entry.keywords || "",
|
||||
description: entry.description || "",
|
||||
action: entry.action || "",
|
||||
provider: entry.provider || "",
|
||||
order: root.itemOrder.indexOf(id)
|
||||
}
|
||||
changed = true
|
||||
}
|
||||
|
||||
if (changed) root.rebuildDisplay()
|
||||
}
|
||||
|
||||
function startProviderForMenu(id) {
|
||||
var entry = root.item(id)
|
||||
if (!entry || !entry.provider || root.providersLoaded[id]) return
|
||||
|
||||
root.providersLoaded[id] = true
|
||||
providerProc.menuId = id
|
||||
providerProc.output = ""
|
||||
providerProc.command = [root.menuBin, "--provider", entry.provider, id]
|
||||
providerProc.running = true
|
||||
}
|
||||
|
||||
function startNextProvider() {
|
||||
if (providerProc.running) return
|
||||
|
||||
while (root.providerQueue.length > 0) {
|
||||
var id = root.providerQueue.shift()
|
||||
var entry = root.item(id)
|
||||
if (!entry || !entry.provider || root.providersLoaded[id]) continue
|
||||
|
||||
root.startProviderForMenu(id)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function loadProviderForMenu(id) {
|
||||
var entry = root.item(id)
|
||||
if (!entry || !entry.provider || root.providersLoaded[id]) return
|
||||
|
||||
if (providerProc.running) {
|
||||
if (root.providerQueue.indexOf(id) < 0) root.providerQueue = root.providerQueue.concat([id])
|
||||
return
|
||||
}
|
||||
|
||||
root.startProviderForMenu(id)
|
||||
}
|
||||
|
||||
function loadProvidersForSearch() {
|
||||
var active = root.item(root.activeMenu) ? root.activeMenu : "root"
|
||||
|
||||
for (var i = 0; i < root.itemOrder.length; i++) {
|
||||
var entry = root.item(root.itemOrder[i])
|
||||
if (!entry || !entry.provider || root.providersLoaded[entry.id]) continue
|
||||
if (active !== "root" && entry.id !== active && !root.isDescendantOf(entry.id, active)) continue
|
||||
|
||||
root.loadProviderForMenu(entry.id)
|
||||
}
|
||||
}
|
||||
|
||||
function depthFor(id) {
|
||||
var depth = 0
|
||||
var current = root.item(id)
|
||||
var guard = 0
|
||||
|
||||
while (current && current.parent && current.parent !== "root" && guard < 32) {
|
||||
depth += 1
|
||||
current = root.item(current.parent)
|
||||
guard += 1
|
||||
}
|
||||
|
||||
return depth
|
||||
}
|
||||
|
||||
function pathFor(id) {
|
||||
var labels = []
|
||||
var current = root.item(id)
|
||||
var guard = 0
|
||||
|
||||
while (current && current.id !== "root" && guard < 32) {
|
||||
labels.unshift(current.label)
|
||||
current = root.item(current.parent)
|
||||
guard += 1
|
||||
}
|
||||
|
||||
return labels.join(" › ")
|
||||
}
|
||||
|
||||
function parentPathFor(id) {
|
||||
var entry = root.item(id)
|
||||
if (!entry || !entry.parent || entry.parent === "root") return ""
|
||||
|
||||
return root.pathFor(entry.parent)
|
||||
}
|
||||
|
||||
function breadcrumbFor(id) {
|
||||
var path = root.pathFor(id)
|
||||
return path ? ("Go › " + path) : "Go"
|
||||
}
|
||||
|
||||
function isDescendantOf(id, ancestorId) {
|
||||
if (ancestorId === "root") return id !== "root"
|
||||
|
||||
var current = root.item(id)
|
||||
var guard = 0
|
||||
while (current && current.parent && guard < 32) {
|
||||
if (current.parent === ancestorId) return true
|
||||
current = root.item(current.parent)
|
||||
guard += 1
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function childCount(id) {
|
||||
var count = 0
|
||||
for (var i = 0; i < root.itemOrder.length; i++) {
|
||||
var entry = root.item(root.itemOrder[i])
|
||||
if (entry && entry.parent === id) count += 1
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
function matchesQuery(entry, query) {
|
||||
if (!entry || entry.id === "root") return false
|
||||
|
||||
var haystack = (entry.label + " " + root.pathFor(entry.id) + " " + entry.keywords + " " + entry.description).toLowerCase()
|
||||
var terms = query.toLowerCase().trim().split(/\s+/)
|
||||
|
||||
for (var i = 0; i < terms.length; i++) {
|
||||
if (terms[i] && haystack.indexOf(terms[i]) === -1) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function searchScore(entry, query) {
|
||||
var needle = query.toLowerCase().trim()
|
||||
var label = entry.label.toLowerCase()
|
||||
var path = root.pathFor(entry.id).toLowerCase()
|
||||
var keywords = entry.keywords.toLowerCase()
|
||||
var parent = root.item(entry.parent)
|
||||
var parentLabel = parent ? parent.label.toLowerCase() : ""
|
||||
var score = 80
|
||||
|
||||
if (label === needle) score = entry.parent === "root" ? 2 : 0
|
||||
else if (label.indexOf(needle) === 0) score = 10
|
||||
else if (path.indexOf(needle) === 0) score = entry.kind === "action" ? 12 : 14
|
||||
else if (parentLabel === needle) score = entry.kind === "action" ? 18 : 20
|
||||
else if (label.indexOf(needle) >= 0) score = 30
|
||||
else if (path.indexOf(needle) >= 0) score = 40
|
||||
else if (keywords.indexOf(needle) >= 0) score = 50
|
||||
|
||||
if (entry.kind === "menu" || entry.kind === "link") score -= 2
|
||||
|
||||
return score * 1000 + root.depthFor(entry.id) * 25 + entry.order
|
||||
}
|
||||
|
||||
function displayRow(entry, detail, score, section) {
|
||||
var target = entry.kind === "link" ? entry.target : entry.id
|
||||
return {
|
||||
itemId: entry.id,
|
||||
kind: entry.kind,
|
||||
icon: entry.icon,
|
||||
label: entry.label,
|
||||
target: target,
|
||||
detail: detail || "",
|
||||
path: root.pathFor(entry.id),
|
||||
childCount: (entry.kind === "menu" || entry.kind === "link") ? root.childCount(target) : 0,
|
||||
action: entry.action || "",
|
||||
provider: entry.provider || "",
|
||||
score: score || 0,
|
||||
section: section || ""
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildDisplay() {
|
||||
displayModel.clear()
|
||||
|
||||
if (!root.rowsLoaded) return
|
||||
|
||||
var active = root.item(root.activeMenu) ? root.activeMenu : "root"
|
||||
root.activeMenu = active
|
||||
var rows = []
|
||||
var query = root.filterText.trim()
|
||||
root.searchDivider = false
|
||||
|
||||
if (query) {
|
||||
var currentRows = []
|
||||
var drilldownRows = []
|
||||
|
||||
for (var i = 0; i < root.itemOrder.length; i++) {
|
||||
var entry = root.item(root.itemOrder[i])
|
||||
if (!entry || entry.id === "root") continue
|
||||
if (!root.isDescendantOf(entry.id, active)) continue
|
||||
if (!root.matchesQuery(entry, query)) continue
|
||||
|
||||
var detail = root.parentPathFor(entry.id)
|
||||
var row = root.displayRow(entry, detail, root.searchScore(entry, query))
|
||||
if (entry.parent === active) currentRows.push(row)
|
||||
else drilldownRows.push(row)
|
||||
}
|
||||
|
||||
var searchSort = function(a, b) {
|
||||
if (a.score !== b.score) return a.score - b.score
|
||||
return a.path.localeCompare(b.path)
|
||||
}
|
||||
|
||||
currentRows.sort(searchSort)
|
||||
drilldownRows.sort(searchSort)
|
||||
root.searchDivider = currentRows.length > 0 && drilldownRows.length > 0
|
||||
if (root.searchDivider) {
|
||||
for (var d = 0; d < drilldownRows.length; d++) drilldownRows[d].section = "drilldown"
|
||||
}
|
||||
rows = currentRows.concat(drilldownRows)
|
||||
} else {
|
||||
if (active !== "root") {
|
||||
var parentTarget = root.item(active).parent || "root"
|
||||
var backTarget = root.navStack.length > 0 ? root.navStack[root.navStack.length - 1] : parentTarget
|
||||
rows.push({ itemId: "__back", kind: "back", icon: "", label: "Back", target: backTarget, detail: root.breadcrumbFor(backTarget), path: "", childCount: 0, action: "", score: -1, section: "" })
|
||||
}
|
||||
|
||||
for (var j = 0; j < root.itemOrder.length; j++) {
|
||||
var child = root.item(root.itemOrder[j])
|
||||
if (!child || child.parent !== active) continue
|
||||
rows.push(root.displayRow(child, child.description, child.order))
|
||||
}
|
||||
}
|
||||
|
||||
for (var k = 0; k < rows.length; k++) displayModel.append(rows[k])
|
||||
layoutSerial += 1
|
||||
|
||||
if (displayModel.count === 0) selectedIndex = 0
|
||||
else if (selectedIndex >= displayModel.count) selectedIndex = displayModel.count - 1
|
||||
else if (selectedIndex < 0) selectedIndex = 0
|
||||
|
||||
Qt.callLater(function() {
|
||||
if (displayModel.count > 0) resultList.positionViewAtIndex(root.selectedIndex, ListView.Contain)
|
||||
})
|
||||
}
|
||||
|
||||
function select(delta) {
|
||||
if (displayModel.count === 0) return
|
||||
|
||||
selectedIndex += delta
|
||||
if (selectedIndex < 0) selectedIndex = 0
|
||||
if (selectedIndex >= displayModel.count) selectedIndex = displayModel.count - 1
|
||||
resultList.positionViewAtIndex(selectedIndex, ListView.Contain)
|
||||
}
|
||||
|
||||
function setFilter(nextFilter) {
|
||||
root.filterText = nextFilter
|
||||
root.selectedIndex = 0
|
||||
if (root.filterText.trim()) root.loadProvidersForSearch()
|
||||
root.rebuildDisplay()
|
||||
}
|
||||
|
||||
function setActiveMenu(id, pushHistory) {
|
||||
if (!root.item(id)) id = "root"
|
||||
if (pushHistory && id !== root.activeMenu) root.navStack = root.navStack.concat([root.activeMenu])
|
||||
root.activeMenu = id
|
||||
root.filterText = ""
|
||||
root.selectedIndex = 0
|
||||
root.rebuildDisplay()
|
||||
root.loadProviderForMenu(id)
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (root.activeMenu === "root") return false
|
||||
|
||||
if (root.navStack.length > 0) {
|
||||
var previous = root.navStack[root.navStack.length - 1]
|
||||
root.navStack = root.navStack.slice(0, root.navStack.length - 1)
|
||||
root.setActiveMenu(previous, false)
|
||||
return true
|
||||
}
|
||||
|
||||
var active = root.item(root.activeMenu)
|
||||
root.setActiveMenu((active && active.parent) ? active.parent : "root", false)
|
||||
return true
|
||||
}
|
||||
|
||||
function activateIndex(index) {
|
||||
if (index < 0 || index >= displayModel.count) return
|
||||
|
||||
var row = displayModel.get(index)
|
||||
if (row.kind === "back") {
|
||||
root.goBack()
|
||||
} else if (row.kind === "menu" || row.kind === "link") {
|
||||
root.setActiveMenu(row.target || row.itemId, true)
|
||||
} else {
|
||||
root.applySelected(row.itemId, row.action)
|
||||
}
|
||||
}
|
||||
|
||||
function releaseNextDoneFile() {
|
||||
if (releaseProc.running || doneFilesToRelease.length === 0) return
|
||||
|
||||
var path = doneFilesToRelease.shift()
|
||||
releaseProc.command = ["bash", "-lc", ": > " + shellQuote(path)]
|
||||
releaseProc.running = true
|
||||
}
|
||||
|
||||
function finishDoneFile(path) {
|
||||
if (!path) return
|
||||
doneFilesToRelease.push(path)
|
||||
releaseNextDoneFile()
|
||||
}
|
||||
|
||||
function resetRequest() {
|
||||
requestActive = false
|
||||
selectionFile = ""
|
||||
doneFile = ""
|
||||
}
|
||||
|
||||
function applySelected(id, action) {
|
||||
if (!id || !selectionFile || !doneFile) {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
|
||||
var activeSelectionFile = selectionFile
|
||||
var activeDoneFile = doneFile
|
||||
applySerial = requestSerial
|
||||
resetRequest()
|
||||
opened = false
|
||||
|
||||
applyProc.command = ["bash", "-lc", "printf '%s\\t%s\\n' " + shellQuote(id) + " " + shellQuote(action || "") + " > " + shellQuote(activeSelectionFile) + "; : > " + shellQuote(activeDoneFile)]
|
||||
applyProc.running = true
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (requestActive) finishDoneFile(doneFile)
|
||||
resetRequest()
|
||||
opened = false
|
||||
filterText = ""
|
||||
}
|
||||
|
||||
function closeMenu(nextDoneFile) {
|
||||
requestSerial += 1
|
||||
|
||||
if (requestActive) finishDoneFile(doneFile)
|
||||
if (nextDoneFile && nextDoneFile !== doneFile) finishDoneFile(nextDoneFile)
|
||||
|
||||
resetRequest()
|
||||
opened = false
|
||||
filterText = ""
|
||||
}
|
||||
|
||||
function openExistingMenu(initialMenu, nextSelectionFile, nextDoneFile) {
|
||||
requestSerial += 1
|
||||
|
||||
if (requestActive && doneFile && doneFile !== nextDoneFile) finishDoneFile(doneFile)
|
||||
|
||||
selectionFile = nextSelectionFile
|
||||
doneFile = nextDoneFile
|
||||
requestActive = !!doneFile
|
||||
activeMenu = root.item(initialMenu) ? initialMenu : "root"
|
||||
navStack = []
|
||||
filterText = ""
|
||||
selectedIndex = 0
|
||||
opened = true
|
||||
rebuildDisplay()
|
||||
loadProviderForMenu(activeMenu)
|
||||
|
||||
Qt.callLater(function() { keyCatcher.forceActiveFocus() })
|
||||
}
|
||||
|
||||
function openMenu(menuJson, initialMenu, nextSelectionFile, nextDoneFile, colorsRaw) {
|
||||
loadMenuJson(menuJson)
|
||||
if (colorsRaw) loadColors(colorsRaw)
|
||||
providersLoaded = ({})
|
||||
providerQueue = []
|
||||
openExistingMenu(initialMenu, nextSelectionFile, nextDoneFile)
|
||||
}
|
||||
|
||||
function loadColors(raw) {
|
||||
try {
|
||||
var colors = JSON.parse(raw || "{}")
|
||||
root.accent = colors.accent || colors.primary || root.accent
|
||||
root.background = colors.background || root.background
|
||||
root.foreground = colors.foreground || colors.backgroundText || root.foreground
|
||||
root.border = colors.border || root.foreground
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function loadStyle(raw) {
|
||||
try {
|
||||
var style = JSON.parse(raw || "{}")
|
||||
root.cornerRadius = Number(style.radius || 0)
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
ListModel { id: displayModel }
|
||||
|
||||
Process {
|
||||
id: providerProc
|
||||
property string menuId: ""
|
||||
property string output: ""
|
||||
stdout: SplitParser {
|
||||
onRead: function(data) {
|
||||
providerProc.output += data + "\n"
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
root.mergeProviderJson(output, menuId)
|
||||
if (root.filterText.trim()) root.loadProvidersForSearch()
|
||||
root.startNextProvider()
|
||||
}
|
||||
}
|
||||
|
||||
SocketServer {
|
||||
active: true
|
||||
path: root.socketPath
|
||||
|
||||
handler: Socket {
|
||||
id: clientSocket
|
||||
parser: SplitParser {
|
||||
onRead: function(message) {
|
||||
var fields = message.split("\t")
|
||||
if (fields[0] === "open") {
|
||||
root.openExistingMenu(fields[1] || "root", fields[2] || "", fields[3] || "")
|
||||
} else {
|
||||
root.closeMenu(fields[3] || "")
|
||||
}
|
||||
clientSocket.connected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileView {
|
||||
path: root.startupMenuJsonFile
|
||||
onLoaded: root.openMenu(text(), root.startupInitialMenu, root.startupSelectionFile, root.startupDoneFile, root.decodeField(root.startupColorsRaw))
|
||||
}
|
||||
|
||||
FileView {
|
||||
path: root.colorsFile
|
||||
watchChanges: true
|
||||
onLoaded: root.loadColors(text())
|
||||
onFileChanged: { reload(); root.loadColors(text()) }
|
||||
}
|
||||
|
||||
FileView {
|
||||
path: root.styleFile
|
||||
watchChanges: true
|
||||
onLoaded: root.loadStyle(text())
|
||||
onFileChanged: { reload(); root.loadStyle(text()) }
|
||||
}
|
||||
|
||||
Process {
|
||||
id: applyProc
|
||||
onExited: {
|
||||
if (root.applySerial === root.requestSerial) root.opened = false
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: releaseProc
|
||||
onExited: root.releaseNextDoneFile()
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: panel
|
||||
visible: root.opened && root.rowsLoaded
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
WlrLayershell.namespace: "omarchy-menu"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: root.cancel()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
width: root.cardWidth
|
||||
height: root.cardHeight
|
||||
radius: root.cornerRadius
|
||||
anchors.centerIn: parent
|
||||
color: root.background
|
||||
border.color: root.withAlpha(root.border, 0.36)
|
||||
border.width: 1
|
||||
|
||||
MouseArea { anchors.fill: parent; onClicked: {} }
|
||||
|
||||
Item {
|
||||
id: keyCatcher
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
|
||||
Keys.priority: Keys.BeforeItem
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
if (root.filterText) root.setFilter("")
|
||||
else root.cancel()
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_Backspace) {
|
||||
if (root.filterText.length > 0) root.setFilter(root.filterText.slice(0, -1))
|
||||
else root.goBack()
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_Up) {
|
||||
root.select(-1)
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_Down) {
|
||||
root.select(1)
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_PageUp) {
|
||||
root.select(-6)
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_PageDown) {
|
||||
root.select(6)
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_Left) {
|
||||
if (!root.filterText) root.goBack()
|
||||
event.accepted = true
|
||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_Right) {
|
||||
root.activateIndex(root.selectedIndex)
|
||||
event.accepted = true
|
||||
} else if (event.text && event.text.length === 1 && event.text.charCodeAt(0) >= 32 && event.text.charCodeAt(0) !== 127 && (event.modifiers === Qt.NoModifier || event.modifiers === Qt.ShiftModifier)) {
|
||||
root.setFilter(root.filterText + event.text)
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.contentMargin
|
||||
spacing: root.contentSpacing
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: root.headerHeight
|
||||
radius: root.cornerRadius
|
||||
color: "transparent"
|
||||
border.width: 0
|
||||
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.filterText || ((root.item(root.activeMenu) ? root.item(root.activeMenu).label : "Go") + "…")
|
||||
color: root.foreground
|
||||
opacity: root.filterText ? 1 : 0.58
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 16
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: root.visibleRowsHeight
|
||||
|
||||
ListView {
|
||||
id: resultList
|
||||
anchors.fill: parent
|
||||
model: displayModel
|
||||
clip: true
|
||||
spacing: root.rowSpacing
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
section.property: "section"
|
||||
section.criteria: ViewSection.FullString
|
||||
section.delegate: Item {
|
||||
required property string section
|
||||
|
||||
width: ListView.view.width
|
||||
height: section === "drilldown" ? root.dividerHeight : 0
|
||||
visible: section === "drilldown"
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 4
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: 1
|
||||
color: root.withAlpha(root.foreground, 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
id: row
|
||||
required property int index
|
||||
required property string itemId
|
||||
required property string kind
|
||||
required property string icon
|
||||
required property string label
|
||||
required property string target
|
||||
required property string detail
|
||||
required property string path
|
||||
required property string action
|
||||
required property int childCount
|
||||
|
||||
width: ListView.view.width
|
||||
height: root.rowHeightForDetail(row.detail)
|
||||
radius: root.cornerRadius
|
||||
color: index === root.selectedIndex ? root.withAlpha(root.foreground, 0.08) : root.withAlpha(root.foreground, mouseArea.containsMouse ? 0.045 : 0)
|
||||
border.color: "transparent"
|
||||
border.width: 0
|
||||
|
||||
Rectangle {
|
||||
visible: false
|
||||
width: 4
|
||||
height: parent.height - 18
|
||||
radius: Math.min(root.cornerRadius, 4)
|
||||
color: root.accent
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
id: iconText
|
||||
text: row.icon
|
||||
color: index === root.selectedIndex ? root.accent : root.foreground
|
||||
opacity: row.kind === "back" ? 0.7 : 1
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 18
|
||||
width: 36
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 8
|
||||
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
||||
}
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
anchors.left: iconText.right
|
||||
anchors.leftMargin: 6
|
||||
anchors.right: trail.left
|
||||
anchors.rightMargin: 6
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 3
|
||||
|
||||
Text {
|
||||
id: labelText
|
||||
width: parent.width
|
||||
text: row.label
|
||||
color: index === root.selectedIndex ? root.accent : root.foreground
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
text: row.detail
|
||||
visible: root.filterText && row.detail.length > 0
|
||||
color: root.foreground
|
||||
opacity: 0.52
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 11
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: trail
|
||||
width: 14
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
y: contentColumn.y + labelText.y + (labelText.height - height) / 2
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
visible: false
|
||||
text: row.childCount
|
||||
color: root.foreground
|
||||
opacity: 0.45
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: row.kind === "menu" || row.kind === "link" ? "›" : (row.kind === "back" ? "" : "↵")
|
||||
color: index === root.selectedIndex ? root.accent : root.foreground
|
||||
opacity: row.kind === "back" ? 0 : 0.36
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.weight: Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.activateIndex(row.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 8
|
||||
visible: displayModel.count === 0
|
||||
|
||||
Text {
|
||||
text: ""
|
||||
color: root.accent
|
||||
opacity: 0.8
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 28
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
width: 320
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.filterText ? "No matches for “" + root.filterText + "”" : "Nothing here yet"
|
||||
color: root.foreground
|
||||
opacity: 0.7
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: 14
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
width: 320
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"accent": "{{ accent }}",
|
||||
"background": "{{ background }}",
|
||||
"foreground": "{{ foreground }}",
|
||||
"border": "{{ foreground }}"
|
||||
}
|
||||
@@ -37,7 +37,7 @@ for conf_toggle in "$toggle_state_dir"/*.conf; do
|
||||
|
||||
if [[ ! -f $lua_toggle ]]; then
|
||||
case "$toggle_name" in
|
||||
flags | single-window-aspect-ratio | window-no-gaps)
|
||||
flags | rounded-corners | single-window-aspect-ratio | window-no-gaps)
|
||||
if [[ -f $toggle_defaults_dir/$toggle_name.lua ]]; then
|
||||
cp -f "$toggle_defaults_dir/$toggle_name.lua" "$lua_toggle"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
echo "Prime Quickshell Omarchy menu styling"
|
||||
|
||||
AUTOSTART_FILE="$HOME/.config/hypr/autostart.lua"
|
||||
if [[ -f $AUTOSTART_FILE ]] && grep -q 'omarchy-menu --daemon' "$AUTOSTART_FILE"; then
|
||||
sed -i '/omarchy-menu --daemon/d' "$AUTOSTART_FILE"
|
||||
fi
|
||||
|
||||
TOGGLES_DIR="$HOME/.local/state/omarchy/toggles"
|
||||
QUICKSHELL_MENU_STYLE="$TOGGLES_DIR/quickshell-menu.json"
|
||||
mkdir -p "$TOGGLES_DIR"
|
||||
|
||||
if [[ ! -f $QUICKSHELL_MENU_STYLE ]]; then
|
||||
radius=0
|
||||
if [[ -f $TOGGLES_DIR/walker.css ]] && grep -q 'border-radius: 6px;' "$TOGGLES_DIR/walker.css"; then
|
||||
radius=6
|
||||
fi
|
||||
|
||||
printf '{ "radius": %s }\n' "$radius" >"$QUICKSHELL_MENU_STYLE"
|
||||
fi
|
||||
|
||||
THEME_DIR="$HOME/.config/omarchy/current/theme"
|
||||
COLORS_FILE="$THEME_DIR/colors.toml"
|
||||
MENU_COLORS_FILE="$THEME_DIR/menu.json"
|
||||
|
||||
color_value() {
|
||||
local key="$1"
|
||||
local value
|
||||
value=$(grep -E "^[[:space:]]*$key[[:space:]]*=" "$COLORS_FILE" | head -1)
|
||||
value="${value#*=}"
|
||||
value="${value//\"/}"
|
||||
value="${value//\'/}"
|
||||
value="${value//[[:space:]]/}"
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
if [[ -f $COLORS_FILE && ! -f $MENU_COLORS_FILE ]]; then
|
||||
accent=$(color_value accent)
|
||||
background=$(color_value background)
|
||||
foreground=$(color_value foreground)
|
||||
|
||||
cat >"$MENU_COLORS_FILE" <<JSON
|
||||
{
|
||||
"accent": "${accent:-#89b4fa}",
|
||||
"background": "${background:-#101315}",
|
||||
"foreground": "${foreground:-#cacccc}",
|
||||
"border": "${foreground:-#cacccc}"
|
||||
}
|
||||
JSON
|
||||
fi
|
||||
|
||||
rm -rf "${XDG_CACHE_HOME:-$HOME/.cache}/omarchy/menu"
|
||||
|
||||
if omarchy-cmd-present hyprctl; then
|
||||
hyprctl reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
@@ -0,0 +1,11 @@
|
||||
echo "Convert Hyprland rounded corners toggle to Lua"
|
||||
|
||||
old_toggle="$HOME/.local/state/omarchy/toggles/hypr/rounded-corners.conf"
|
||||
new_toggle="$HOME/.local/state/omarchy/toggles/hypr/rounded-corners.lua"
|
||||
|
||||
if [[ -f $old_toggle ]]; then
|
||||
mkdir -p "$(dirname "$new_toggle")"
|
||||
cp "$OMARCHY_PATH/default/hypr/toggles/rounded-corners.lua" "$new_toggle"
|
||||
rm -f "$old_toggle"
|
||||
hyprctl reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
Reference in New Issue
Block a user