summary refs log tree commit diff
path: root/bin/swx
blob: ea2d8f059613362fbed93100d33344ed4d544be8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/bin/sh
set -e

[ -n "$DEBUG" ] && set -x

# check requirements
for app in swaymsg swq jq; do
	if ! command -v "$app" >/dev/null; then
		printf "%s: %s not install but required" "$0" "$app" >&2
		exit 1
	fi
done

border=
wspace=
output=
geometry=
termify=
appid_override=
rotate=
force_sleep=
sticky=
while getopts b:w:o:g:I:r:S:sth name; do
	case "$name" in
	b)	# border
		border="${OPTARG}" ;;
	w)	# move to workspace
		wspace="${OPTARG}" ;;
	o)	# move to output
		output="${OPTARG}" ;;
	g)	# geometry
		geometry="${OPTARG}" ;;
	t)	# termify
		termify=1 ;;
	I)	# override app_id for non-terminal applications
		appid_override="${OPTARG}" ;;
	r)	# rotate
		if ! command -v cage >/dev/null; then
			printf "%s: cage not installed but required to rotate containers" "$0" >&2
			exit 1
		fi
		rotate="${OPTARG}" ;;
	S)	# force sleep
		force_sleep="${OPTARG}" ;;
	s)	# set contianer to sticky
		sticky=1 ;;
	h|?)	printf "usage: %s [-bwogIrSs] COMMAND\n" "$(basename "$0")"
		printf "\n"
		printf "  -t \t\t(run COMMAND in \$TERM)\n"
		printf "  -b BORDER \t(set border property)\n"
		printf "  -w WORKSPACE \t(move to workspace)\n"
		printf "  -o OUTPUT \t(move to output)\n"
		printf "  -g GEOMETRY \t(resize/position window)\n"
		printf "  -I APP_ID \t(override app_id used to detect window, only makes sense with -t)\n"
		printf "  -r ROTATION \t(rotate the container, requires cage(1))\n"
		printf "  -S SLEEP \t(force a delay between spawning and property setting, see sleep(1))\n"
		printf "  -s \t\t(make COMMAND a sticky window, appearing on all workspaces)\n"
		printf "\n"
		printf "See sway(5) for possible options for BORDER, WORKSPACE, OUTPUT and GEOMETRY.\n"
		exit 2 ;;
	esac
done
shift $((OPTIND - 1))

arg0=$(basename "$1")
appid=${arg0}
if [ -z "${arg0}" ]; then
	exec "$0" -h
fi
shift

# needs to be termified?
# spawn a $TERM instance and exec that
if [ -n "${termify}" ]; then
	case ${TERM} in
	alacritty)	args="--title=${arg0} --class=${arg0} --command" ;;
	*) 		args="" ;;
	esac
	command="${TERM} ${args} ${arg0} ${*}"
else
	[ -n "${appid_override}" ] && appid=${appid_override}
	command="${arg0} ${*}"
fi

# needs to be rotated
# spawn a cage(1) instance and exec that, takes previous $command
if [ -n "${rotate}" ]; then
	# figure out how many "-r" flags we need
	rotate_args=""
	while [ $(( (rotate / 90) >= 1 )) = 1 ]; do
		rotate_args="${rotate_args} -r"
		rotate=$((rotate - 90))
	done
	# allow for the firefox workaround that spawns a kiosk window
	# under firejail (to avoid profile folder issues)
	if echo "$command" | grep -E 'firefox'; then
		command="firejail --overlay-tmpfs --profile=firefox ${command} --no-remote --kiosk"
	fi
	command="cage -d ${rotate_args} -- \"${command}\""
	appid="wlroots"
fi

sway exec "${command}" >/dev/null

if [ -n "${force_sleep}" ]; then
	sleep "${force_sleep}"
fi

sway_props_done=
waiting=0
while [ -z "${sway_props_done}" ]; do
	if ! swq has appid "${appid}" | jq -e 'length>0' \
		&& [ -z "${force_sleep}" ]
	then
		waiting=$((waiting+1))
		if [ "${waiting}" -gt 20 ]; then
			printf "%s: failed to run %s.\n" "$0" "${arg0}" >&2
			if [ -z "${termify}" ]; then
				printf "If you do see the application try running:\n" >&2
				printf "%s -I %s %s\n" \
					"$(basename "$0")" \
					"$(swq current con | jq -r '.app_id')" \
					"${arg0} $*" >&2
			fi
			exit 1
		fi >&2
		continue
	fi
	if [ -n "${border}" ]; then
		swaymsg border "${border}"
	fi
	if [ -n "${wspace}" ]; then
		swaymsg move workspace "${wspace}"
	fi
	if [ -n "${output}" ]; then
		swaymsg move output "${wspace}"
	fi
	if [ -n "${geometry}" ]; then
		swaymsg floating enable
		wh=$(printf "%s" "${geometry}" | cut -d' ' -f2)
		sway resize set \
			width "$(printf "%s" "${wh}" | cut -d'x' -f1)" px \
			height "$(printf "%s" "${wh}" | cut -d'x' -f2)" px
		xy=$(printf "%s" "${geometry}" | cut -d' ' -f1)
		swaymsg move absolute position \
			"$(printf "%s" "${xy}" | cut -d',' -f1)" px \
			"$(printf "%s" "${xy}" | cut -d',' -f2)" px
	fi
	if [ -n "${sticky}" ]; then
		swaymsg sticky enable
	fi
	sway_props_done=1
done >/dev/null