#!/usr/bin/env bash MUTDROP_PATH=/tmp/tdrop_"$USER" # shellcheck disable=SC2174 mkdir -p "$MUTDROP_PATH" -m 700 print_help() { echo " usage: tdrop [options] or 'current' or one of 'auto_show'/'auto_hide'/'toggle_auto_hide' options: -h height specify a height for a newly created term (default: 45%) -w width specify a width for a newly created term (default: 100%) -x pos specify x offset for a newly created term (default: 0) -y pos specify y offset for a newly created term (default: 1, see man) -s name name for tmux/tmuxinator/tmuxifier session (supported terminal required) -n num num or extra text; only needed if for the purpose of using multiple dropdowns of same program -c cmd provide a pre-create command -C cmd provide a post-create command -l cmd provide a command to float the window before it is mapped -L cmd provide a command to float the window after it is mapped -p cmd provide a pre-map command -P cmd provide a post-map command -u cmd provide a pre-unmap command -U cmd provide a post-unmap command -d XxY give decoration/border size to accurately restore window position; only applicable with auto_show -S cmd can be used to fix saved geometry with auto_hide; see manpage -i cmd provide a command to detect whether the current window is a floating window; on applicable with auto_hide -f flags specify flags/options to be used when creating the term or window (e.g. -f '--title mytitle'; default: none). Caution: if there is a tmux session specified (with -s), the option to execute a program (usually -e for terminal programs) is implicitly added by tdrop -a automatically detect window manager and set relevant options (e.g. this makes specifying -l/-L, -d, and -i uneccessary for supported WMs) (default: false) -m for use with multiple monitors and only with dropdowns (i.e. not for auto_show or auto_hide); convert percentages used for width or height to values relative to the size of the current monitor and force resizing of the dropdown when the monitor changes (default: false) --wm set the window manager name to mimic another window manager (for use with -a) --class name manually specify the class of the window (can be obtained with xprop) --name name set a new name for the dropdown window --clear clear saved window id; useful after accidentally make a window a dropdown (e.g. '$ tdrop --clear current') --no-cancel don't cancel auto-showing (default is to prevent this when manually toggling a window after it is auto-hidden) --help print help See man page for more details. " if [[ $1 == illegal_opt ]]; then exit 1 else exit 0 fi } # * Default Options and Option Parsing # xdotool can take percentages; cannot take decimal percentages though width="100%" height="45%" xoff=0 yoff=2 session_name= num= pre_create= post_create= pre_float= post_float= pre_map= post_map= pre_unmap= post_unmap= dec_fix= # NOTE: # pekwm, xfwm4, sawfish, openbox need subtract_when_same to be true # for awesome, fluxbox, blackbox, mutter, fvwm, and metacity, the value # does not matter # set in decoration_settings subtract_when_same= is_floating= program_flags= clearwid=false cancel_auto_show=true auto_detect_wm=false monitor_aware=false wm= user_set_wm=false class= name= while getopts :h:w:x:y:s:n:c:C:l:L:p:P:u:U:d:f:-:am opt do case $opt in h) height=$OPTARG;; w) width=$OPTARG;; x) xoff=$OPTARG;; y) yoff=$OPTARG;; s) session_name=$OPTARG;; n) num=$OPTARG;; c) pre_create=$OPTARG;; C) post_create=$OPTARG;; l) pre_float=$OPTARG;; L) post_float=$OPTARG;; p) pre_map=$OPTARG;; P) post_map=$OPTARG;; u) pre_unmap=$OPTARG;; U) post_unmap=$OPTARG;; d) dec_fix=$OPTARG;; S) subtract_when_same=false;; i) is_floating=$OPTARG;; f) program_flags=$OPTARG;; a) auto_detect_wm=true;; m) monitor_aware=true;; -) if [[ $OPTARG =~ ^(auto-detect-wm|monitor-aware|clear|no-cancel|help)$ ]] || \ [[ $OPTARG == *=* ]]; then OPTION=${OPTARG%%=*} OPTARG=${OPTARG#*=} else OPTION=$OPTARG # shellcheck disable=SC2124 OPTARG=${@:$OPTIND:1} ((OPTIND++)) fi case $OPTION in height) height=$OPTARG;; width) width=$OPTARG;; x-offset) xoff=$OPTARG;; y-offset) yoff=$OPTARG;; session) session_name=$OPTARG;; number) num=$OPTARG;; pre-create-hook) pre_create=$OPTARG;; post-create-hook) post_create=$OPTARG;; pre-map-float-command) pre_float=$OPTARG;; post-map-float-command) post_float=$OPTARG;; pre-map-hook) pre_map=$OPTARG;; post-map-hook) post_map=$OPTARG;; pre-unmap-hook) pre_unmap=$OPTARG;; post-unmap-hook) post_unmap=$OPTARG;; decoration-fix) dec_fix=$OPTARG;; no-subtract-when-same) subtract_when_same=false;; is-floating) is_floating=$OPTARG;; program-flags) program_flags=$OPTARG;; auto-detect-wm) auto_detect_wm=true;; monitor-aware) monitor_aware=true;; wm) wm=$OPTARG user_set_wm=true;; class) class=$OPTARG;; name) name=$OPTARG;; clear) clearwid=true;; no-cancel) cancel_auto_show=false;; help) print_help;; *) print_help illegal_opt;; esac;; *) print_help illegal_opt;; esac done shift "$((OPTIND-1))" program=$1 # check that the program is not a path and does not contain flags if [[ ! $program =~ ^(current|auto_hide|auto_show|toggle_auto_hide)$ ]] && \ ! type "$program" 2> /dev/null; then echo >&2 "The program should be in PATH and not contain flags." | \ tee -a "$MUTDROP_PATH"/log exit 1 fi if [[ $# -ne 1 ]]; then echo >&2 "Exactly 1 positional argument is required." \ "For help use -h or --help or see the manpage." | \ tee -a "$MUTDROP_PATH"/log exit 1 fi # validate options that require number values if [[ ! $height$width$xoff$yoff =~ ^[0-9%-]*$ ]]; then echo >&2 "The -h, -w, -x, and -y values must be numbers (or percentages)." | \ tee -a "$MUTDROP_PATH"/log exit 1 fi if [[ -n $dec_fix ]] && [[ ! $dec_fix =~ ^-?[0-9]+x-?[0-9]+$ ]]; then echo >&2 "The decoration fix value must have form 'num'x'num'." \ "The numbers can be negative or zero." | tee -a "$MUTDROP_PATH"/log exit 1 fi # non-user-settable global vars wid= # used for -m option; at first tdrop assumes that there is a focused window # on the current desktop; if there isn't (and the WM doesn't have some way to # query the current monitor), this will be set to false, and tdrop will have to # find out the current monitor info after opening the dropdown # (currently, using xwininfo to find the position of a window is the only # WM-independent way I know to find out what the current monitor is) focused_window_exists=true # * Multiple Monitor Automatic Re-Sizing percent_of_total() { # percent total awk "BEGIN {printf(\"%.0f\", 0.01*${1%\%}*$2)}" } # acts on globals convert_geometry_to_pixels() { total_width=$1 total_height=$2 local minus_width minus_height minus_xoff minus_yoff if [[ $width =~ %$ ]]; then width=$(percent_of_total "$width" "$total_width") elif [[ $width =~ ^- ]]; then minus_width=${width#-} width=$((total_width-minus_width)) fi if [[ $height =~ %$ ]]; then height=$(percent_of_total "$height" "$total_height") elif [[ $height =~ ^- ]]; then minus_height=${height#-} height=$((total_height-minus_height)) fi if [[ $xoff =~ %$ ]]; then xoff=$(percent_of_total "$xoff" "$total_width") elif [[ $xoff =~ ^- ]]; then minus_xoff=${xoff#-} xoff=$((total_width-minus_xoff)) fi if [[ $yoff =~ %$ ]]; then yoff=$(percent_of_total "$yoff" "$total_height") elif [[ $yoff =~ ^- ]]; then minus_yoff=${yoff#-} yoff=$((total_height-minus_yoff)) fi } update_geometry_settings_for_monitor() { # 1. Correctly interpret width/height percentages when there exist multiple # monitors so an initially created dropdown is the correct size (xdotool # would create a dropdown the width of all screens for 100% width) # 2. Force resize the dropdown to the correct percentage of the current # monitor IF the monitor has changed since the last time the dropdown # was used # it is conceivable that a user may want to use -m but not -a, so # get the wm from within this function local wm current_monitor wm=$(get_window_manager) if [[ $wm == bspwm ]]; then current_monitor=$(bspc query -T -m | grep -Po '^{"name":.*?",' | \ awk -F ":" '{gsub("[\",]", ""); print $2}') elif [[ $wm == i3 ]]; then # I'd rather not make jq a dependency current_monitor=$(i3-msg -t get_workspaces | sed 's/{"num"/\n/g' | \ awk -F ',' '/focused":true/ {sub(".*output",""); gsub("[:\"]",""); print $1}') fi local monitor_geo x_begin y_begin x_width y_height if [[ -n $current_monitor ]]; then monitor_geo=$(xrandr --query | \ awk "/$current_monitor/ {gsub(\"primary \",\"\"); print \$3}") x_begin=$(echo "$monitor_geo" | awk -F '+' '{print $2}') y_begin=$(echo "$monitor_geo" | awk -F '+' '{print $3}') x_width=$(echo "$monitor_geo" | awk -F 'x' '{print $1}') y_height=$(echo "$monitor_geo" | awk -F 'x|+' '{print $2}') else local wid wininfo window_x window_y monitors_info x_end y_end # determine current monitor in generic way wid=$(xdotool getactivewindow) if [[ -z $wid ]]; then # will try again after remapping or creating the dropdown return 1 fi wininfo=$(xwininfo -id "$wid") window_x=$(echo "$wininfo" | awk '/Absolute.*X/ {print $4}') window_y=$(echo "$wininfo" | awk '/Absolute.*Y/ {print $4}') monitors_info=$(xrandr --query | awk '/ connected/ {gsub("primary ",""); print}') while read -r monitor; do monitor_geo=$(echo "$monitor" | awk '{print $3}') if [[ $monitor_geo =~ ^[0-9]+x[0-9]+\+[0-9]+\+[0-9]+$ ]]; then x_begin=$(echo "$monitor_geo" | awk -F '+' '{print $2}') y_begin=$(echo "$monitor_geo" | awk -F '+' '{print $3}') x_width=$(echo "$monitor_geo" | awk -F 'x' '{print $1}') y_height=$(echo "$monitor_geo" | awk -F 'x|+' '{print $2}') x_end=$((x_begin+x_width)) y_end=$((y_begin+y_height)) if [[ $window_x -ge $x_begin ]] && [[ $window_x -lt $x_end ]] && \ [[ $window_y -ge $y_begin ]] && [[ $window_y -lt $y_end ]]; then current_monitor=$(echo "$monitor" | awk '{print $1}') break fi fi done <<< "$monitors_info" fi # convert w/h/x/y percentages/negatives to pixels convert_geometry_to_pixels "$x_width" "$y_height" # update x and y offsets, so that will appear on correct screen # (required for some WMs apparently, but not for others) ((xoff+=x_begin)) ((yoff+=y_begin)) } map_and_reset_geometry() { xdotool windowmap "$wid" windowmove "$wid" "$xoff" "$yoff" \ windowsize "$wid" "$width" "$height" 2> /dev/null } # * WM Detection and Hooks get_window_manager() { # xfwm4 and fvwm at least will give two names (hence piping into head) xprop -notype -id "$(xprop -root -notype | \ awk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}')" \ -f _NET_WM_NAME 8u | awk -F "\"" '/WM_NAME/ {print $2}' | head -n 1 } set_wm() { if ! $user_set_wm && $auto_detect_wm; then wm=$(get_window_manager) fi } decoration_settings() { if [[ -z $subtract_when_same ]]; then if $auto_detect_wm \ && [[ $wm =~ ^(Mutter|GNOME Shell|bspwm|i3|GoomwW)$ ]]; then subtract_when_same=false else subtract_when_same=true fi fi if [[ -z "$dec_fix" ]] && $auto_detect_wm; then # settings for stacking/floating wms where can't get right position # easily from xwininfo; take borders into account if [[ $wm == Blackbox ]]; then dec_fix="1x22" elif [[ $wm =~ ^(Mutter|GNOME Shell)$ ]]; then dec_fix="-10x-8" elif [[ $wm =~ ^(Mutter \(Muffin\))$ ]]; then dec_fix="-9x-8" fi fi } set_class() { if [[ -z "$class" ]]; then if [[ $program =~ ^google-chrome ]]; then class=google-chrome elif [[ $program == st ]]; then class=st-256color elif [[ $program == gnome-terminal ]]; then class=Gnome-terminal elif [[ $program == urxvtc ]]; then class=urxvt elif [[ $program == xiatec ]]; then class=xiate elif [[ $program == alacritty ]]; then class=Alacritty elif [[ $program == current ]]; then class=$(cat "$MUTDROP_PATH"/current"$num"_class 2> /dev/null) else class=$program fi fi } is_floating() { if [[ -n $is_floating ]]; then eval "$is_floating $1" elif $auto_detect_wm; then if [[ $wm == i3 ]]; then # TODO make sure this returns 1 on failure i3-msg -t get_tree | awk 'gsub(/{"id"/, "\n{\"id\"")' | \ awk '/focused":true.*floating":"user_on/ {print $1}' elif [[ $wm == bspwm ]]; then bspc query -T -n | grep '"state":"floating"' else return 0 fi else return 0 fi } pre_float() { if [[ $wm == bspwm ]]; then # newest (using "instance" names) if [[ $class =~ [A-Z] ]]; then bspc rule -a "$class" -o state=floating else bspc rule -a \*:"$class" -o state=floating fi fi } post_float() { if [[ $wm == awesome ]]; then echo 'local awful = require("awful") ; awful.client.floating.set(c, true)' | \ awesome-client elif [[ $wm == i3 ]]; then i3-msg "[id=$wid] floating enable" > /dev/null elif [[ $wm == herbstluftwm ]]; then herbstclient fullscreen on fi } pre_create() { if [[ -n $pre_create ]]; then eval "$pre_create" fi } post_create() { if [[ -n $post_create ]]; then eval "$post_create" fi } pre_map() { float=${1:-true} if [[ $float != false ]]; then if [[ -n $pre_float ]]; then eval "$pre_float" elif $auto_detect_wm; then pre_float fi fi if [[ -n $pre_map ]]; then eval "$pre_map" fi } map_and_post_map() { # always reset geometry map_and_reset_geometry float=${1:-true} if [[ $float != false ]]; then if [[ -n $post_float ]]; then eval "$post_float" elif $auto_detect_wm; then post_float fi fi # need to set geometry again if wasn't previously floating map_and_reset_geometry if [[ -n $post_map ]]; then eval "$post_map" fi } pre_unmap() { if [[ -n $pre_unmap ]]; then eval "$pre_unmap" fi } post_unmap() { if [[ -n $post_unmap ]]; then eval "$post_unmap" fi } unmap() { hide=$1 pre_unmap xdotool windowunmap "$wid" if [[ -z $hide ]]; then if [[ $wm == herbstluftwm ]]; then # TODO should only happen if wasn't previously fullscreen herbstclient fullscreen off fi fi post_unmap } # Old notes: # floating WMs that may move a window after remapping it # pekwm|Fluxbox|Blackbox|xfwm4|Metacity|FVWM|Sawfish|GoomwW|Mutter|GNOME Shell|Mutter \(Muffin\)|KWin|Metacity \(Marco\)|[Cc]ompiz|bspwm # floating WMs that may both move and resize a window after remapping it # Openbox # * General Helper Functions get_class_name() { xprop -id "$1" WM_CLASS | awk '{gsub(/"/, ""); print $4}' } get_visibility() { xwininfo -id "$1" 2> /dev/null | awk '/Map State/ {print $3}' } maybe_cancel_auto_show() { if $cancel_auto_show && \ [[ $1 == $(cat "$MUTDROP_PATH"/auto_hidden/wid 2> /dev/null) ]]; then # shellcheck disable=SC2188 > "$MUTDROP_PATH"/auto_hidden/wid fi } # * Dropdown Initialization create_win_return_wid() { local blacklist program_command pid visible_wid wids wid program_wid # blacklist all existing wids of program # (for programs where one pid shares all wids) blacklist=$(xdotool search --classname "$program") # for programs where $! won't always work (e.g. one pid for all windows) if [[ $program =~ ^(tilix|xfce4-terminal)$ ]]; then pid=$(pgrep -x "$program") elif [[ $program == urxvtc ]]; then blacklist=$(xdotool search --classname urxvtd) pid=$(pgrep -x urxvtd) elif [[ $program == xiatec ]]; then pid=$(pgrep -x xiate) elif [[ $program == chromium ]]; then # this may work fine # pid=$(pgrep -xo chromium) pid=$(pgrep -xa chromium | awk '!/--type/ {print $1}') elif [[ $program == chromium-browser ]]; then pid=$(pgrep -xa chromium-browse | awk '!/--type/ {print $1}') elif [[ $program =~ ^google-chrome ]]; then pid=$(pgrep -xa chrome | awk '!/--type/ {print $1}') fi # need to redirect stdout or function won't return eval "$1 > /dev/null &" if [[ -z $pid ]]; then # for normal programs # also for when one of the programs above hadn't already been started pid=$! fi visible_wid=false while : ; do if [[ $program == gnome-terminal ]]; then # only 1 pid; changes at some point after first run # actual process name for me is gnome-terminal- pid=$(pgrep gnome-terminal) fi wids=$(xdotool search --pid "$pid") if [[ -n "$wids" ]]; then while read -r wid; do if [[ ! $blacklist =~ (^|$'\n')"$wid"($|$'\n') ]] && \ [[ $(get_visibility "$wid") == IsViewable ]]; then visible_wid=true program_wid=$wid fi done <<< "$wids" fi if $visible_wid; then break fi sleep 0.01 done echo -n "$program_wid" } program_start() { local program_command tmux_command wid program_command="$program $program_flags" if [[ -n "$session_name" ]]; then session_name=$(printf "%q" "$session_name") tmux_command="'tmux attach-session -dt $session_name || \ tmuxifier load-session $session_name || \ tmuxinator start $session_name || \ tmux new-session -s $session_name'" if [[ $program =~ ^(urxvt|alacritty|xiatec$) ]]; then program_command="$program_command -e bash -c $tmux_command" elif [[ $program == kitty ]]; then program_command="$program_command bash -c $tmux_command" else program_command="$program_command -e \"bash -c $tmux_command\"" fi fi wid=$(create_win_return_wid "$program_command") if [[ -n "$name" ]]; then xdotool set_window --name "$name" "$wid" fi echo "$wid" > "$MUTDROP_PATH/$program$num" echo -n "$wid" } current_create() { # turns active window into a dropdown local wid wid=$(xdotool getactivewindow) echo "$wid" > "$MUTDROP_PATH"/current"$num" get_class_name "$wid" > "$MUTDROP_PATH"/current"$num"_class if [[ -n "$name" ]]; then xdotool set_window --name "$name" "$wid" fi echo -n "$wid" } wid_toggle() { # deal with percentages/negatives when no -m if ! $monitor_aware; then local total_geo total_width total_height total_geo=$(xwininfo -root | awk '/geometry/ {print $2}') total_width=$(echo "$total_geo" | awk -F 'x' '{print $1}') total_height=$(echo "$total_geo" | awk -F 'x|+' '{print $2}') convert_geometry_to_pixels "$total_width" "$total_height" fi # get saved window id if already created local exists visibility # cat to silence error wid=$(cat "$MUTDROP_PATH/$program$num" 2> /dev/null) exists=true if [[ -n $wid ]]; then visibility=$(get_visibility "$wid") # sometimes xwininfo will still report a window as existing hence xprop check if [[ -z $visibility ]] || [[ -z $(xprop -id "$wid" 2> /dev/null) ]]; then # window no longer exists exists=false # shellcheck disable=SC2188 > "$MUTDROP_PATH/$program$num" fi else exists=false fi if $exists; then if [[ $visibility =~ ^(IsUnMapped|IsUnviewable)$ ]]; then # visibility will be IsUnMapped on most WMs if the dropdown is open # on another desktop; may also be IsUnviewable xdotool set_desktop_for_window "$wid" "$(xdotool get_desktop)" if [[ $(get_visibility "$wid") == IsUnMapped ]]; then pre_map else xdotool windowactivate "$wid" fi # update here if possible so this doesn't cause a delay # between the window being remapped and resized if $monitor_aware; then update_geometry_settings_for_monitor || \ focused_window_exists=false fi map_and_post_map # cancel auto-show for a window when manually remapping it maybe_cancel_auto_show "$wid" if ! $focused_window_exists; then # need to use dropdown as active window to get monitor info update_geometry_settings_for_monitor # always resize/move; if monitor hasn't changed then it won't be # necessary, but it won't cause problems either map_and_reset_geometry fi else unmap fi else # necessary to deal with negative width or height # if creating on an empty desktop and can't determine the monitor, # must set temporary values for negative width and/or height local original_width original_height if $monitor_aware && ! update_geometry_settings_for_monitor; then focused_window_exists=false if [[ $width =~ ^- ]]; then original_width=$width width=100% fi if [[ $height =~ ^- ]]; then original_height=$height height=100% fi fi # make it pre_create if [[ $program == current ]]; then wid=$(current_create) unmap else pre_map wid=$(program_start) map_and_post_map # update window dimensions if necessary if ! $focused_window_exists; then width=${original_width:-$width} height=${original_height:-$height} update_geometry_settings_for_monitor map_and_reset_geometry fi fi post_create fi } # * Helper Functions for Auto Hiding/Showing get_geometry() { # so that won't float a tiled window later when showing if is_floating "$1" &> /dev/null; then local wininfo x y rel_x rel_y width height wininfo=$(xwininfo -id "$1") x=$(echo "$wininfo" | awk '/Absolute.*X/ {print $4}') y=$(echo "$wininfo" | awk '/Absolute.*Y/ {print $4}') rel_x=$(echo "$wininfo" | awk '/Relative.*X/ {print $4}') rel_y=$(echo "$wininfo" | awk '/Relative.*Y/ {print $4}') if [[ $subtract_when_same != false ]]; then # behaviour works for most WMs (at least floating ones) x=$((x-rel_x)) y=$((y-rel_y)) else # don't subtract when abs and rel values are the same # necessary for WMs like bspwm and i3 if [[ $x -ne $rel_x ]]; then x=$((x-rel_x)) fi if [[ $y -ne $rel_y ]]; then y=$((y-rel_y)) fi fi width=$(xwininfo -id "$(xdotool getactivewindow)" | \ awk '/Width/ {print $2}') height=$(xwininfo -id "$(xdotool getactivewindow)" | \ awk '/Height/ {print $2}') echo -n -e "xoff=$x\nyoff=$y\nwidth=$width\nheight=$height" else # window is not floating; don't bother saving geometry echo -n "false" fi } # set global xoff, yoff, width, and height based on stored values restore_geometry() { local x_fix y_fix eval "$(< "$MUTDROP_PATH"/auto_hidden/geometry)" if [[ -n $dec_fix ]]; then x_fix=$(echo "$dec_fix" | awk -F "x" '{print $1}') y_fix=$(echo "$dec_fix" | awk -F "x" '{print $2}') xoff=$((xoff-x_fix)) yoff=$((yoff-y_fix)) fi } toggle_auto_hide() { local no_hide no_hide=$(< "$MUTDROP_PATH"/auto_hidden/no_hide) 2> /dev/null mkdir -p "$MUTDROP_PATH"/auto_hidden if [[ -z $no_hide ]]; then echo "true" > "$MUTDROP_PATH"/auto_hidden/no_hide else # shellcheck disable=SC2188 > "$MUTDROP_PATH"/auto_hidden/no_hide fi } # * Auto Hiding/Showing auto_hide() { local no_hide no_hide=$(< "$MUTDROP_PATH"/auto_hidden/no_hide) 2> /dev/null if [[ -z $no_hide ]]; then wid=$(xdotool getactivewindow) mkdir -p "$MUTDROP_PATH"/auto_hidden echo "$wid" > "$MUTDROP_PATH"/auto_hidden/wid get_class_name "$wid" > "$MUTDROP_PATH"/auto_hidden/class get_geometry "$wid" > "$MUTDROP_PATH"/auto_hidden/geometry unmap hide fi } auto_show() { local no_hide no_hide=$(< "$MUTDROP_PATH"/auto_hidden/no_hide) 2> /dev/null if [[ -z $no_hide ]]; then local was_floating XY wid=$(< "$MUTDROP_PATH"/auto_hidden/wid) class=$(< "$MUTDROP_PATH"/auto_hidden/class) was_floating=$(< "$MUTDROP_PATH"/auto_hidden/geometry) restore_geometry "$wid" pre_map "$was_floating" map_and_post_map "$was_floating" fi } # * Main # ** Setup set_wm decoration_settings set_class # ** Primary Action if $clearwid; then # shellcheck disable=SC2188 > "$MUTDROP_PATH/$program$num" elif [[ $program == toggle_auto_hide ]]; then toggle_auto_hide elif [[ $program == auto_hide ]]; then auto_hide elif [[ $program == auto_show ]]; then auto_show else wid_toggle fi # vim is dumb # vim: set ft=sh noet: