#! /usr/bin/env bash # @describe Wrapper for launching applications with window rules # Relies on polling for the next open window, not the process id # Race conditions are possible with active usage during application start # # https://github.com/sigoden/argc # @meta combine-shorts # @option -M --move Move next window to absolute position (X[%] Y[%]) (requires floating) # @option -R --resize Resize next window to absolute dimensions (W[%] H[%]) (requires floating) # @option -W --workspace Move next window to workspace # @flag -a --active Focus and raise next window (raise requires floating) # @flag -c --center Center next window (requires floating) # @flag -e --empty Only launch if workspace is empty (requires workspace) # @flag -f --float Float next window # @flag -g --group Add next window to the active group # @flag -l --lock Lock next window's group # @flag -m --maximize Maximize next window # @flag -n --new Add next window to a new group # @flag -p --pin Pin next window (requires floating) # @flag -s --fullscreen Fullscreen next window # @flag -t --tile Tile next window # @arg commands+ Commands to execute in an exec dispatcher eval "$(argc --argc-eval "$0" "$@")" if [[ "${argc_empty:-}" ]]; then # Delay to mitigate on-created-empty window race condition sleep 0.5 # Silently exit if window exists on specified workspace if hyprctl -j clients | jq -r .[].workspace.name | grep "${argc_workspace:-}"; then exit fi fi # Get initial count of open windows count="$(hyprctl -j clients | jq length)" # Launch application hyprctl dispatch exec -- "${argc_commands[@]:-}" # Poll for next window c=0 while (("$(hyprctl -j clients | jq length)" <= "$count")); do # Increment timeout counter ((c += 1)) # Time out after 60 seconds if (("$c" >= 60 * 10)); then notify-send "> launch" "Polling timed out" --urgency critical exit 1 fi sleep 0.1 done # Get address of last window window="address:$(hyprctl -j clients | jq -r ".[-1].address")" # Set batch rules on window batch= ### Floating rules if [[ "${argc_float:-}" ]]; then batch+="dispatch setfloating $window;" fi if [[ "${argc_center:-}" ]]; then batch+="dispatch focuswindow $window; dispatch centerwindow;" fi if [[ "${argc_move:-}" ]]; then batch+="dispatch movewindowpixel exact ${argc_move:-},$window;" fi if [[ "${argc_pin:-}" ]]; then batch+="dispatch pin $window;" fi if [[ "${argc_resize:-}" ]]; then batch+="dispatch resizewindowpixel exact ${argc_resize:-},$window;" fi ### Group rules if [[ "${argc_new:-}" ]]; then batch+="dispatch focuswindow $window; dispatch togglegroup;" # Requires no initial group fi if [[ "${argc_lock:-}" ]]; then batch+="dispatch focuswindow $window; dispatch lockactivegroup lock;" fi ### Global rules if [[ "${argc_active:-}" ]]; then batch+="dispatch alterzorder top,$window; dispatch focuswindow $window;" # Handles floating fi if [[ "${argc_fullscreen:-}" ]]; then batch+="dispatch focuswindow $window; dispatch fullscreen 0;" fi if [[ "${argc_group:-}" ]]; then batch+="dispatch focuswindow $window; dispatch moveintogroup up;" # Assumes up direction fi if [[ "${argc_maximize:-}" ]]; then batch+="dispatch focuswindow $window; dispatch fullscreen 1;" fi if [[ "${argc_tile:-}" ]]; then batch+="dispatch settiled $window;" fi if [[ "${argc_workspace:-}" ]]; then batch+="dispatch movetoworkspacesilent ${argc_workspace:-},$window;" fi # Dispatch batch commands if [[ "${batch:-}" ]]; then hyprctl --batch "$batch" fi