Skip to content

Instantly share code, notes, and snippets.

@ortango
Last active February 8, 2024 06:20
Show Gist options
  • Save ortango/f77ae3589204eef62f8e2d2fa23e2eda to your computer and use it in GitHub Desktop.
Save ortango/f77ae3589204eef62f8e2d2fa23e2eda to your computer and use it in GitHub Desktop.
#!/bin/bash
#wxh+x+y
parse_geom() {
declare -n g
g="$1"
readarray -t g < <( awk '{
split($0, a, "[x+-]", s);
printf("%d\n%d\n",a[1],a[2]);
printf("%s%d\n%s%d\n",s[2],a[3],s[3],a[4]);
}' <<<"$2")
}
max() { declare -n v; v=$1; v=$(( $v > $2 ? $v : $2 )); }
getrootgeo() { xwininfo -root | awk '$1 ~ /-geometry/{ print $2 }'; }
getbspwminfo() { bspc wm -d | jq -r '.monitors[] | [.name, .rectangle[], .padding[]]|join(" ")'; }
m2arrays() {
declare -a m
m=( $1 )
name="${m[0]}"
padding=( ${m[8]} ${m[6]} ${m[5]} ${m[7]} )
mongeo=( ${m[3]} ${m[4]} ${m[1]} ${m[2]} )
}
strut_p=( 0 0 0 0 0 0 0 0 0 0 0 0 )
fake="false"
#fake - first line is root
#root format: "wxh+x+y"
#mon format as '.monitors[] | [.name, .rectangle[], .padding[]]|join(" ")'
### "name x y width height top right bottom left"
while getopts 'f:b:m:s:' opt; do
case "$opt" in
f)
fake="true"
[[ -s "$OPTARG" ]] && {
read root_window
readarray -t mon
} <"$OPTARG"
;;
b) bar="$OPTARG";;
m) bar_monitor="$OPTARG";;
s) strutsize="$OPTARG";;
esac
done; shift $(( OPTIND -1 ))
[[ -n "$bar" && -n "$bar_monitor" ]] || exit
case "$1" in
top|bottom|left|right) placement="$1";;
*|'') exit 1;;
esac
case "$fake" in
true) [[ -n "${mon[*]}" && -n "$root_window" ]] || exit;;
false)
root_window="$(getrootgeo)"
readarray -t mon < <(getbspwminfo)
;;
esac
parse_geom rootgeo "${root_window}"
declare -a padding mongeo
match="false"
for m in "${!mon[@]}"; do
m2arrays "${mon[$m]}"
[[ "$name" == "$bar_monitor" ]] && { match=true; break; }
done
[[ -n "${rootgeo[*]}" && "$match" == "true" ]] || exit
: "${strutsize:=10}"
#bar logic:
case "$bar" in
polybar)
case "$placement" in
bottom) correction=$(( rootgeo[1] - ( mongeo[3] + mongeo[1] ) ));;
top) correction="${mongeo[3]}";;
left|right) exit 1;;
esac
max correction 0
strutsize=$(( correction + strutsize ))
case "$placement" in
bottom)
strut_p[3]=$strutsize
strut_p[10]=${mongeo[2]}
strut_p[11]=$(( mongeo[0] + mongeo[2] - 1 ))
;;
top)
strut_p[2]=$strutsize
strut_p[8]=${mongeo[2]}
strut_p[9]=$(( mongeo[0] + mongeo[2] - 1 ))
;;
esac
;;
*) exit;;
esac
printf '\nnew %s strut size to set: %d\n' "$bar" "$strutsize"
printf '\t( '; printf '%d ' "${strut_p[@]}"; printf ')\n' >&2
# rect 0=width 1=height 2=x 3=y
# padding/strut
# 0=left 1=right 2=top 3=bottom
# strut
# 4=left_start_y 5=left_end_y
# 6=right_start_y 7=right_end_y
# 8=top_start_x 9=top_end_x
# 10=bottom_start_x 11=bottom_end_x
#bspwm logic:
for m in "${!mon[@]}"; do
changed="false"
m2arrays "${mon[$m]}"
#left)
if (( mongeo[2] < strut_p[0] )) &&
(( strut_p[0] < (mongeo[2] + mongeo[0] - 1) )) &&
(( strut_p[5] >= mongeo[3] )) &&
(( strut_p[4] < (mongeo[3] + mongeo[1]) )); then
d=$(( strut_p[0] - mongeo[2] ))
if (( padding[0] < 0 )); then
(( padding[0] += d ))
else
max padding[0] $d
fi
changed="true"
fi
#right)
if (( (mongeo[2] + mongeo[0]) > (rootgeo[0] - strut_p[1]) )) &&
(( (rootgeo[0] - strut_p[1]) > mongeo[2] ))
(( strut_p[7] >= mongeo[3] )) &&
(( strut_p[6] < (mongeo[3] + mongeo[1]) )); then
d=$(( (mongeo[2] + mongeo[0]) - rootgeo[0] + strut_p[1] ))
if (( padding[1] < 0 )); then
(( padding[1] += d ))
else
max padding[1] $d
fi
changed="true"
fi
#top)
if (( mongeo[3] < strut_p[2] )) &&
(( strut_p[2] < (mongeo[3] + mongeo[1] - 1) )) &&
(( strut_p[9] >= mongeo[2] )) &&
(( strut_p[8] < (mongeo[2] + mongeo[0]) )); then
d=$(( strut_p[2] - mongeo[3] ))
if (( padding[2] < 0 )); then
(( padding[2] += d ))
else
max padding[2] $d
fi
changed="true"
fi
#bottom)
if (( (mongeo[3] + mongeo[1]) > (rootgeo[1] - strut_p[3]) )) &&
(( (rootgeo[1] - strut_p[3]) > mongeo[3] ))
(( strut_p[11] >= mongeo[2] )) &&
(( strut_p[10] < (mongeo[2] + mongeo[0]) )); then
echo "(${mongeo[3]} + ${mongeo[1]}) - ${rootgeo[1]} + ${strut_p[3]}" >&2
d=$(( (mongeo[3] + mongeo[1]) - rootgeo[1] + strut_p[3] ))
if (( padding[3] < 0 )); then
(( padding[3] += d ))
else
max padding[3] $d
fi
changed="true"
fi
if [[ "$changed" == "true" ]]; then
printf 'new padding on %s:\n' "$name"
printf '\tleft_padding: %d\n' "${padding[0]}"
printf '\tright_padding: %d\n' "${padding[1]}"
printf '\ttop_padding: %d\n' "${padding[2]}"
printf '\tbottom_padding: %d\n' "${padding[3]}"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment