Compare commits
No commits in common. 'gh-pages' and 'master' have entirely different histories.
@ -0,0 +1,10 @@
|
|||||||
|
name: lint
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
shellcheck:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: shellcheck
|
||||||
|
uses: ludeeus/action-shellcheck@0.1.0
|
@ -0,0 +1,24 @@
|
|||||||
|
Copyright (c) 2015, Fox Kiester
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
PREFIX ?= /usr/local
|
||||||
|
BINDIR = $(PREFIX)/bin
|
||||||
|
MANDIR = $(PREFIX)/share/man
|
||||||
|
LICENSEDIR = $(PREFIX)/share/licenses
|
||||||
|
|
||||||
|
install:
|
||||||
|
# 755 is default
|
||||||
|
install -D -m 755 tdrop "$(DESTDIR)$(BINDIR)"/tdrop
|
||||||
|
install -D -m 644 tdrop.1 "$(DESTDIR)$(MANDIR)"/man1/tdrop.1
|
||||||
|
install -D -m 644 LICENSE "$(DESTDIR)$(LICENSEDIR)"/tdrop/LICENSE
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f "$(DESTDIR)$(BINDIR)"/tdrop
|
||||||
|
rm -f "$(DESTDIR)$(MANDIR)"/man1/tdrop.1
|
||||||
|
rm -rf "$(DESTDIR)$(LICENSEDIR)/tdrop"
|
@ -0,0 +1,5 @@
|
|||||||
|
* About
|
||||||
|
This is a tdrop fork but using an external script xtoolwait (on AUR =xtoolwait-git=).
|
||||||
|
It was created to support few programs (like suckless tabbed) which doesn't work yet with the upstream version.
|
||||||
|
|
||||||
|
Just don't forget to install xtoolwait, because I basically replaced hundred lines of code with just one call to this utility.
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 MiB |
@ -0,0 +1,806 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MUTDROP_PATH=/tmp/tdrop_"$USER"
|
||||||
|
# shellcheck disable=SC2174
|
||||||
|
mkdir -p "$MUTDROP_PATH" -m 700
|
||||||
|
|
||||||
|
print_help() {
|
||||||
|
echo "
|
||||||
|
usage: tdrop [options] <program> [program options ...]
|
||||||
|
or 'current'
|
||||||
|
or one of 'auto_show'/'auto_hide'/'toggle_auto_hide'
|
||||||
|
or 'hide_all'
|
||||||
|
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).
|
||||||
|
NOTE: This flag is deprecated. Specify flags after the program name
|
||||||
|
instead. This flag may be removed in the future.
|
||||||
|
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)
|
||||||
|
-t use mouse pointer location for detecting which monitor is the current
|
||||||
|
one
|
||||||
|
--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)
|
||||||
|
--timeout set the timeout (in seconds) that tdrop will wait for a window
|
||||||
|
to appear before giving up in case the program fails to start
|
||||||
|
(default: 10)
|
||||||
|
--help print help
|
||||||
|
|
||||||
|
See man page for more details.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo >&2 "$@" | tee -a "$MUTDROP_PATH"/log
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# * 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
|
||||||
|
pointer_monitor_detection=false
|
||||||
|
wm=
|
||||||
|
user_set_wm=false
|
||||||
|
class=
|
||||||
|
name=
|
||||||
|
timeout=10
|
||||||
|
while getopts :h:w:x:y:s:n:c:C:l:L:p:P:u:U:d:S:i:f:-:amt 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) eval "program_flags=($OPTARG)";;
|
||||||
|
a) auto_detect_wm=true;;
|
||||||
|
m) monitor_aware=true;;
|
||||||
|
t) pointer_monitor_detection=true;;
|
||||||
|
-)
|
||||||
|
if [[ $OPTARG =~ ^(auto-detect-wm|monitor-aware|pointer-monitor-detection|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) eval "program_flags=($OPTARG)";;
|
||||||
|
auto-detect-wm) auto_detect_wm=true;;
|
||||||
|
monitor-aware) monitor_aware=true;;
|
||||||
|
pointer-monitor-detection) pointer_monitor_detection=true;;
|
||||||
|
wm) wm=$OPTARG
|
||||||
|
user_set_wm=true;;
|
||||||
|
class) class=$OPTARG;;
|
||||||
|
name) name=$OPTARG;;
|
||||||
|
clear) clearwid=true;;
|
||||||
|
no-cancel) cancel_auto_show=false;;
|
||||||
|
timeout) timeout=$OPTARG;;
|
||||||
|
help) print_help;;
|
||||||
|
*) error "Unknown option --$OPTION." \
|
||||||
|
"Use --help to see available flags.";;
|
||||||
|
esac;;
|
||||||
|
*) error "Unknown option -$OPTARG." \
|
||||||
|
"Use --help to see available flags.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift "$((OPTIND-1))"
|
||||||
|
program=$1
|
||||||
|
|
||||||
|
if [[ ${#program_flags[@]} -eq 0 ]]; then
|
||||||
|
program_flags=("${@:2}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $program ]]; then
|
||||||
|
error "Program to run is required as a positional argument." \
|
||||||
|
"For help use -h or --help or see the manpage."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check that the program is in PATH
|
||||||
|
if [[ ! $program =~ ^(current|auto_hide|auto_show|toggle_auto_hide|hide_all)$ ]] && \
|
||||||
|
! type "$program" &> /dev/null; then
|
||||||
|
error "The program should be in PATH."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# validate options that require number values
|
||||||
|
if [[ ! $height$width$xoff$yoff =~ ^[0-9%-]*$ ]]; then
|
||||||
|
error "The -h, -w, -x, and -y values must be numbers (or percentages)."
|
||||||
|
fi
|
||||||
|
if [[ -n $dec_fix ]] && [[ ! $dec_fix =~ ^-?[0-9]+x-?[0-9]+$ ]]; then
|
||||||
|
error "The decoration fix value must have form 'num'x'num'." \
|
||||||
|
"The numbers can be negative or zero."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# non-user-settable global vars
|
||||||
|
wid=
|
||||||
|
|
||||||
|
# * Multiple Monitor Automatic Re-Sizing
|
||||||
|
percent_of_total() { # percent total
|
||||||
|
# gawk "BEGIN {printf(\"%.0f\", 0.01*${1%\%}*$2)}"
|
||||||
|
echo $((${1%\%} * ${2} / 100))
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
# meant to set non-local variables
|
||||||
|
split_geometry() { # <monitor geometry>
|
||||||
|
monitor_geo=$1
|
||||||
|
# x_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $2}')
|
||||||
|
x_begin=${monitor_geo#*+}
|
||||||
|
x_begin=${x_begin%+*}
|
||||||
|
# y_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $3}')
|
||||||
|
y_begin=${monitor_geo##*+}
|
||||||
|
# x_width=$(echo "$monitor_geo" | gawk -F 'x' '{print $1}')
|
||||||
|
x_width=${monitor_geo%x*}
|
||||||
|
# y_height=$(echo "$monitor_geo" | gawk -F 'x|+' '{print $2}')
|
||||||
|
y_height=${monitor_geo#*x}
|
||||||
|
y_height=${y_height%%+*}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 current_monitor
|
||||||
|
if [[ $wm == bspwm ]]; then
|
||||||
|
current_monitor=$(bspc query --names --monitors --monitor)
|
||||||
|
elif [[ $wm == i3 ]]; then
|
||||||
|
# TODO use jq if installed
|
||||||
|
# I'd rather not make jq a dependency
|
||||||
|
current_monitor=$(i3-msg -t get_workspaces | sed 's/{"num"/\n/g' | \
|
||||||
|
gawk -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 --current | \
|
||||||
|
gawk "/^$current_monitor/ {gsub(\"primary \",\"\"); print \$3}")
|
||||||
|
split_geometry "$monitor_geo"
|
||||||
|
else
|
||||||
|
local current_x current_y monitors_info x_end y_end
|
||||||
|
if ! $pointer_monitor_detection; then
|
||||||
|
# determine current monitor using active window
|
||||||
|
local wid wininfo
|
||||||
|
wid=$(xdotool getactivewindow)
|
||||||
|
if [[ -z $wid ]]; then
|
||||||
|
# will try again after remapping or creating the dropdown
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
wininfo=$(xwininfo -id "$wid")
|
||||||
|
current_x=$(echo "$wininfo" | gawk '/Absolute.*X/ {print $4}')
|
||||||
|
current_y=$(echo "$wininfo" | gawk '/Absolute.*Y/ {print $4}')
|
||||||
|
else
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
local X Y SCREEN WINDOW
|
||||||
|
# determine current monitor using pointer location
|
||||||
|
eval "$(xdotool getmouselocation --shell)"
|
||||||
|
current_x=X
|
||||||
|
current_y=Y
|
||||||
|
fi
|
||||||
|
monitors_info=$(xrandr --current | gawk '/ connected/ {gsub("primary ",""); print}')
|
||||||
|
while read -r monitor; do
|
||||||
|
monitor_geo=$(echo "$monitor" | gawk '{print $3}')
|
||||||
|
if [[ $monitor_geo =~ ^[0-9]+x[0-9]+\+[0-9]+\+[0-9]+$ ]]; then
|
||||||
|
split_geometry "$monitor_geo"
|
||||||
|
x_end=$((x_begin+x_width))
|
||||||
|
y_end=$((y_begin+y_height))
|
||||||
|
if [[ $current_x -ge $x_begin ]] && [[ $current_x -lt $x_end ]] && \
|
||||||
|
[[ $current_y -ge $y_begin ]] && [[ $current_y -lt $y_end ]]; then
|
||||||
|
# current_monitor=$(echo "$monitor" | gawk '{print $1}')
|
||||||
|
current_monitor=${monitor%% *}
|
||||||
|
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
|
||||||
|
set_wm() {
|
||||||
|
if ! $user_set_wm && $auto_detect_wm; then
|
||||||
|
local id
|
||||||
|
id=$(xprop -root -notype _NET_SUPPORTING_WM_CHECK)
|
||||||
|
id=${id##* }
|
||||||
|
# xfwm4 and fvwm at least will give two names (hence piping into head)
|
||||||
|
wm=$(xprop -notype -id "$id" _NET_WM_NAME | head -n 1)
|
||||||
|
wm=${wm##* }
|
||||||
|
wm=${wm//\"/}
|
||||||
|
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 =~ ^emacsclient ]]; then
|
||||||
|
class=emacs
|
||||||
|
elif [[ $program =~ ^google-chrome ]]; then
|
||||||
|
class=google-chrome
|
||||||
|
elif [[ $program == st ]]; then
|
||||||
|
class=st-256color
|
||||||
|
elif [[ $program == gnome-terminal ]]; then
|
||||||
|
class=Gnome-terminal
|
||||||
|
elif [[ $program =~ ^urxvt.* ]]; 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 | gawk 'gsub(/{"id"/, "\n{\"id\"")' | \
|
||||||
|
gawk '/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() {
|
||||||
|
local class
|
||||||
|
class=$(xprop -id "$1" WM_CLASS 2> /dev/null)
|
||||||
|
class=${class##* }
|
||||||
|
class=${class//\"/}
|
||||||
|
echo "$class"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_visibility() {
|
||||||
|
xwininfo -id "$1" 2> /dev/null | gawk '/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
|
||||||
|
}
|
||||||
|
|
||||||
|
program_start() {
|
||||||
|
local program_command tmux_command wid
|
||||||
|
program_command=("$program")
|
||||||
|
if [[ $program == alacritty ]]; then
|
||||||
|
# prevent alacritty from resizing the terminal to 80x24
|
||||||
|
program_command+=(-d 0 0)
|
||||||
|
fi
|
||||||
|
program_command+=("${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"
|
||||||
|
# note: st will work with or without the -e flag (like kitty)
|
||||||
|
# note: regular console works with or without quotes, but trinity's
|
||||||
|
# konsole only works without quotes
|
||||||
|
if [[ $program =~ ^(urxvt|alacritty|xiatec|st|lxterminal|qterminal|cool-retro-term|lilyterm|konsole$) ]]; then
|
||||||
|
program_command+=(-e bash -c "$tmux_command")
|
||||||
|
elif [[ $program == kitty ]]; then
|
||||||
|
program_command+=(bash -c "$tmux_command")
|
||||||
|
else
|
||||||
|
program_command+=(-e "\"bash -c $tmux_command\"")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
wid=$(xtoolwait -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() {
|
||||||
|
# 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)
|
||||||
|
local focused_window_exists
|
||||||
|
focused_window_exists=true
|
||||||
|
|
||||||
|
# deal with percentages/negatives when no -m
|
||||||
|
if ! $monitor_aware; then
|
||||||
|
local total_geo total_width total_height
|
||||||
|
total_geo=$(xwininfo -root | gawk '/geometry/ {gsub("+*",""); print $2}')
|
||||||
|
# total_width=$(echo "$total_geo" | gawk -F 'x' '{print $1}')
|
||||||
|
total_width=${total_geo%x*}
|
||||||
|
# total_height=$(echo "$total_geo" | gawk -F 'x' '{print $2}')
|
||||||
|
total_height=${total_geo#*x}
|
||||||
|
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 ]] || ! xprop -id "$wid" &> /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" | gawk '/Absolute.*X/ {print $4}')
|
||||||
|
y=$(echo "$wininfo" | gawk '/Absolute.*Y/ {print $4}')
|
||||||
|
rel_x=$(echo "$wininfo" | gawk '/Relative.*X/ {print $4}')
|
||||||
|
rel_y=$(echo "$wininfo" | gawk '/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)" | \
|
||||||
|
gawk '/Width/ {print $2}')
|
||||||
|
height=$(xwininfo -id "$(xdotool getactivewindow)" | \
|
||||||
|
gawk '/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" | gawk -F "x" '{print $1}')
|
||||||
|
y_fix=$(echo "$dec_fix" | gawk -F "x" '{print $2}')
|
||||||
|
xoff=$((xoff-x_fix))
|
||||||
|
yoff=$((yoff-y_fix))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle_auto_hide() {
|
||||||
|
local no_hide
|
||||||
|
no_hide=$(cat "$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=$(cat "$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=$(cat "$MUTDROP_PATH"/auto_hidden/no_hide 2> /dev/null)
|
||||||
|
if [[ -z $no_hide ]]; then
|
||||||
|
local was_floating
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# * Hide All
|
||||||
|
hide_all() {
|
||||||
|
shopt -s nullglob dotglob
|
||||||
|
local dropdowns
|
||||||
|
dropdowns=("$MUTDROP_PATH"/*)
|
||||||
|
for dropdown in "${dropdowns[@]}"; do
|
||||||
|
# cat to silence errors
|
||||||
|
wid=$(cat "$dropdown" 2> /dev/null)
|
||||||
|
unmap "$wid" 2> /dev/null
|
||||||
|
done
|
||||||
|
shopt -u nullglob dotglob
|
||||||
|
}
|
||||||
|
|
||||||
|
# * 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
|
||||||
|
elif [[ $program == hide_all ]]; then
|
||||||
|
hide_all
|
||||||
|
else
|
||||||
|
wid_toggle
|
||||||
|
fi
|
||||||
|
|
||||||
|
# vim is dumb
|
||||||
|
# vim: set ft=sh noet:
|
@ -0,0 +1,201 @@
|
|||||||
|
.\" Man page for tdrop.
|
||||||
|
.\" Please make an issue on the online repository if you find errors or typos.
|
||||||
|
.TH TDROP 1 "11 February 2015" "tdrop 0.2" "tdrop man page"
|
||||||
|
.SH NAME
|
||||||
|
Tdrop - make dropdown terminals and windows
|
||||||
|
.SH SYNOPSIS
|
||||||
|
tdrop [\fIOPTIONS\fR] [program name or cmd] [program options ...]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Tdrop is used for hiding/unhiding programs to acheive quake/dropdown functionality. It can create a dropdown window if one does not already exist or turn the current window into a dropdown on the fly. It provides options to control the intial size and position of dropdowns, for example to leave panels visible or to deal with window borders. When used with a terminal, it provides an option to specify the name of a tmux session to automatically start. It also allows the user to specify arbitrary options/flags to be used when starting programs. It uses window IDs as opposed to classes, so it can be used with multiple windows of the same program.
|
||||||
|
|
||||||
|
It also has the ability to automatically hide and automatically show dropdowns. For example, it can be used to automatically hide a terminal when opening something from it, e.g. an image viewer, video player, etc. Tdrop can then automatically bring back the terminal whenever the image view, video player, etc. is closed. See the Examples section for more information.
|
||||||
|
.SH Commands
|
||||||
|
Tdrop expects the name of a program or 'current' (to use the current window) as the last argument to create a dropdown (optionally followed by any flags to that program). Alternatively, it can take one of auto_show, auto_hide, toggle_auto_hide, or hide_all. If hide_all is given instead of a program name, tdrop will hide all visible dropdowns.
|
||||||
|
|
||||||
|
Tdrop's functionality is not particularly useful called directly from the command line. Commands should either be bound to a key, used in shell functions/aliases, or used with a file opener (e.g. in the rifle.conf).
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.br
|
||||||
|
E.g.
|
||||||
|
.br
|
||||||
|
$ tdrop -y 15 termite
|
||||||
|
.br
|
||||||
|
$ tdrop --y-offset=15 termite
|
||||||
|
.br
|
||||||
|
$ tdrop --y-offset 15 termite
|
||||||
|
.TP
|
||||||
|
Note that all hook and command related options can make use of any tdrop variables (such as $width, $height, $xoff, $yoff, $class, $wid, etc.). Note that for some of the hooks, the window id is not guarunteed to be known (since the window may not have yet been created), so any scripts that make use of these should check if it is defined (pre-map and pre-float; wid will never be known for pre-create).
|
||||||
|
.TP
|
||||||
|
\fB-w WIDTH\fR, \fB --width=WIDTH\fR
|
||||||
|
Specify a width for a created window as a number or percentage. A negative number is allowed (e.g. '-w -4') in which case the width will be that many pixels less than 100% of the screen size (or monitor size if '-m' is being used). This fixes the problem where 100% width may actually go over the screen due to window borders/decoration. The other other geometry options also accept negative values ('-h', '-x', and '-y'). (default: 100%)
|
||||||
|
.TP
|
||||||
|
\fB-h HEIGHT\fR, \fB --height=HEIGHT\fR
|
||||||
|
Specify a height for a created window as a number or percentage. (default: 45%)
|
||||||
|
.TP
|
||||||
|
\fB-x OFFSET\fR, \fB --x-offset=OFFSET\fR
|
||||||
|
Specify the x position for a created window as a number or percentage. (default: 0)
|
||||||
|
.TP
|
||||||
|
\fB-y OFFSET\fR, \fB --y-offset=OFFSET\fR
|
||||||
|
Specify the y position for a created window as a number or percentage. (default: 1, see BUGS)
|
||||||
|
.TP
|
||||||
|
\fB-s NAME\fR, \fB --session=NAME\fR
|
||||||
|
Specify a tmuxinator, tmuxifier, or tmux session name to start. An existing tmux session has highest precedence and will be connected to with '-d', detaching other attached clients. If a there is no tmuxinator/tmuxifier/etc. session of the given name, a normal tmux session with the name will be created. If this option is not given, tmux will not be used. Note that this option requires that the program be a supported terminal. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-n NUMBER\fR, \fB --number=NUMBER\fR
|
||||||
|
Specify a number (or any extra text) to differentiate between dropdowns of the same program (this is only needed when using multiple dropdowns of the same program). This flag can also be used for creating multiple different dropdowns on the fly ('current'). Note that it is not necessary to use this to deal with multi-user systems as tdrop stores dropdown information separately for each user. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-c COMMAND\fR, \fB --pre-create-hook=COMMAND\fR
|
||||||
|
Specify a command to execute before first creating or initializing a dropdown (before mapping a normal dropdown or before unmapping the 'current' window). This flag has no effect for the auto_(hide|show) commands. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-C\fR, \fB --post-create-hook=COMMAND\fR
|
||||||
|
Specify a command to execute after first creating or initializing a dropdown (after mapping a normal dropdown or after unmapping the 'current' window). This flag has no effect for the auto_(hide|show) commands. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-p COMMAND\fR, \fB --pre-map-hook=COMMAND\fR
|
||||||
|
Specify a command to execute before showing/mapping a dropdown. Note that this will run when showing a dropdown for the first time even when --pre-create-hook is used. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-P COMMAND\fR, \fB --post-map-hook=COMMAND\fR
|
||||||
|
Specify a command to execute after showing/mapping a dropdown. Note that this will run when hiding a dropdown for the first time even when --post-create-hook is used. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-u COMMAND\fR, \fB --pre-unmap-hook=COMMAND\fR
|
||||||
|
Specify a command to execute before hiding/unmapping a dropdown. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-U COMMAND\fR, \fB --post-unmap-hook=COMMAND\fR
|
||||||
|
Specify a command to execute after hiding/unmapping a dropdown. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-l COMMAND\fR, \fB --pre-map-float-command=COMMAND\fR
|
||||||
|
Specify a command execute before showing/mapping a dropdown in order to float the dropdown (e.g. a bspwm oneshot rule). This may be useful if you don't want to float all windows of a given program and tdrop doesn't automatically support this for your window manager with the -a flag. This will override any default floating command when used with -a.
|
||||||
|
.TP
|
||||||
|
\fB-L COMMAND\fR, \fB --post-map-float-command=COMMAND\fR
|
||||||
|
Specify a command execute after showing/mapping a dropdown in order to float the dropdown. This may be useful if you don't want to float all windows of a given program and tdrop doesn't automatically support this for your window manager with the -a flag. This can be used if your window manager does not support floating rules at all; for example, it can be used to fake a key combination (e.g. using xdotool) that will float the current window. This will override any default floating command when used with -a.
|
||||||
|
.TP
|
||||||
|
\fB-d DEC_SIZE\fR, \fB --decoration-fix=DEC_SIZE\fR
|
||||||
|
Specify a window decoration/border size in the form <x decoration size>x<y decoration size> to be taken into account when saving window position. This should not be necessary for most window managers and is only used with 'auto_show', e.g. 'tdrop -d 1x22 auto_show' for blackbox. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-S\fR, \fB --no-subtract-when-same\fR
|
||||||
|
This option is a more complicated companion to -d that is also unlikely to be needed. This is used to determine how to calculate the X and Y position of a window using xwininfo when 'auto_hide' is used (if the absolute and relative X or Y values are reported as the same, this option determines the behavior). If you are sure you have the decoration size correct, but windows are still being restored in an incorrect position with 'auto_show', you may want to try using this. Takes no argument. (default: false)
|
||||||
|
.TP
|
||||||
|
\fB-i\fR, \fB --is-floating\fR
|
||||||
|
Specify a command that will determine whether the current window is floating ($wid can be used in the command instead). Only used for the auto_hide command. This will be used to save whether the current window is floating or not. When restoring the window, if there is a float command and the window was previously floating, it will be floated. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-f\fR, \fB --program-flags\fR
|
||||||
|
NOTE: Using this flag is deprecated; it may be removed in the future. Instead, specify program flags after the program (e.g. "tdrop kitty --name foo").
|
||||||
|
|
||||||
|
Specify flags/options that the terminal or program should be called with. For example, to set the title of the terminal, something like 'tdrop -f "--title mytitle" <program>' can be used.
|
||||||
|
|
||||||
|
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! (default: none)
|
||||||
|
.TP
|
||||||
|
\fB-a\fR, \fB --auto-detect-wm\fR
|
||||||
|
If there are available settings for the detected window manager for the -l, -L, -d, and/or -i options, automatically set them. Takes no argument. Manually specified settings take precedence. This can be used both for dropdowns and the auto_(hide|show) commands. Takes no argument. (default: false)
|
||||||
|
.TP
|
||||||
|
\fB-m\fR, \fB --monitor-aware\fR
|
||||||
|
This option only applies for dropdowns (not auto-hiding and auto-showing). Specify that geometry values should be relative to the current monitor. For example, if the width is a percentage or negative value, the pixel width will be calculated as a percentage of the current monitor's width (instead of the combined width of all monitors). If the monitor changes, this option will cause a dropdown to be resized to fit the given percentages. Note that this option assumes xrandr is being used and requires xrandr to work. (default: false)
|
||||||
|
.TP
|
||||||
|
\fB-t\fR, \fB --pointer-monitor-detection\fR
|
||||||
|
Use mouse pointer location for detecting which monitor is the current one so terminal will be displayed on it. Without this option, the monitor with currently active window is considered the current one. This option is only effective if -m / --monitor-aware option is enabled.
|
||||||
|
.TP
|
||||||
|
\fB --wm=NAME\fR
|
||||||
|
Specify the window manager name (which determines the default settings when -a is specified). This may be useful if you've change the name of your window manager using wmname as this will prevent tdrop from correctly detecting the real window manager name. This could also potentially be useful if the all the default -a settings for another window manager work with the current one (e.g. if using a similar but differently named fork of some window manager). (default: automatically detected)
|
||||||
|
.TP
|
||||||
|
\fB --class=NAME\fR
|
||||||
|
Providing this option lets tdrop know what the class (or classname) of the window is (it does not actually set the class for a window). This is used for window managers like bspwm that use the class for floating rules. For some commonly used programs, tdrop will already use the correct class. This option is useful when the program name and class are not the same and there is not already a default mapping between the two. (default: the program name or a known substitution)
|
||||||
|
|
||||||
|
Both the class and classname of a window can be obtained using xprop (see WM_CLASS). As for the difference, generally the class starts with an uppercase letter and the classname starts with a lowercase letter. The xprop output may only list one for some programs (e.g. urxvt only has "urxvt"). Currently this option is only useful for bspwm, and it does not matter whether the class or classname (which bspwm calls an instance name) is provided, so the user does not really need to worry about the distinction.
|
||||||
|
.TP
|
||||||
|
\fB --name=NAME\fR
|
||||||
|
This option only applies for dropdowns (not auto-hiding and auto-showing). Set a new name for the dropdown window (see _NET_WM_NAME and WM_NAME in xprop output). This option may be useful if you want to add specific rules just for dropdowns with a program like compton by giving them a common title. (default: none)
|
||||||
|
.TP
|
||||||
|
\fB --clear\fR
|
||||||
|
Used to clear a saved window id for the given program or 'current' instead of creating a dropdown. Takes no argument.
|
||||||
|
.TP
|
||||||
|
\fB --no-cancel\fR
|
||||||
|
Specifies that manually re-showing an auto-hidden window with tdrop should not cancel an auto_show. Takes no argument. See the examples.
|
||||||
|
\fB --timeout\fR
|
||||||
|
Specifies the timeout in to wait for a window to appear when starting a program before giving up. This prevents a tdrop process from sticking around forever if a program fails to start. (default: 10)
|
||||||
|
.TP
|
||||||
|
\fB --help\fR
|
||||||
|
Print basic help information. Takes no argument.
|
||||||
|
|
||||||
|
.SH EXAMPLES
|
||||||
|
.SS Making Dropdowns
|
||||||
|
Use a key binding program such as sxhkd to bind keys to these commands.
|
||||||
|
|
||||||
|
The simplest example to make a dropdown for an xterm:
|
||||||
|
.br
|
||||||
|
$ tdrop xterm
|
||||||
|
|
||||||
|
When using a tiling window manager like bspwm, dropdowns like guake will by default be tiled instead of floated. One can create a rule to float every instance of guake or another dropdown. However, one may not want to float every instance of a terminal used with tdrop. Tdrop allows the user to run their own commands at various points during execution, for example before mapping the window:
|
||||||
|
.br
|
||||||
|
$ tdrop -p "bspc rule -a xterm -o floating=on" xterm
|
||||||
|
|
||||||
|
Tdrop also provides tested settings for certain window managers. One can use the '-a' flag if settings exist for the current window manager. For example, if bspwm is the window manager, the following command is the same as the above command and will work for whatever terminal/program is specified and will also work with 'tdrop auto_show'. For a list of window managers with tested settings see the readme or the script itself.
|
||||||
|
.br
|
||||||
|
$ tdrop -a xterm
|
||||||
|
|
||||||
|
Tdrop supports controlling the initial size and placement of a terminal. The border of a window may need to be taken into an account. For example, I use a border size of 2, so I use 4 less than my screen size. I also use a y-offset of 14 so that the dropdown doesn't hide my panel:
|
||||||
|
.br
|
||||||
|
$ tdrop -a -w 1362 -y 14 xterm
|
||||||
|
|
||||||
|
Tdrop can also create a tmux session if it does not exist:
|
||||||
|
.br
|
||||||
|
$ tdrop -a -w 1362 -y 14 -s dropdown xterm
|
||||||
|
|
||||||
|
Tdrop allows for having multiple dropdowns of the same type:
|
||||||
|
.br
|
||||||
|
$ tdrop xterm
|
||||||
|
.br
|
||||||
|
$ tdrop -n 1 xterm
|
||||||
|
.br
|
||||||
|
$ tdrop -n 2 xterm
|
||||||
|
.br
|
||||||
|
...
|
||||||
|
|
||||||
|
Tdrop works with normal windows (with some potential visual annoyance, see BUGS):
|
||||||
|
.br
|
||||||
|
$ tdrop zathura
|
||||||
|
.br
|
||||||
|
# the current window
|
||||||
|
.br
|
||||||
|
$ tdrop current
|
||||||
|
|
||||||
|
Once a window is turned into a dropdown, the key bound to 'tdrop ... current' will continue to toggle that window until it is closed. Then the key can be used to create a new dropdown. '-n' can also be used to have multiple 'current' keys. If an active window is accidentally turned into a dropdown, it can be cleared:
|
||||||
|
.br
|
||||||
|
$ tdrop --clear current
|
||||||
|
.br
|
||||||
|
# clear a specific number
|
||||||
|
.br
|
||||||
|
$ tdrop -n 1 --clear current
|
||||||
|
|
||||||
|
.SS Auto-hiding/showing
|
||||||
|
These example will work even for non-dropdown terminals.
|
||||||
|
|
||||||
|
Tdrop provides the functionality to get programs/terminals out of the way when opening other programs. For example, when opening an image viewer from a normal floating dropdown, the dropdown will be over the image viewer. This requires an extra hotkey press to hide the dropdown. If one wants to return to the dropdown after looking at images, the hotkey must be once again invoked. Tdrop allows for this process to be automated.
|
||||||
|
|
||||||
|
For example, this could be added to a shell's config/startup file:
|
||||||
|
.br
|
||||||
|
hide_on_open() { tdrop -a auto_hide; "$@" && tdrop -a auto_show }
|
||||||
|
|
||||||
|
To use it in an alias when writing a commit message in an graphical $EDITOR started from a terminal:
|
||||||
|
.br
|
||||||
|
alias gc='hide_on_open git commit'
|
||||||
|
|
||||||
|
This will hide the terminal window when opening the commit editor and then reshow the terminal once the editor is closed. It should also maintain the window's position and size when showing it. If the window moves down and to the right every time it is auto-hidden and then shown again, the user may need to specify a -d value. Alternatively, if one already exists for the user's window manager, -a can be used to automatically set it. The -l and -L options are also used with auto_show and can be set automatically with -a if default settings exist for the current window manager.
|
||||||
|
|
||||||
|
Note that for tiling window managers that support 'tdrop -a auto_show', reshowing a window will always float the window (even if it was orignally tiled) if -i is not specified. To prevent this, also use 'tdrop -a auto_hide' if your window manager is supported. Otherwise, -i must be manually specified with auto_hide.
|
||||||
|
|
||||||
|
This functionality might lead to some unwanted "re-shows" of dropdown. Consider a situation in which one opens an image viewer from a dropdown and leaves it open for a while, resuming normal use of the dropdown. When the image viewer is closed, the dropdown appears, unwanted. Tdrop is smart about this and won't "re-show" a dropdown if it has been manually toggled since an auto-hide. If you don't want this check to happen, use '--no-cancel' in your dropdown key binding.
|
||||||
|
|
||||||
|
Auto-hiding functionality is particularly nice to use with a file opener like rifle:
|
||||||
|
.br
|
||||||
|
mime ^image, has sxiv, X, flag f = tdrop auto_hide ; sxiv -a -- "$@" && tdrop -a auto_show
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
If -y is set to 0, a window may be subsequently moved to the middle when showing/mapping it with xdotool. This may have to do with the window border.
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
Fox Kiester <noct at posteo\&.net>
|
||||||
|
.br
|
||||||
|
Source: https://github.com/noctuid/tdrop
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
xdotool(1), sxhkd(1), xprop(1), xwininfo(1), tmux(1)
|
||||||
|
|
Loading…
Reference in New Issue