129 lines
4.2 KiB
Bash
Executable File
129 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ollie:prompt
|
|
# ## gui_input
|
|
#
|
|
# Synthetic keyboard/mouse input (ydotool/xdotool).
|
|
#
|
|
# **Args**: `[action, ...]`
|
|
# - Actions: `key`, `type`, `click`, `move`, `scroll`
|
|
#
|
|
# ```
|
|
# call_tool: calls=[{tool: "gui_input", args: ["key", "ctrl+s"]}]
|
|
# call_tool: calls=[{tool: "gui_input", args: ["type", "hello world"]}]
|
|
# ```
|
|
# ollie:end
|
|
set -euo pipefail
|
|
|
|
cmd="${1:?usage: gui_input <key|type|click|move|scroll> [args...]}"
|
|
shift
|
|
|
|
# Detect input method: prefer ydotool (Wayland-safe), fall back to xdotool
|
|
if command -v ydotool &>/dev/null; then
|
|
INPUT_TOOL="ydotool"
|
|
elif command -v xdotool &>/dev/null; then
|
|
INPUT_TOOL="xdotool"
|
|
else
|
|
echo "ERROR: install ydotool (Wayland) or xdotool (X11)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
case "$cmd" in
|
|
key)
|
|
# Simulate key press. Examples: "Return", "ctrl+c", "alt+F4", "super"
|
|
keys="${1:?usage: gui_input key <key_combo>}"
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
# ydotool uses key codes; map common names
|
|
ydotool key "$keys"
|
|
else
|
|
xdotool key "$keys"
|
|
fi
|
|
echo "key: $keys"
|
|
;;
|
|
type)
|
|
# Type a string
|
|
text="${1:?usage: gui_input type <text>}"
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
ydotool type -- "$text"
|
|
else
|
|
xdotool type --clearmodifiers -- "$text"
|
|
fi
|
|
echo "typed: ${#text} chars"
|
|
;;
|
|
click)
|
|
# Mouse click. Args: [button] [x y]
|
|
button="${1:-1}" # 1=left, 2=middle, 3=right
|
|
if [ $# -ge 3 ]; then
|
|
x="$2"; y="$3"
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
ydotool mousemove --absolute "$x" "$y"
|
|
sleep 0.05
|
|
ydotool click "$button"
|
|
else
|
|
xdotool mousemove "$x" "$y"
|
|
sleep 0.05
|
|
xdotool click "$button"
|
|
fi
|
|
echo "click: button=$button at $x,$y"
|
|
else
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
ydotool click "$button"
|
|
else
|
|
xdotool click "$button"
|
|
fi
|
|
echo "click: button=$button at cursor"
|
|
fi
|
|
;;
|
|
move)
|
|
# Move mouse. Args: <x> <y> [--relative]
|
|
x="${1:?usage: gui_input move <x> <y> [--relative]}"
|
|
y="${2:?usage: gui_input move <x> <y> [--relative]}"
|
|
relative="${3:-}"
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
if [ "$relative" = "--relative" ]; then
|
|
ydotool mousemove -- "$x" "$y"
|
|
else
|
|
ydotool mousemove --absolute "$x" "$y"
|
|
fi
|
|
else
|
|
if [ "$relative" = "--relative" ]; then
|
|
xdotool mousemove_relative "$x" "$y"
|
|
else
|
|
xdotool mousemove "$x" "$y"
|
|
fi
|
|
fi
|
|
echo "moved: $x,$y${relative:+ (relative)}"
|
|
;;
|
|
scroll)
|
|
# Scroll. Args: <up|down|left|right> [amount]
|
|
direction="${1:?usage: gui_input scroll <up|down|left|right> [amount]}"
|
|
amount="${2:-3}"
|
|
if [ "$INPUT_TOOL" = "ydotool" ]; then
|
|
case "$direction" in
|
|
up) ydotool mousemove --wheel -- 0 "-$amount" ;;
|
|
down) ydotool mousemove --wheel -- 0 "$amount" ;;
|
|
left) ydotool mousemove --wheel -- "-$amount" 0 ;;
|
|
right) ydotool mousemove --wheel -- "$amount" 0 ;;
|
|
esac
|
|
else
|
|
case "$direction" in
|
|
up) xdotool click --repeat "$amount" 4 ;;
|
|
down) xdotool click --repeat "$amount" 5 ;;
|
|
left) xdotool click --repeat "$amount" 6 ;;
|
|
right) xdotool click --repeat "$amount" 7 ;;
|
|
esac
|
|
fi
|
|
echo "scroll: $direction $amount"
|
|
;;
|
|
*)
|
|
echo "usage: gui_input <key|type|click|move|scroll> [args...]" >&2
|
|
echo "" >&2
|
|
echo "Commands:" >&2
|
|
echo " key <combo> - press key combo (e.g. ctrl+c, Return, alt+F4)" >&2
|
|
echo " type <text> - type a string" >&2
|
|
echo " click [btn] [x y] - mouse click (1=left 2=mid 3=right)" >&2
|
|
echo " move <x> <y> [--relative] - move cursor" >&2
|
|
echo " scroll <dir> [amount] - scroll (up/down/left/right)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|