Improve performance

- Prefer builtins where possible
  - Use builtin math for percent_of_total
  - Use parameter expansion instead of awk where possible
  - Query specific property that want for xprop instead of using awk
- Avoid extra call to get_window_manager
- Use xrandr's --current flag (doesn't poll for hardware changes; ~0.01 second vs. 0.075 seconds on my comupter)
- Get current monitor name from bspc directly without parsing

Addresses #36.
performance
Fox Kiester 5 years ago
parent d74150f01f
commit 216070e29e
No known key found for this signature in database
GPG Key ID: 316E205D6017DBFF

98
tdrop

@ -199,17 +199,11 @@ fi
# non-user-settable global vars # non-user-settable global vars
wid= 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 # * Multiple Monitor Automatic Re-Sizing
percent_of_total() { # percent total percent_of_total() { # percent total
gawk "BEGIN {printf(\"%.0f\", 0.01*${1%\%}*$2)}" # gawk "BEGIN {printf(\"%.0f\", 0.01*${1%\%}*$2)}"
echo $((${1%\%} * ${2} / 100))
} }
# acts on globals # acts on globals
@ -243,6 +237,21 @@ convert_geometry_to_pixels() {
fi 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() { update_geometry_settings_for_monitor() {
# 1. Correctly interpret width/height percentages when there exist multiple # 1. Correctly interpret width/height percentages when there exist multiple
# monitors so an initially created dropdown is the correct size (xdotool # monitors so an initially created dropdown is the correct size (xdotool
@ -253,12 +262,11 @@ update_geometry_settings_for_monitor() {
# it is conceivable that a user may want to use -m but not -a, so # it is conceivable that a user may want to use -m but not -a, so
# get the wm from within this function # get the wm from within this function
local wm current_monitor local current_monitor
wm=$(get_window_manager)
if [[ $wm == bspwm ]]; then if [[ $wm == bspwm ]]; then
current_monitor=$(bspc query -T -m | grep -Po '^{"name":.*?",' | \ current_monitor=$(bspc query --names --monitors --monitor)
gawk -F ":" '{gsub("[\",]", ""); print $2}')
elif [[ $wm == i3 ]]; then elif [[ $wm == i3 ]]; then
# TODO use jq if installed
# I'd rather not make jq a dependency # I'd rather not make jq a dependency
current_monitor=$(i3-msg -t get_workspaces | sed 's/{"num"/\n/g' | \ current_monitor=$(i3-msg -t get_workspaces | sed 's/{"num"/\n/g' | \
gawk -F ',' '/focused":true/ {sub(".*output",""); gsub("[:\"]",""); print $1}') gawk -F ',' '/focused":true/ {sub(".*output",""); gsub("[:\"]",""); print $1}')
@ -266,12 +274,9 @@ update_geometry_settings_for_monitor() {
local monitor_geo x_begin y_begin x_width y_height local monitor_geo x_begin y_begin x_width y_height
if [[ -n $current_monitor ]]; then if [[ -n $current_monitor ]]; then
monitor_geo=$(xrandr --query | \ monitor_geo=$(xrandr --current | \
gawk "/^$current_monitor/ {gsub(\"primary \",\"\"); print \$3}") gawk "/^$current_monitor/ {gsub(\"primary \",\"\"); print \$3}")
x_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $2}') split_geometry "$monitor_geo"
y_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $3}')
x_width=$(echo "$monitor_geo" | gawk -F 'x' '{print $1}')
y_height=$(echo "$monitor_geo" | gawk -F 'x|+' '{print $2}')
else else
local current_x current_y monitors_info x_end y_end local current_x current_y monitors_info x_end y_end
if ! $pointer_monitor_detection; then if ! $pointer_monitor_detection; then
@ -287,25 +292,24 @@ update_geometry_settings_for_monitor() {
current_x=$(echo "$wininfo" | gawk '/Absolute.*X/ {print $4}') current_x=$(echo "$wininfo" | gawk '/Absolute.*X/ {print $4}')
current_y=$(echo "$wininfo" | gawk '/Absolute.*Y/ {print $4}') current_y=$(echo "$wininfo" | gawk '/Absolute.*Y/ {print $4}')
else else
# shellcheck disable=SC2034
local X Y SCREEN WINDOW
# determine current monitor using pointer location # determine current monitor using pointer location
local pointerinfo eval "$(xdotool getmouselocation --shell)"
pointerinfo=$(xdotool getmouselocation --shell) current_x=X
current_x=$(echo "$pointerinfo" | sed -n 's/X=//p') current_y=Y
current_y=$(echo "$pointerinfo" | sed -n 's/Y=//p')
fi fi
monitors_info=$(xrandr --query | gawk '/ connected/ {gsub("primary ",""); print}') monitors_info=$(xrandr --current | gawk '/ connected/ {gsub("primary ",""); print}')
while read -r monitor; do while read -r monitor; do
monitor_geo=$(echo "$monitor" | gawk '{print $3}') monitor_geo=$(echo "$monitor" | gawk '{print $3}')
if [[ $monitor_geo =~ ^[0-9]+x[0-9]+\+[0-9]+\+[0-9]+$ ]]; then if [[ $monitor_geo =~ ^[0-9]+x[0-9]+\+[0-9]+\+[0-9]+$ ]]; then
x_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $2}') split_geometry "$monitor_geo"
y_begin=$(echo "$monitor_geo" | gawk -F '+' '{print $3}')
x_width=$(echo "$monitor_geo" | gawk -F 'x' '{print $1}')
y_height=$(echo "$monitor_geo" | gawk -F 'x|+' '{print $2}')
x_end=$((x_begin+x_width)) x_end=$((x_begin+x_width))
y_end=$((y_begin+y_height)) y_end=$((y_begin+y_height))
if [[ $current_x -ge $x_begin ]] && [[ $current_x -lt $x_end ]] && \ if [[ $current_x -ge $x_begin ]] && [[ $current_x -lt $x_end ]] && \
[[ $current_y -ge $y_begin ]] && [[ $current_y -lt $y_end ]]; then [[ $current_y -ge $y_begin ]] && [[ $current_y -lt $y_end ]]; then
current_monitor=$(echo "$monitor" | gawk '{print $1}') # current_monitor=$(echo "$monitor" | gawk '{print $1}')
current_monitor=${monitor%% *}
break break
fi fi
fi fi
@ -327,16 +331,15 @@ map_and_reset_geometry() {
} }
# * WM Detection and Hooks # * 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 | \
gawk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}')" \
-f _NET_WM_NAME 8u | gawk -F "\"" '/WM_NAME/ {print $2}' | head -n 1
}
set_wm() { set_wm() {
if ! $user_set_wm && $auto_detect_wm; then if ! $user_set_wm && $auto_detect_wm; then
wm=$(get_window_manager) 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 fi
} }
@ -502,7 +505,11 @@ unmap() {
# * General Helper Functions # * General Helper Functions
get_class_name() { get_class_name() {
xprop -id "$1" WM_CLASS 2> /dev/null | gawk '{gsub(/"/, ""); print $4}' local class
class=$(xprop -id "$1" WM_CLASS 2> /dev/null)
class=${class##* }
class=${class//\"/}
echo "$class"
} }
get_visibility() { get_visibility() {
@ -640,12 +647,23 @@ current_create() {
} }
wid_toggle() { 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 # deal with percentages/negatives when no -m
if ! $monitor_aware; then if ! $monitor_aware; then
local total_geo total_width total_height local total_geo total_width total_height
total_geo=$(xwininfo -root | gawk '/geometry/ {print $2}') total_geo=$(xwininfo -root | gawk '/geometry/ {gsub("+*",""); print $2}')
total_width=$(echo "$total_geo" | gawk -F 'x' '{print $1}') # total_width=$(echo "$total_geo" | gawk -F 'x' '{print $1}')
total_height=$(echo "$total_geo" | gawk -F 'x|+' '{print $2}') 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" convert_geometry_to_pixels "$total_width" "$total_height"
fi fi
# get saved window id if already created # get saved window id if already created
@ -656,7 +674,7 @@ wid_toggle() {
if [[ -n $wid ]]; then if [[ -n $wid ]]; then
visibility=$(get_visibility "$wid") visibility=$(get_visibility "$wid")
# sometimes xwininfo will still report a window as existing hence xprop check # sometimes xwininfo will still report a window as existing hence xprop check
if [[ -z $visibility ]] || [[ -z $(xprop -id "$wid" 2> /dev/null) ]]; then if [[ -z $visibility ]] || ! xprop -id "$wid" &> /dev/null; then
# window no longer exists # window no longer exists
exists=false exists=false
# shellcheck disable=SC2188 # shellcheck disable=SC2188

Loading…
Cancel
Save