master ohmu/wmutils / src / contrib / workspace.sh
ohmu  ·  2026-07-25
  1#!/bin/sh
  2# Constructs and groups windows into workspaces to switch between using your favorite keybinder.
  3
  4NUM_WS=9
  5
  6help() {
  7	cat << EOF
  8usage: $(basename $0) [-hinp] [-g ws_num] [-m ws_num]
  9	-h: Displays this message
 10	-i: Initialize workspaces. Should be called once in a startup script.
 11	-n: Move up one workspace
 12	-p: Move down one workspace
 13	-g, <ws_num>: go to the workspace specified by <ws_num>
 14	-m, <ws_num>: move the currently focused window to the worskpace specified by <ws_num>
 15EOF
 16	exit 1
 17}
 18# Initializes us in workspace 0.
 19ws_init() {
 20	mkdir -p /tmp/workspaces/
 21	i=0
 22	while [ $i -le $NUM_WS ]; do
 23		:> /tmp/workspaces/ws"$i"
 24		i=$(expr $i + 1)
 25	done
 26	echo 0 > /tmp/workspaces/curr
 27}
 28# Saves all mapped windows to the current workspace.
 29save_ws() {
 30	curr=$(cat /tmp/workspaces/curr)
 31	lsw > /tmp/workspaces/ws"$curr"
 32}
 33move_to_ws() {
 34	ws_num=$1
 35	if [ $ws_num -gt $NUM_WS ] || [ $ws_num -lt 0 ]; then
 36		echo "Workspace not found"
 37		return
 38	fi
 39	curr_ws=$(cat /tmp/workspaces/curr);
 40	if [ $ws_num == $curr_ws ]; then
 41		# same workspace. ignore flicker
 42		return
 43	fi
 44	save_ws
 45	curr_windows=$(lsw)
 46	if [ "$curr_windows" ]; then
 47		mapw -u $(lsw)
 48	fi
 49	new_windows="$(cat /tmp/workspaces/ws$ws_num)"
 50	if [ "$new_windows" ]; then
 51		mapw -m $new_windows
 52	fi
 53	echo $ws_num > /tmp/workspaces/curr
 54}
 55next_ws() {
 56	# Get what ws we're currently in.
 57	curr=$(cat /tmp/workspaces/curr)
 58	curr=$(expr $curr + 1)
 59
 60	# Take care of loopback.
 61	if [ $curr -gt $NUM_WS ]; then
 62		curr=0
 63	fi
 64
 65	move_to_ws $curr
 66}
 67prev_ws() {
 68	# Get what ws we're currently in.
 69	curr=$(cat /tmp/workspaces/curr)
 70	curr=$(expr $curr - 1)
 71
 72	# Take care of loopback.
 73	if [ $curr -lt 0 ]; then
 74		curr=$NUM_WS
 75	fi
 76
 77	move_to_ws $curr
 78}
 79move_focused_window() {
 80	ws_num=$1
 81	if [ $ws_num -gt $NUM_WS ] || [ $ws_num -lt 0 ]; then
 82		echo "Workspace not found"
 83		return
 84	fi
 85	wid=$(pfw)
 86	curr_ws=$(cat /tmp/workspaces/curr);
 87	if [ $ws_num != $curr_ws ]; then
 88		pfw >> /tmp/workspaces/ws"$1"
 89		mapw -u $wid
 90	fi
 91}
 92while getopts ":m:g:npi" opt; do
 93	case $opt in
 94		n)
 95			next_ws;;
 96		p)
 97			prev_ws;;
 98		g)
 99			move_to_ws $OPTARG;;
100		m)
101			move_focused_window $OPTARG;;
102		i)
103			ws_init;;
104		\?)
105			help;;
106	esac
107done