ollie/data/tools/gui_apps

123 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# args_json: {"type":"object","required":["action"],"properties":{"action":{"type":"string","description":"list|launch|activate"},"name":{"type":"string","description":"Application name"}}}
# ollie:prompt
# ## gui_apps
#
# Launch/list/activate applications.
#
# **Args**: `[action]` or `[action, app_name]`
# - Actions: `list`, `launch`, `activate`
#
# ```
# gui_apps(action="launch", name="firefox")
# gui_apps(action="list")
# ```
# ollie:end
set -euo pipefail
source "$(dirname "$0")/_lib/args.sh"
cmd=$(arg_get "action" "list")
name=$(arg_get "name" "")
case "$cmd" in
list)
# List running applications via KWin
if command -v wmctrl &>/dev/null; then
echo "CLASS TITLE"
wmctrl -l -x | while read -r wid desktop class host title; do
echo "$class $title"
done
elif command -v xdotool &>/dev/null; then
echo "WID NAME"
xdotool search --onlyvisible --name '' 2>/dev/null | while read -r wid; do
name=$(xdotool getwindowname "$wid" 2>/dev/null || echo '?')
echo "$wid $name"
done
else
# D-Bus fallback: list org.freedesktop.DBus registered names
echo "ERROR: install wmctrl or xdotool for window listing" >&2
exit 1
fi
;;
launch)
if [ $# -lt 2 ]; then echo '{"schema": {"type": "array", "items": [{"name": "action", "type": "string", "description": "list|launch|activate|installed", "required": true}, {"name": "app", "type": "string", "description": "App name or desktop file (for launch/activate)", "required": false}], "examples": [["list"], ["launch", "firefox"], ["activate", "Firefox"]]}}'; exit 1; fi
app="$name"
# Try gtk-launch first (handles .desktop files)
if command -v gtk-launch &>/dev/null; then
gtk-launch "$app" 2>/dev/null && { echo "launched: $app"; exit 0; }
fi
# Try kioclient
if command -v kioclient5 &>/dev/null || command -v kioclient &>/dev/null; then
kio=$(command -v kioclient5 || command -v kioclient)
"$kio" exec "applications:$app.desktop" 2>/dev/null && { echo "launched: $app"; exit 0; }
fi
# Try gio
if command -v gio &>/dev/null; then
# Find .desktop file
desktop_file=$(find /usr/share/applications ~/.local/share/applications \
-name "*${app}*.desktop" 2>/dev/null | head -1)
if [ -n "$desktop_file" ]; then
gio launch "$desktop_file" && { echo "launched: $app"; exit 0; }
fi
fi
# Try D-Bus activation
gdbus call --session \
--dest org.freedesktop.DBus \
--object-path /org/freedesktop/DBus \
--method org.freedesktop.DBus.StartServiceByName \
"$app" 0 2>/dev/null && { echo "activated: $app"; exit 0; }
# Last resort: just exec it
if command -v "$app" &>/dev/null; then
setsid "$app" &>/dev/null &
echo "launched: $app (pid $!)"
else
echo "ERROR: cannot find or launch '$app'" >&2
exit 1
fi
;;
activate)
if [ $# -lt 2 ]; then echo '{"schema": {"type": "array", "items": [{"name": "action", "type": "string", "description": "list|launch|activate|installed", "required": true}, {"name": "app", "type": "string", "description": "App name or desktop file (for launch/activate)", "required": false}], "examples": [["list"], ["launch", "firefox"], ["activate", "Firefox"]]}}'; exit 1; fi
app="$name"
# Focus existing window
if command -v wmctrl &>/dev/null; then
# Try by class first
wid=$(wmctrl -l -x | grep -i "$app" | head -1 | awk '{print $1}')
if [ -n "$wid" ]; then
wmctrl -i -a "$wid"
echo "activated: $wid"
exit 0
fi
fi
if command -v xdotool &>/dev/null; then
wid=$(xdotool search --name "$app" 2>/dev/null | head -1)
if [ -n "$wid" ]; then
xdotool windowactivate "$wid"
echo "activated: $wid"
exit 0
fi
fi
echo "ERROR: no window matching '$app'" >&2
exit 1
;;
installed)
# List installed .desktop files
find /usr/share/applications ~/.local/share/applications \
-name '*.desktop' 2>/dev/null | \
xargs grep -l '^Name=' | \
while read -r f; do
name=$(grep '^Name=' "$f" | head -1 | cut -d= -f2)
echo "$(basename "$f" .desktop) $name"
done | sort
;;
*)
echo '{"schema": {"type": "array", "items": [{"name": "action", "type": "string", "description": "list|launch|activate|installed", "required": true}, {"name": "app", "type": "string", "description": "App name or desktop file (for launch/activate)", "required": false}], "examples": [["list"], ["launch", "firefox"], ["activate", "Firefox"]]}}' >&2
exit 1
;;
esac