#! /usr/bin/env bash if [ -n "$DEBUG" ]; then set -x; fi show-help() { echo "usage: $(basename "$0") []" echo echo "Toggle visibility of a window belonging to a specific process:" echo " - If not running the will be launched." echo " - If process is running (or first window found) will be" echo " activated and focused." echo " - If process is running and is in focus, minimize it." echo echo "Options:" echo " -p (Required) process name given to pgrep to narrow list of" echo " possible target windows." echo " -e Executable name or path used to launch process when it is not" echo " running. If not specified, will attempt to use process name" echo " instead." echo " -w Title/name of window which belongs to process to focus on." echo " Allows regular expression matching. If not specified, the first" echo " window found belonging to process will be used." echo " -b Bring window to current desktop if it is on another one." echo " -a Assign window to all desktops/workspaces after activating it." echo " -h Display this help message." echo echo "Requirements:" echo " - xdotool" echo " - wmctrl" } error() { echo -e "ERROR: $*" 1>&2 } error-help() { error "$@" show-help 1>&2 } OPT_PROC="" OPT_BIN="" OPT_WIN="" OPT_BRING="" OPT_ALL="" parse-arguments() { while getopts ":p:e:w:bah" opt; do case ${opt} in p ) OPT_PROC="$OPTARG" ;; e ) OPT_BIN="$OPTARG" ;; w ) OPT_WIN="$OPTARG" ;; b ) OPT_BRING="1" ;; a ) OPT_ALL="1" ;; h ) show-help ;; \? ) error-help "Invalid option: -${OPTARG}\n" 1>&2 exit 1 ;; esac done shift $((OPTIND - 1)) if [ -z "$OPT_PROC" ]; then error-help "-p option is required." exit 1 fi if [ -z "$OPT_BIN" ]; then OPT_BIN="$OPT_PROC" fi if ! command -v "$OPT_BIN" &>/dev/null; then error "\"${OPT_BIN}\" does not seem to be a valid executable." exit 2 fi } main() { local target local pid local win_id local focused_id parse-arguments "$@" mapfile -t target < <(find-window) pid="${target[0]}" win_id="${target[1]}" if [ -z "$pid" ]; then echo "$OPT_PROC not running, launching with: \"$OPT_BIN\"" "$OPT_BIN" else echo "$OPT_PROC instance found" focused_id="$(xdotool getactivewindow)" if [ "$win_id" == "$focused_id" ]; then echo "Target window is in focus, minimizing" xdotool windowminimize "$win_id" else if [ -n "$OPT_BRING" ]; then echo "Bring window to current desktop and activate" wmctrl -i -R "$win_id" if [ -n "$OPT_ALL" ]; then echo "Assign window to all desktops" xdotool set_desktop_for_window "$win_id" -1 fi else echo "Activating window triggering desktop switch as needed" xdotool windowactivate "$win_id" fi fi fi } find-window() { local pid local win_id local opts opts=(--all --onlyvisible) if [ -n "$OPT_WIN" ]; then opts+=(--name "$OPT_WIN") fi for pid in $(pgrep "$OPT_PROC"); do win_id="$(xdotool search --pid "$pid" "${opts[@]}")" if [ -n "$win_id" ]; then echo -e "$pid\n$win_id" break fi done } main "$@"