fuzzel could only answer "which app", so launching Brave at a URL meant picking the app, waiting for it, then typing the address somewhere else. The launcher now takes a verb and an object in one line: type `gitlab.enqs.de` and every app that can open it sorts to the top, default browser first, ready for Enter — or arrow/hjkl down to Brave's New Incognito Window, which is offered as a peer of Brave itself rather than hidden behind a submenu. services/Apps.qml is the brain and holds no UI: it flattens desktop entries and their actions into one index, classifies the typed argument (url / mail / path), ranks by fuzzy match plus handler affinity plus frecency, and launches. Launching through `uwsm app` keeps each app in its own scope; entries whose Exec declares no field code (Brave's `--incognito` action, among others) are launched by tokenising Exec per the Desktop Entry spec and appending the argument, never via `sh -c`. Four prefixes reuse the same window, so there is one picker and one set of keys: `>` runs a command, `=` evaluates arithmetic, `:` is clipboard history (cliphist, which had been a second fuzzel invocation), and a dmenu mode is driven over IPC. quickshell/scripts/takemi-dmenu is the bridge for that last one — a `fuzzel --dmenu` drop-in for scripts that want a picker, symlinked into ~/.local/bin. fluxo's bt menu now goes through it. Living in the Quickshell process means the window is on screen on the frame the bind fires, with no process to spawn. Removes fuzzel entirely: its config, its theme submodule, the package, and the last consumers (the bar sigil, fluxo's menu_command). Also drops hypr/scripts/powermenu.sh, which was fuzzel-based and bound to nothing.
40 lines
1.1 KiB
Bash
Executable File
40 lines
1.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# fuzzel --dmenu, backed by the Takemi launcher in Quickshell.
|
|
#
|
|
# Reads choices on stdin, prints the chosen line on stdout, prints nothing if
|
|
# the launcher was dismissed. Accepts the handful of fuzzel flags the callers
|
|
# in this config actually pass so they did not have to be rewritten.
|
|
#
|
|
# The launcher lives in the already-running shell process, so unlike fuzzel
|
|
# there is nothing to start; the cost here is the two-file handshake, which
|
|
# exists because `qs ipc call` returns immediately and a dmenu has to block.
|
|
set -eu
|
|
|
|
prompt=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--dmenu|-d) ;;
|
|
--prompt) prompt="${2-}"; shift ;;
|
|
--prompt=*) prompt="${1#--prompt=}" ;;
|
|
*) ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
dir=$(mktemp -d)
|
|
trap 'rm -rf "$dir"' EXIT INT TERM
|
|
cat > "$dir/in"
|
|
|
|
qs ipc call shell dmenu "$dir/in" "$dir/out" "$prompt" >/dev/null
|
|
|
|
# Give up after two minutes rather than wedging a caller forever if the shell
|
|
# is reloaded out from under us mid-choice.
|
|
i=0
|
|
while [ ! -e "$dir/out" ]; do
|
|
i=$((i + 1))
|
|
[ "$i" -gt 2400 ] && exit 1
|
|
sleep 0.05
|
|
done
|
|
|
|
cat "$dir/out"
|