You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdrop-xtoolwait/tdrop

233 lines
7.5 KiB
Bash

#!/bin/bash
print_help() {
echo "
Used for hiding/unhiding programs to acheive quake-dropdown-like-functionality. Can create a dropdown window if one does not already exist and provides options to control the intial size and position, e.g. to leave panels visible. When used with a terminal, provides the option to specify the name of a tmuxinator or tmux session to automatically start or attach to.
Also supports the ability to auto-hide and auto-show. For example, this can be used to automatically hide a window when opening something, e.g. image viewer, video player, etc. from it, and then re-show the window whenever the image view, video player, etc. is closed.
Takes a window as an argument or one of auto_show, auto_hide, or toggle_auto_hide. 'toggle_auto_hide' toggles whether calling 'auto_hide' or 'auto_show' will have any effect. 'current' will turn the current window into a dropdown.
usage: tdrop [options] <program or 'current'> or one of <auto_show/auto_hide/toggle_auto_hide>
options:
-h height specify a height for a newly created term (default: 100%)
-w width specify a width for a newly created term (default: 45%)
-x pos specify x offset for a newly created term (default: 0)
-y pos specify y offset for a newly created term (default: 1)
-s name name for tmux or tmuxinator session (if not given, will not use tmux)
-n num num or extra text; only needed if want multiple dropdowns of same program (default: "")
-p cmd provide a pre command to float the window if necessary
-P cmd provide a post command to float the window if necessary
-O cmd provide a one time command only for when a dropdown is created/initiated (useful for 'tdrop -c')
-W the given program is not a terminal (or lacks an -e flag) (default: assume it IS a terminal)
--no-cancel don't cancel auto-showing
(default is to prevent this when manually toggling a term 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
}
# xdotool can take percentages; cannot take decimal percentages though
width="100%"
height="45%"
xoff=0
yoff=1
float_pre=""
float_post=""
oneshot_post=""
session_name=""
num=""
normal_window=false
cancel_auto_show=true
term=${*:0-1}
while getopts :h:w:x:y:s:n:p:P:O:-:W opt
do
case $opt in
h) height=$OPTARG;;
w) width=$OPTARG;;
x) xoff=$OPTARG;;
y) yoff=$OPTARG;;
s) session_name=$OPTARG;;
n) num=$OPTARG;;
p) float_pre=$OPTARG;;
P) float_post=$OPTARG;;
O) oneshot_post=$OPTARG;;
W) normal_window=true;;
-)
OPTION=$(echo "$OPTARG" | awk -F '=' '{print $1}')
OPTARG=$(echo "$OPTARG" | awk -F '=' '{print $2}')
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-command) float_pre=$OPTARG;;
post-command) float_post=$OPTARG;;
oneshot-post) oneshot_post=$OPTARG;;
normal-window) normal_window=true;;
no-cancel) cancel_auto_show=false;;
help) print_help;;
esac;;
*) print_help illegal_opt;;
esac
done
float_pre_command() {
if [[ -n $float_pre ]]; then
if [[ $float_pre == bspwm ]]; then
float_pre="bspc rule -a '$1' -o floating=on"
fi
eval "$float_pre"
fi
}
float_post_command() {
if [[ -n $oneshot_post ]] && [[ $1 == oneshot ]]; then
eval "$oneshot_post"
elif [[ -n $float_post ]]; then
eval "$float_post"
fi
}
term_create() {
if [[ -n $session_name ]]; then
# ugly workarounds due to how different terms different -e flags work
if [[ $term == urxvt ]]; then
$term -e bash -c "sleep 0.01 && xdotool getactivewindow > /tmp/tdrop/$term$num && xdotool getactivewindow windowmove $xoff $yoff windowsize $width $height && tmux attach-session -dt $session_name || tmuxinator start $session_name || tmux new-session -s $session_name" &
else
# starting with '/bin/bash -c' because required by termite
$term -e "/bin/bash -c 'sleep 0.01 && xdotool getactivewindow > /tmp/tdrop/$term$num && xdotool getactivewindow windowmove $xoff $yoff windowsize $width $height && tmux attach-session -dt $session_name || tmuxinator start $session_name || tmux new-session -s $session_name'" &
fi
else
# not using hold, because flag is different for different terminals
if [[ $term == urxvt ]]; then
$term -e bash -c "sleep 0.01 && xdotool getactivewindow > /tmp/tdrop/$term$num && xdotool getactivewindow windowmove $xoff $yoff windowsize $width $height && $SHELL" &
else
# not using hold, because flag is different for different terminals
$term -e "/bin/bash -c 'sleep 0.01 && xdotool getactivewindow > /tmp/tdrop/$term$num && xdotool getactivewindow windowmove $xoff $yoff windowsize $width $height && $SHELL'" &
fi
fi
}
win_create() {
$term &
# need to wait for window to be created
sleep 0.2
# often pids have two wids; first one has always been the right one for what I've tested
wid=$(xdotool search --pid $! | head -n 1)
echo "$wid" > /tmp/tdrop/"$term$num"
xdotool windowmove "$wid" "$xoff" "$yoff" windowsize "$wid" "$width" "$height"
}
current_create() {
# turns active window into a dropdown
wid=$(xdotool getactivewindow)
echo "$wid" > /tmp/tdrop/current"$num"
xprop -id "$(xprop -root _NET_ACTIVE_WINDOW | awk '{print $5}')" WM_CLASS | awk '{ gsub(/"/, ""); print $4}' > /tmp/tdrop/current"$num"_type
}
wid_toggle() {
mkdir -p /tmp/tdrop
# get saved window id if already created
wid=$(< /tmp/tdrop/"$term$num")
exists=true
if [[ -n $wid ]]; then
visibility=$(xwininfo -id "$wid" | awk '/Map State/ {print $3}')
if [[ -z $visibility ]]; then
# window no longer exists
exists=false
fi
else
exists=false
fi
if $exists && [[ $visibility != IsUnviewable ]]; then
if [[ $visibility == IsUnMapped ]]; then
if [[ $term == current ]]; then
float_pre_command "$(< /tmp/tdrop/current"$num"_type)"
else
float_pre_command "$term"
fi
xdotool windowmap "$wid"
float_post_command
else
xdotool windowunmap "$wid"
maybe_cancel_auto_show "$wid"
fi
else
# make it
float_pre_command "$term"
if [[ $term == current ]]; then
current_create
elif $normal_window; then
win_create
else
term_create
fi
float_post_command oneshot
fi
}
auto_hide() {
no_hide=$(< /tmp/tdrop/auto_hidden/no_hide)
if [[ -z $no_hide ]]; then
wid=$(xdotool getactivewindow)
class_name=$(xprop -id "$(xprop -root _NET_ACTIVE_WINDOW | awk '{print $5}')" WM_CLASS | awk '{ gsub(/"/, ""); print $4}')
mkdir -p /tmp/tdrop/auto_hidden
echo "$wid" > /tmp/tdrop/auto_hidden/wid
echo "$class_name" > /tmp/tdrop/auto_hidden/class
xdotool windowunmap "$wid"
fi
}
auto_show() {
no_hide=$(< /tmp/tdrop/auto_hidden/no_hide)
if [[ -z $no_hide ]]; then
wid=$(< /tmp/tdrop/auto_hidden/wid)
class=$(< /tmp/tdrop/auto_hidden/class)
float_pre_command "$class"
xdotool windowmap "$wid"
float_post_command
fi
}
maybe_cancel_auto_show() {
auto_hidden_wid=$(< /tmp/tdrop/auto_hidden/wid)
if $cancel_auto_show && [[ $1 == "$auto_hidden_wid" ]]; then
> /tmp/auto_hidden_terminal/wid
fi
}
toggle_auto_hide() {
no_hide=$(< /tmp/tdrop/auto_hidden/no_hide)
mkdir -p /tmp/tdrop/auto_hidden
if [[ -z $no_hide ]]; then
echo "true" > /tmp/tdrop/auto_hidden/no_hide
else
> /tmp/tdrop/auto_hidden/no_hide
fi
}
if [[ -n $1 ]]; then
if [[ $term == toggle_auto_hide ]]; then
toggle_auto_hide
elif [[ $term == auto_hide ]]; then
auto_hide
elif [[ $term == auto_show ]]; then
auto_show
else
wid_toggle
fi
else
print_help illegal_opt
fi
# vim is dumb
# vim: set ft=sh: