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.
267 lines
8.3 KiB
Bash
267 lines
8.3 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)
|
|
--clear clear saved window id; useful 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 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
|
|
clearwid=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;;
|
|
clear) clearwid=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
|
|
bspc rule -a "$1" -o floating=on
|
|
else
|
|
eval "$float_pre"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
float_post_command() {
|
|
if [[ -n $oneshot_post ]] && [[ $1 == oneshot ]]; then
|
|
eval "$oneshot_post"
|
|
elif [[ -n $float_post ]]; then
|
|
if [[ $float_post == openbox ]]; then
|
|
xdotool getactivewindow windowmove "$wid" "$xoff" "$yoff" windowsize "$wid" "$width" "$height"
|
|
else
|
|
eval "$float_post"
|
|
fi
|
|
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.5
|
|
# 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"
|
|
get_class_name > /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 "$wid"
|
|
maybe_cancel_auto_show "$wid"
|
|
else
|
|
xdotool windowunmap "$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
|
|
}
|
|
|
|
get_class_name() {
|
|
xprop -id "$(xprop -root _NET_ACTIVE_WINDOW | awk '{print $5}')" WM_CLASS | awk '{ gsub(/"/, ""); print $4}'
|
|
}
|
|
|
|
get_geometry() {
|
|
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 [[ $x -ne $rel_x ]]; then
|
|
x=$((x-rel_x))
|
|
fi
|
|
if [[ $y -ne $rel_y ]]; then
|
|
y=$((y-rel_y))
|
|
fi
|
|
echo -e "X=$x\nY=$y"
|
|
}
|
|
|
|
set_geometry() {
|
|
eval "$(< /tmp/tdrop/auto_hidden/geometry)"
|
|
xdotool windowmove "$1" "$X" "$Y"
|
|
}
|
|
|
|
auto_hide() {
|
|
no_hide=$(< /tmp/tdrop/auto_hidden/no_hide)
|
|
if [[ -z $no_hide ]]; then
|
|
wid=$(xdotool getactivewindow)
|
|
mkdir -p /tmp/tdrop/auto_hidden
|
|
echo "$wid" > /tmp/tdrop/auto_hidden/wid
|
|
get_class_name > /tmp/tdrop/auto_hidden/class
|
|
geometry_get "$wid" > /tmp/tdrop/auto_hidden/geometry
|
|
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 "$wid"
|
|
set_geometry "$wid"
|
|
fi
|
|
}
|
|
|
|
maybe_cancel_auto_show() {
|
|
if $cancel_auto_show && [[ $1 == "$(< /tmp/tdrop/auto_hidden/wid)" ]]; then
|
|
> /tmp/tdrop/auto_hidden/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 $clearwid; then
|
|
> /tmp/tdrop/"$term$num"
|
|
elif [[ $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:
|