mirror of https://gitlab.com/dabruh/dotfiles.git
138 lines
4.2 KiB
Bash
138 lines
4.2 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
# This script contains utility functions related to i3 workspaces.
|
||
|
|
||
|
# Ensure required functions exist
|
||
|
if ! command -v monitor_exist >/dev/null 2>&1; then
|
||
|
echo "monitor_exist function is required but not found. Please source x.sh before i3.sh." 1>&2
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
# Get the list of empty i3 workspaces.
|
||
|
# Usage: get_empty_i3_workspaces
|
||
|
get_empty_i3_workspaces() {
|
||
|
set -euo pipefail
|
||
|
i3-msg -t get_tree | jq -r '
|
||
|
recurse(.nodes[]?) |
|
||
|
select(.type == "workspace") |
|
||
|
select(.name | test("^[^_].*")) |
|
||
|
select(.nodes | length == 0) |
|
||
|
.name
|
||
|
'
|
||
|
}
|
||
|
|
||
|
# Check if the i3 workspace is empty.
|
||
|
# Usage: i3_workspace_is_empty <workspace_name>
|
||
|
i3_workspace_is_empty() {
|
||
|
set -euo pipefail
|
||
|
local workspace_name=${1:?Workspace name not set}
|
||
|
local empty_workspace
|
||
|
empty_workspace=$(get_empty_i3_workspaces)
|
||
|
|
||
|
for workspace in $empty_workspace; do
|
||
|
if [ "$workspace" = "$workspace_name" ]; then
|
||
|
return 0
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
# Get a comma separated list of i3 workspace names and the output they are on.
|
||
|
# Usage: get_i3_workspaces
|
||
|
get_i3_workspaces() {
|
||
|
set -euo pipefail
|
||
|
i3-msg -t get_workspaces | jq -r '.[] | .name + "," + .output'
|
||
|
}
|
||
|
|
||
|
# Get a property of an i3 workspace.
|
||
|
# Usage: get_i3_workspace_prop <workspace_name> <property>
|
||
|
get_i3_workspace_prop() {
|
||
|
set -euo pipefail
|
||
|
local workspace_name=${1:?Workspace name not set}
|
||
|
local prop=${2:?Property not set}
|
||
|
i3-msg -t get_workspaces | jq -r ".[] | select(.name == \"$workspace_name\") | .$prop"
|
||
|
}
|
||
|
|
||
|
# Check if an i3 workspace exists.
|
||
|
# Usage: i3_workspace_exists <workspace_name>
|
||
|
i3_workspace_exists() {
|
||
|
set -euo pipefail
|
||
|
local workspace_name=${1:?Workspace name not set}
|
||
|
if [[ -n "$(get_i3_workspace_prop "$workspace_name" name)" ]]; then
|
||
|
return 0
|
||
|
fi
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
# Move an i3 workspace to a different monitor.
|
||
|
# Usage: move_i3_workspace <workspace_name> <monitor_name> [increment]
|
||
|
move_i3_workspace() {
|
||
|
set -euo pipefail
|
||
|
local workspace_name=${1:?Workspace name not set}
|
||
|
local monitor_name=${2:?Monitor name not set}
|
||
|
local increment=${3:-0}
|
||
|
local new_workspace_name="$workspace_name"
|
||
|
|
||
|
if ! i3_workspace_exists "$workspace_name"; then
|
||
|
echo "Workspace $workspace_name not found" 1>&2
|
||
|
return 1
|
||
|
elif ! monitor_exist "$monitor_name"; then
|
||
|
echo "Monitor $monitor_name not found" 1>&2
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
if [[ "$(get_i3_workspace_prop "$workspace_name" output)" == "$monitor_name" ]]; then
|
||
|
echo "Workspace $workspace_name is already on monitor $monitor_name" 1>&2
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
if [[ "$workspace_name" =~ ^[0-9]+$ ]]; then
|
||
|
new_workspace_name=$((workspace_name + increment))
|
||
|
elif [ "$increment" -ne 0 ]; then
|
||
|
echo "Workspace name is not an integer. Unable to increment/decrement." 1>&2
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
if i3_workspace_exists "$new_workspace_name"; then
|
||
|
if [[ "$new_workspace_name" != "$workspace_name" ]]; then
|
||
|
echo "Workspace $new_workspace_name already exists" 1>&2
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
echo "Moving workspace $workspace_name to monitor $monitor_name as $new_workspace_name"
|
||
|
|
||
|
i3-msg "workspace $workspace_name" 1>/dev/null
|
||
|
i3-msg "rename workspace $workspace_name to $new_workspace_name" 1>/dev/null
|
||
|
i3-msg "move workspace to output $monitor_name" 1>/dev/null
|
||
|
}
|
||
|
|
||
|
# Move all workspaces to a specified monitor.
|
||
|
# Usage: move_nonexistent_i3_workspaces <monitor_name> [increment]
|
||
|
move_nonexistent_i3_workspaces() {
|
||
|
set -euo pipefail
|
||
|
local monitor_name=${1:?Monitor name not set}
|
||
|
local increment=${2:-0}
|
||
|
local workspaces
|
||
|
workspaces=$(get_i3_workspaces)
|
||
|
|
||
|
echo "Moving workspaces to monitor $monitor_name"
|
||
|
|
||
|
for workspace in $workspaces; do
|
||
|
local workspace_name
|
||
|
local workspace_output
|
||
|
workspace_name=$(echo "$workspace" | cut -d',' -f1)
|
||
|
workspace_output=$(echo "$workspace" | cut -d',' -f2)
|
||
|
|
||
|
if i3_workspace_is_empty "$workspace_name"; then
|
||
|
echo "Skipping empty workspace $workspace_name"
|
||
|
continue
|
||
|
fi
|
||
|
|
||
|
if ! monitor_exist "$workspace_output"; then
|
||
|
move_i3_workspace "$workspace_name" "$monitor_name" "$increment"
|
||
|
fi
|
||
|
done
|
||
|
}
|