Add most recent X session management scritps - scripts - various script and utils
HTML git clone git://z3bra.org/scripts
DIR Log
DIR Files
DIR Refs
---
DIR commit f07507e039ebeb92776c05587b6bba09d623b374
DIR parent 208c003045d0a5f28e9e8f7d5840d5d116cd7df5
HTML Author: Willy Goiffon <dev@z3bra.org>
Date: Thu, 20 Aug 2026 22:02:56 +0000
Add most recent X session management scritps
Diffstat:
A wmutils/x-alttab | 30 ++++++++++++++++++++++++++++++
A wmutils/x-center | 17 +++++++++++++++++
A wmutils/x-desktop | 15 +++++++++++++++
A wmutils/x-expand | 56 +++++++++++++++++++++++++++++++
A wmutils/x-maximize | 26 ++++++++++++++++++++++++++
A wmutils/x-monitors | 7 +++++++
A wmutils/x-moveresize | 37 +++++++++++++++++++++++++++++++
A wmutils/x-rotate | 4 ++++
A wmutils/x-wait | 0
A wmutils/x-widgets | 180 +++++++++++++++++++++++++++++++
10 files changed, 372 insertions(+), 0 deletions(-)
---
DIR diff --git a/wmutils/x-alttab b/wmutils/x-alttab
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+usage() {
+ echo "usage: $(basename $0) [-frh]" >&2
+}
+
+cur=$(pdw)
+top=$(lsw|head -n1)
+bot=$(lsw|tail -n1)
+prv=$(lsw|grep -B1 $cur|sed 2d)
+nxt=$(lsw|grep -A1 $cur|sed 1d)
+
+wid=${nxt:-$top}
+while getopts 'frh' OPT; do
+ case $OPT in
+ f) wid=${nxt:-$top} ;;
+ r) wid=${prv:-$bot} ;;
+ h) usage; exit ;;
+ esac
+done
+
+[ -z "$wid" ] && exit 1
+
+wattr whxyb $wid | {
+ read w h x y b
+ wmp -a $((x + w - 16)) $((y + h - 16))
+}
+
+chwso -r $wid
+wtf $wid
DIR diff --git a/wmutils/x-center b/wmutils/x-center
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+wid=${1:-$(pfw)}
+
+sw=$(randr|head -n1|cut -f2)
+sh=$(randr|head -n1|cut -f3)
+sx=$(randr|head -n1|cut -f4)
+sy=$(randr|head -n1|cut -f5)
+
+wattr whb "$wid" | {
+ read w h b
+ x=$(( (sw-w-b)/2 + sx ))
+ y=$(( (sh-h-b)/2 + sy ))
+ chwso -r $wid
+ wtp $x $y $w $h $wid
+ wmp $((x + w - 2*b)) $((y + h - 2*b))
+}
DIR diff --git a/wmutils/x-desktop b/wmutils/x-desktop
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+atom="DESKTOP_WINDOWS"
+root="$(lsw -r)"
+
+winlist="$(atomx $atom $root)"
+
+if [ -n "$winlist" ]; then
+ atomx -d $atom $root
+else
+ winlist="$(lsw)"
+ atomx ${atom}="$winlist" $root >/dev/null
+fi
+
+mapw -t $winlist
DIR diff --git a/wmutils/x-expand b/wmutils/x-expand
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# Expand window in the direction specified until it reach the monitor side
+
+usage() {
+ echo "usage: $(basename $0) wid [direction]" >&2
+}
+
+expand() {
+ # current window size
+ b="$(wattr b $1)"
+ w="$(wattr w $1)"
+ h="$(wattr h $1)"
+ x="$(wattr x $1)"
+ y="$(wattr y $1)"
+
+ # monitor size / position
+ mx="$(randr $1 | cut -f 4 | head -n 1)"
+ my="$(randr $1 | cut -f 5 | head -n 1)"
+ mw="$(randr $1 | cut -f 2 | head -n 1)"
+ mh="$(randr $1 | cut -f 3 | head -n 1)"
+
+ case $2 in
+ n) h=$((y + h)); y=$my ;;
+ s) h=$((mh - y - 2*b)) ;;
+ w) w=$((x - mx + w)); x=$mx ;;
+ e) w=$((mw + mx - x - 2*b)) ;;
+ esac
+
+ wtp $x $y $w $h $1
+ wtf $wid
+}
+
+
+while getopts 'nswe' OPT; do
+ case $OPT in
+ n|s|w|e) direction=$OPT ;;
+ h) usage; exit 0 ;;
+ *) usage; exit 1 ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+cur=$(pdw)
+wid=${1:-$cur}
+
+[ -z "$wid" ] && { usage; exit 1; }
+
+if [ -n "$direction" ]; then
+ expand $wid $direction
+else
+ expand $wid n
+ expand $wid s
+ expand $wid w
+ expand $wid e
+fi
DIR diff --git a/wmutils/x-maximize b/wmutils/x-maximize
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# Make the current window cover the whole monitor, or change it back to
+# its previous size if it's already maxed out
+
+cur=$(pdw)
+wid=${1:-$cur}
+gap=2
+atom="WM_ORIG_SIZE"
+
+[ -z "$wid" ] && exit 1
+
+size="$(atomx $atom $wid)"
+if [ -n "$size" ]; then
+ wtp $size $wid
+ atomx -d $atom $wid
+else
+ wattr xywhb $wid | { read x y w h b
+ randr | { read mn mw mh mx my md
+
+ # take gap/border size into account
+ atomx ${atom}="$x $y $w $h" $wid > /dev/null
+ wtp $((mx + gap)) $((my + gap)) $((mw - 2*(b+gap))) $((mh - 2*(b+gap))) $wid
+ }
+ }
+fi
DIR diff --git a/wmutils/x-monitors b/wmutils/x-monitors
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+case $(lsusb | grep -Eo '(05e3:0608|0424:2807)') in
+05e3:0608) external ;;
+0424:2807) dock ;;
+*) undock ;;
+esac
DIR diff --git a/wmutils/x-moveresize b/wmutils/x-moveresize
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+usage() {
+ echo "usage: $(basename $0) -mr [-hxy] [-s size] wid" >&2
+}
+
+x=0
+y=0
+step=10
+bin=
+
+while getopts "xymrs:h" OPT; do
+ case $OPT in
+ m) bin=wmv ;;
+ r) bin=wrs ;;
+ s) step=$OPTARG ;;
+ x) x='' ;;
+ y) y='' ;;
+ h) usage; exit 0 ;;
+ *) usage; exit 1 ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+wid=$1
+
+[ -z "$wid" ] && { usage; exit 1; }
+[ -z "$bin" ] && { usage; exit 1; }
+[ -z "$x" ] && x=$step
+[ -z "$y" ] && y=$step
+
+chwso -r $wid
+wmp -a -- $(wattr xy $wid)
+wmp -r -- $(wattr wh $wid)
+wmp -r -- -10 -15
+$bin $x $y $wid
+wmp -r -- $x $y
DIR diff --git a/wmutils/x-rotate b/wmutils/x-rotate
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+xrandr --output DP-1-2 --rotate ${1:-right}
+xrandr --output DP-1-1 --pos 0x385
DIR diff --git a/wmutils/x-wait b/wmutils/x-wait
Binary files differ.
DIR diff --git a/wmutils/x-widgets b/wmutils/x-widgets
@@ -0,0 +1,180 @@
+#!/bin/sh
+
+bg=${BG_COLOR:-#00000000}
+fg=${FG_COLOR:-#ff000000}
+fn1='Monospace:size=12:antialias=true:autohint=true'
+fn2='Monospace:weight=bold:size=12:antialias=true:autohint=true'
+
+usage() {
+ echo "usage: $(basename $0) [-hr] [-xy pos] [-fb color]" >&2
+}
+
+reload() {
+ pkill lemonbar
+ exec $0
+}
+
+clock() {
+ while pgrep widgets >/dev/null; do
+ printf '%%{T2}%s %%{T-}%s\n' "$(LANG=fr_FR.UTF-8 date '+%a %d')" "$(date +%H:%M)"
+ sleep 60
+ done
+}
+
+palovpn() {
+ while pgrep widgets >/dev/null; do
+ vpn="$(</dev/null timeout 5s globalprotect show --status | tr A-Z a-z | grep -Eo 'status: .*' | cut -d' ' -f2)"
+ printf '%%{T2}vpn %%{T-}%s\n' ${vpn:-down}
+ sleep 10
+ done
+}
+
+ifname() {
+ if=$(ip route | grep '^default' | head -n1 | cut -d ' ' -f5)
+ case $if in
+ bond0) cat /sys/class/net/$if/bonding/active_slave ;;
+ *) printf '%s\n' "$if"
+ esac
+}
+
+network() {
+ while pgrep widgets >/dev/null; do
+ if=$(ifname)
+ case $if in
+ en*) printf '%%{T2}wired %%{T-}%s\n' $if ;;
+ wl*)
+ rfkill="$(LC_ALL=C rfkill -r | grep wlan | cut -d ' ' -f 4)"
+ if [ "$rfkill" = "blocked" ]; then
+ ssid="BLOCKED"
+ else
+ ssid=$(iw dev $if link|sed -n 's/.*SSID: //p')
+ fi
+ printf '%%{T2}ssid %%{T-}%s\n' "${ssid:--}"
+ ;;
+ *) printf '%%{T2}network %%{T-}down\n' ;;
+ esac
+ sleep 1
+ done
+}
+
+# click on volume to toggle it
+# mouse scroll on volume to increase/decrease
+# require scripts named "speakers" and "microphone" to be in $PATH to work
+sound() {
+ dev=$1
+ while pgrep widgets >/dev/null; do
+ printf '%%{T2}%s %%{T-}%%{+u}' $dev
+ printf '%%{A:%s toggle:}' $dev
+ printf '%%{A4:%s +5%%:}' $dev
+ printf '%%{A5:%s -5%%:}' $dev
+ printf ' %s %%{A}%%{A}%%{A}%%{-u}\n' "$($dev)"
+ sleep 1
+ done
+}
+
+battery() {
+ while pgrep widgets >/dev/null; do
+ lvl="$(cat /sys/class/power_supply/$1/capacity)"
+ ac="$(cat /sys/class/power_supply/$1/status)"
+ case $ac in
+ Charging) ac='+' ;;
+ *) ac='' ;;
+ esac
+ printf '%%{T2}juice %%{T-}%d%%%c\n' "$lvl" "$ac"
+ sleep 10
+ done
+}
+
+cpufreq() {
+ while pgrep widgets >/dev/null; do
+ mode=$(cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor|uniq)
+ freq=$(</proc/cpuinfo awk 'BEGIN{print "3k"} /MHz/{print $4} END{print "+++++++++++++++++++++ 1000000* 21/ p"}'|dc)
+ printf '%%{T2}cpu %%{T-}%sHz (%%{+u}' "$(SCALE=1 human ${freq})"
+ case $mode in
+ powersave) name="chill"; gov="performance";;
+ performance) name="boost"; gov="powersave";;
+ *) name="idk";;
+ esac
+ printf '%%{A:doas cpupower -c 0-21 frequency-set -g %s:}%s%%{A}%%{-u})\n' "$gov" "$name"
+ sleep 2
+ done
+}
+
+desktop_groups() {
+ while pgrep widgets >/dev/null; do
+ groups="$(gm -l | sort | sed -r 's,GM_([0-9]+),\1,' | tr '\n' ' ')"
+ if [ -n "$groups" ]; then
+ printf '%%{T2}groups %%{T-}%s\n' "$groups"
+ else
+ printf '%%{T2}groups %%{T-}none\n'
+ fi
+ sleep 2
+ done
+}
+
+meetings() {
+ n=$(remind -naa $HOME/.reminders | grep ^$(date +%Y/%m/%d) | wc -l)
+ [ "$n" -eq 0 ] && return
+ [ "$n" -gt 1 ] && c=s
+
+ printf '(%%{T2}%%{A:meetings:}%d event%s%%{A}%%{T-})\n' "$n" "$c"
+}
+
+time_tracker() {
+ while pgrep widgets >/dev/null; do
+ if ! flock -n $HOME/.cache/tt/.lock true; then
+ msg="$(awk -F '[][]' '{print $1 $2}' $HOME/.cache/tt/current)"
+ printf '%%{T2}kpi%%{T-} %s\n' "$msg"
+ else
+ printf '%%{T2}kpi %%{T-} untracked\n'
+ fi
+ sleep 5
+ done
+}
+
+mailbox() {
+ mh=$HOME/lib/mail
+ box=${1:-inbox}
+ while pgrep widgets >/dev/null; do
+ total=$(mlist $mh/$box | wc -l)
+ unread=$(mlist -s $mh/$box | wc -l)
+ printf '%%{T2}%s %%{T-}%d/%d %s\n' $box $unread $total "$(meetings)"
+ sleep 5
+ done
+}
+
+traffic() {
+ if=${1:-$(ifname)}
+ sbm -t -i $if | while read rx tx rxpps txpps; do
+ printf '%%{T2}traffic ↓↑ %%{T-}%s/%s %s\n' $(human $rx) $(human $tx)
+ done
+}
+
+x=32
+y=28
+
+while getopts "hx:y:f:b:" OPT; do
+ case $OPT in
+ r) reload; exit 0;;
+ x) x=$OPTARG;;
+ y) y=$OPTARG;;
+ f) fg=$OPTARG;;
+ b) bg=$OPTARG;;
+ h) usage; exit 0;;
+ *) usage; exit 1;;
+ esac
+done
+
+y=$((y + 28)); battery BAT0 | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+y=$((y + 28)); sound speakers | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y | sh &
+y=$((y + 28)); sound microphone | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y | sh &
+y=$((y + 28)); cpufreq | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y | sh &
+#y=$((y + 28)); traffic $(ifname)| lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+#y=$((y + 28)); desktop_groups | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+y=$((y + 28)); palovpn gpd0 | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+y=$((y + 28)); time_tracker | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+y=$((y + 28)); network | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+y=$((y + 28)); mailbox inbox | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y | sh &
+y=$((y + 28)); clock | lemonbar -db -U "$fg" -B "$bg" -F "$fg" -f "$fn1" -f "$fn2" -g 300x28+$x+$y &
+
+wait