96 lines
2.4 KiB
Bash
Executable file
96 lines
2.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Simple script to launch an application or focus it if already running in sway
|
|
# Usage: launch-or-focus <command> [--class CLASS] [--title TITLE] [args...]
|
|
#
|
|
# Examples:
|
|
# launch-or-focus firefox
|
|
# launch-or-focus code --class Code --title "My Project"
|
|
# launch-or-focus kitty --class kitty
|
|
|
|
CLASS=""
|
|
TITLE=""
|
|
ARGS=()
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--class)
|
|
CLASS="$2"
|
|
shift 2
|
|
;;
|
|
--title)
|
|
TITLE="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
ARGS+=("$1")
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ${#ARGS[@]} -eq 0 ]; then
|
|
echo "Usage: $0 <command> [--class CLASS] [--title TITLE] [args...]" >&2
|
|
exit 1
|
|
fi
|
|
|
|
COMMAND="${ARGS[0]}"
|
|
APP_NAME=$(basename "$COMMAND")
|
|
unset 'ARGS[0]'
|
|
ARGS=("${ARGS[@]}")
|
|
|
|
# If class/title were provided as flags, add them to command args (for apps that support them)
|
|
if [ -n "$CLASS" ]; then
|
|
ARGS=("--class=$CLASS" "${ARGS[@]}")
|
|
fi
|
|
if [ -n "$TITLE" ]; then
|
|
ARGS=("--title=$TITLE" "${ARGS[@]}")
|
|
fi
|
|
|
|
# Find window by app_id (sway uses app_id), title, or app name
|
|
find_window() {
|
|
local class="$1"
|
|
local title="$2"
|
|
local app="$3"
|
|
|
|
# If class provided, search by app_id first (sway uses app_id)
|
|
if [ -n "$class" ]; then
|
|
swaymsg -t get_tree | jq -r --arg class "$class" '
|
|
recurse(.nodes[]?, .floating_nodes[]?) |
|
|
select((.app_id | type) == "string" and .app_id == $class) |
|
|
.id
|
|
' | head -n 1
|
|
return
|
|
fi
|
|
|
|
# If only title provided, search by title
|
|
if [ -n "$title" ]; then
|
|
swaymsg -t get_tree | jq -r --arg title "$title" '
|
|
recurse(.nodes[]?, .floating_nodes[]?) |
|
|
select((.name | type) == "string" and .name == $title) |
|
|
.id
|
|
' | head -n 1
|
|
return
|
|
fi
|
|
|
|
# Fallback to app name (search by app_id)
|
|
swaymsg -t get_tree | jq -r --arg app "$app" '
|
|
recurse(.nodes[]?, .floating_nodes[]?) |
|
|
select((.app_id | type) == "string" and .app_id == $app) |
|
|
.id
|
|
' | head -n 1
|
|
}
|
|
|
|
# Try to find existing window
|
|
WINDOW_ID=$(find_window "$CLASS" "$TITLE" "$APP_NAME")
|
|
|
|
# Focus if found, otherwise launch
|
|
if [ -n "$WINDOW_ID" ] && [ "$WINDOW_ID" != "null" ]; then
|
|
swaymsg "[con_id=$WINDOW_ID]" focus
|
|
else
|
|
"$COMMAND" "${ARGS[@]}" >/dev/null 2>&1 &
|
|
disown
|
|
fi
|
|
|