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