#!/bin/sh set -e [ -n "$DEBUG" ] && set -x # check requirements for app in swaymsg jq swq centercon; 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= rotate= sticky= floating= autotile= into_scratchpad= while getopts b:w:o:g:I:r:stfF:aSh 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 ;; 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) # set container to sticky sticky=1 ;; f) # set container to float floating=1 ;; F) floating="${OPTARG}" ;; a) # auto-tiling enabled autotile=1 ;; S) # launch into scratchpad into_scratchpad=1 ;; h|?) printf "usage: %s [-bwogIrsfoS] COMMAND\n" "$(basename "$0")" printf "\n" printf " -t \t\trun COMMAND in \$TERM\n" printf " -b BORDER \tset border property\n" printf " -w WORKSPACE \tmove to workspace\n" printf " -o OUTPUT \tmove to output\n" printf " -g GEOMETRY \tresize/position window\n" printf " -r ROTATION \trotate the container, requires cage(1)\n" printf " -s \t\tmake COMMAND a sticky window, appearing on all workspaces\n" printf " -f \t\tmake COMMAND a floating window\n\tsee centercon(1) for possible values\n" printf " -F [PERC [MODE]]\tmake COMMAND a floating window\n\tsee centercon(1) for possible values\n" printf " -a \t\tauto-tiling; always open COMMAND on the shorter edge\n\t\tof the current container\n" printf " -S \t\tmove the container into the scratchpad\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") 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 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}\"" fi if [ -n "${autotile}" ]; then case "$(swq current workspace | jq -r '.layout')" in split*) if [ "$(swq current con | jq '.rect | .width > .height')" = "true" ]; then swaymsg splith else swaymsg splitv fi ;; esac fi swaymsg exec "${command}" >/dev/null con_id="$(swaymsg -t subscribe '["window"]' | jq -s -r '.[]|select(.change=="new")|.container.id')" sway_props_done= while [ -z "${sway_props_done}" ]; do if [ -n "${floating}" ]; then swaymsg [con_id="${con_id}"] floating enable [ ! "${floating}" = "1" ] && centercon "${floating}" fi if [ -n "${into_scratchpad}" ]; then swaymsg [con_id="${con_id}"] move to scratchpad fi if [ -n "${geometry}" ]; then swaymsg [con_id="${con_id}"] floating enable wh=$(printf "%s" "${geometry}" | cut -d' ' -f2) swaymsg [con_id="${con_id}"] 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 [con_id="${con_id}"] move absolute position \ "$(printf "%s" "${xy}" | cut -d',' -f1)" px \ "$(printf "%s" "${xy}" | cut -d',' -f2)" px fi if [ -n "${wspace}" ]; then swaymsg [con_id="${con_id}"] move workspace "${wspace}" fi if [ -n "${output}" ]; then swaymsg [con_id="${con_id}"] move output "${wspace}" fi if [ -n "${sticky}" ]; then swaymsg [con_id="${con_id}"] sticky enable fi if [ -n "${border}" ]; then swaymsg [con_id="${con_id}"] border "${border}" fi sway_props_done=1 done >/dev/null