mirror of https://gitlab.com/dabruh/dotfiles.git
Make xmonconf configuration file driven
This commit is contained in:
parent
90b7fc35d2
commit
f7292d6958
|
@ -0,0 +1,78 @@
|
|||
displayConfig:
|
||||
- name: "Work"
|
||||
requiredUsbDevices: # Group of USB devices that are required to be connected to the system. All devices in a group must be connected for the display config to be applied
|
||||
- require: all
|
||||
match: exact
|
||||
group:
|
||||
- "HP, Inc HP USB-C Universal Dock"
|
||||
|
||||
requiredOutputs: # Group of outputs that are required to be connected to the system. All outputs in a group must be connected for the display config to be applied
|
||||
- group:
|
||||
- "eDP-1"
|
||||
- "DVI-I-1-1"
|
||||
- "DVI-I-2-2"
|
||||
- group:
|
||||
- "eDP-1"
|
||||
- "DVI-I-2-2"
|
||||
- "DVI-I-3-3"
|
||||
outputs: # The order of the outputs is important as it is linked to requiredOutputs
|
||||
- mode: "1920x1200"
|
||||
rotate: "normal"
|
||||
pos: "1200x1450"
|
||||
primary: true
|
||||
- mode: "1920x1200"
|
||||
rotate: "left"
|
||||
pos: "0x0"
|
||||
- mode: "1920x1200"
|
||||
rotate: "normal"
|
||||
pos: "1200x250"
|
||||
|
||||
- name: "Home, Private Laptop"
|
||||
requiredUsbDevices:
|
||||
- require: all
|
||||
match: exact
|
||||
group:
|
||||
- "Lenovo ThinkPad USB-C Dock Audio"
|
||||
requiredOutputs:
|
||||
- group:
|
||||
- "eDP-1"
|
||||
- "DP-1-0.3"
|
||||
- "DP-1-0.1"
|
||||
outputs:
|
||||
- mode: "2560x1440"
|
||||
rotate: "normal"
|
||||
pos: "0x480"
|
||||
primary: true
|
||||
- mode: "3440x1440"
|
||||
rotate: "normal"
|
||||
pos: "2560x480"
|
||||
- mode: "1920x1200"
|
||||
rotate: "right"
|
||||
pos: "6000x0"
|
||||
|
||||
- name: "Home, Work Laptop"
|
||||
requiredUsbDevices:
|
||||
- require: all
|
||||
match: exact
|
||||
group:
|
||||
- "Lenovo ThinkPad USB-C Dock Audio"
|
||||
requiredOutputs:
|
||||
- group:
|
||||
- "DP-3-3"
|
||||
- "eDP-1"
|
||||
- "DP-3-1"
|
||||
- group:
|
||||
- "DP-1-3"
|
||||
- "eDP-1"
|
||||
- "DP-1-1"
|
||||
outputs:
|
||||
- mode: "3440x1440"
|
||||
rotate: "normal"
|
||||
pos: "0x480"
|
||||
- mode: "1920x1200"
|
||||
rotate: "normal"
|
||||
pos: "3440x720"
|
||||
primary: true
|
||||
- mode: "1920x1200"
|
||||
rotate: "right"
|
||||
pos: "5360x0"
|
|
@ -3,15 +3,131 @@
|
|||
|
||||
# This script is used to apply monitor profiles based on the connected monitors and USB devices.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Source the utility functions
|
||||
source ~/.local/share/dabruh/libs/bash/x.sh
|
||||
source ~/.local/share/dabruh/libs/bash/i3.sh
|
||||
source ~/.local/share/dabruh/libs/bash/usb.sh
|
||||
|
||||
# Function to check if USB devices exist
|
||||
check_usb_devices() {
|
||||
local config_index=$1
|
||||
local config_file=$2
|
||||
|
||||
local required_usb_device_list_count
|
||||
required_usb_device_list_count=$(yq e ".displayConfig[$config_index].requiredUsbDevices | length" "$config_file")
|
||||
|
||||
for i in $(seq 0 $((required_usb_device_list_count - 1))); do
|
||||
local required_usb_devices
|
||||
required_usb_devices=$(yq e -o=j -I=0 ".displayConfig[$config_index].requiredUsbDevices[$i]" "$config_file")
|
||||
echo "Required USB devices: $required_usb_devices"
|
||||
|
||||
local required_usb_device_group_list required_usb_device_group_list_count
|
||||
required_usb_device_group_list=$(echo "$required_usb_devices" | yq e -o=j -I=0 '.group')
|
||||
required_usb_device_group_list_count=$(echo "$required_usb_device_group_list" | yq e -o=j -I=0 '. | length')
|
||||
|
||||
local require match
|
||||
require=$(echo "$required_usb_devices" | jq -r '.require')
|
||||
match=$(echo "$required_usb_devices" | jq -r '.match')
|
||||
|
||||
local usb_devices=()
|
||||
for j in $(seq 0 $((required_usb_device_group_list_count - 1))); do
|
||||
local item
|
||||
item=$(echo "$required_usb_device_group_list" | jq -r ".[$j]")
|
||||
usb_devices+=("$item")
|
||||
done
|
||||
|
||||
# Call the function with the array of USB devices
|
||||
if usb_devices_exist "$require" "$match" "${usb_devices[@]}" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to check if monitors exist and return the group index for the first group that exists
|
||||
check_monitors() {
|
||||
local config_index=$1
|
||||
local config_file=$2
|
||||
|
||||
local required_output_list_count
|
||||
required_output_list_count=$(yq e ".displayConfig[$config_index].requiredOutputs | length" "$config_file")
|
||||
|
||||
for i in $(seq 0 $((required_output_list_count - 1))); do
|
||||
local required_outputs
|
||||
required_outputs=$(yq e -o=j -I=0 ".displayConfig[$config_index].requiredOutputs[$i]" "$config_file")
|
||||
|
||||
local required_output_group_list required_output_group_list_count
|
||||
required_output_group_list=$(echo "$required_outputs" | yq e -o=j -I=0 '.group')
|
||||
required_output_group_list_count=$(echo "$required_output_group_list" | yq e -o=j -I=0 '. | length')
|
||||
|
||||
local monitors=()
|
||||
for j in $(seq 0 $((required_output_group_list_count - 1))); do
|
||||
local item
|
||||
item=$(echo "$required_output_group_list" | jq -r ".[$j]")
|
||||
monitors+=("$item")
|
||||
done
|
||||
|
||||
# Call the function with the array of monitors
|
||||
if monitors_exist "${monitors[@]}" >/dev/null; then
|
||||
echo "$i" # Return the group index
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to apply the display settings
|
||||
apply_display_settings() {
|
||||
local config_index=$1
|
||||
local group_index=$2
|
||||
local config_file=$3
|
||||
|
||||
local outputs
|
||||
outputs=$(yq e -o=j -I=0 ".displayConfig[$config_index].outputs" "$config_file")
|
||||
|
||||
output_group=$(yq e -o=j -I=0 ".displayConfig[$config_index].requiredOutputs[$group_index].group" "$config_file")
|
||||
|
||||
local output_list_count
|
||||
output_list_count=$(echo "$outputs" | yq e -o=j -I=0 '. | length')
|
||||
|
||||
local args
|
||||
args=()
|
||||
|
||||
for o in $(seq 0 $((output_list_count - 1))); do
|
||||
local output_name
|
||||
output_name=$(echo "$output_group" | jq -r ".[$o]")
|
||||
|
||||
local mode rotate pos primary
|
||||
mode=$(echo "$outputs" | jq -r ".[$o].mode")
|
||||
rotate=$(echo "$outputs" | jq -r ".[$o].rotate")
|
||||
pos=$(echo "$outputs" | jq -r ".[$o].pos")
|
||||
primary=$(echo "$outputs" | jq -r ".[$o].primary // false")
|
||||
|
||||
echo "Setting $output_name to $mode, $rotate, $pos, primary=$primary"
|
||||
|
||||
args+=("--output" "$output_name" "--mode" "$mode" "--rotate" "$rotate" "--pos" "$pos")
|
||||
[ "$primary" = "true" ] && args+=("--primary")
|
||||
done
|
||||
|
||||
echo "Running xrandr ${args[*]}"
|
||||
xrandr "${args[@]}"
|
||||
}
|
||||
|
||||
# Function to parse and apply display configuration
|
||||
apply_display_config() {
|
||||
local config_index=$1
|
||||
local config_file=$2
|
||||
|
||||
check_usb_devices "$config_index" "$config_file" || return 1
|
||||
group_index=$(check_monitors "$config_index" "$config_file") || return 2
|
||||
apply_display_settings "$config_index" "$group_index" "$config_file"
|
||||
}
|
||||
|
||||
main() {
|
||||
local primary_monitor monitor_count monitors=() profile_found=false
|
||||
local config_file=$1
|
||||
local primary_monitor monitor_count profile_found=false
|
||||
primary_monitor=$(get_monitors primary | cut -d',' -f1)
|
||||
monitor_count=$(get_monitors connected | wc -l)
|
||||
echo "Monitors connected: $monitor_count"
|
||||
|
@ -20,49 +136,20 @@ main() {
|
|||
echo "Applying laptop-only profile"
|
||||
xrandr --auto
|
||||
profile_found=true
|
||||
elif usb_devices_exist all exact "HP, Inc HP USB-C Universal Dock" >/dev/null 2>&1; then
|
||||
monitors=(
|
||||
"eDP-1,DVI-I-1-1,DVI-I-2-2"
|
||||
"eDP-1,DVI-I-2-2,DVI-I-3-3"
|
||||
)
|
||||
else
|
||||
local config_count
|
||||
config_count=$(yq e '.displayConfig | length' "$config_file")
|
||||
|
||||
for monitor in "${monitors[@]}"; do
|
||||
IFS=',' read -r -a monitor_array <<<"$monitor"
|
||||
if monitors_exist "${monitor_array[@]}" >/dev/null; then
|
||||
echo "Applying work profile for ${monitor_array[*]}"
|
||||
xrandr \
|
||||
--output "${monitor_array[0]}" --mode 1920x1200 --rotate normal --pos 1200x1474 --primary \
|
||||
--output "${monitor_array[1]}" --mode 1920x1200 --rotate left --pos 0x0 \
|
||||
--output "${monitor_array[2]}" --mode 1920x1200 --rotate normal --pos 1200x274
|
||||
for i in $(seq 0 $((config_count - 1))); do
|
||||
name=$(yq e ".displayConfig[$i].name" "$config_file")
|
||||
echo "Trying profile #$i '$name'"
|
||||
if apply_display_config "$i" "$config_file"; then
|
||||
profile_found=true
|
||||
break
|
||||
else
|
||||
echo "Profile #$i '$name' failed with exit code $?" >&2
|
||||
fi
|
||||
done
|
||||
elif usb_devices_exist all exact "Lenovo ThinkPad USB-C Dock Audio" >/dev/null 2>&1; then
|
||||
monitor_array=(eDP-1 DP-1-0.3 DP-1-0.1)
|
||||
if monitors_exist "${monitor_array[@]}" >/dev/null; then
|
||||
echo "Applying home profile for ${monitor_array[*]}"
|
||||
xrandr \
|
||||
--output "${monitor_array[0]}" --mode 2560x1440 --rotate normal --pos 0x480 --primary \
|
||||
--output "${monitor_array[1]}" --mode 3440x1440 --rotate normal --pos 2560x480 \
|
||||
--output "${monitor_array[2]}" --mode 1920x1200 --rotate right --pos 6000x0
|
||||
profile_found=true
|
||||
fi
|
||||
|
||||
monitors=(
|
||||
"DP-3-3,eDP-1,DP-3-1"
|
||||
"DP-1-3,eDP-1,DP-1-1"
|
||||
)
|
||||
|
||||
for monitor in "${monitors[@]}"; do
|
||||
IFS=',' read -r -a monitor_array <<<"$monitor"
|
||||
if monitors_exist "${monitor_array[@]}" >/dev/null; then
|
||||
xrandr \
|
||||
--output "${monitor_array[0]}" --mode 3440x1440 --pos 0x480 --rotate normal \
|
||||
--output "${monitor_array[1]}" --mode 1920x1200 --pos 3440x720 --rotate normal --primary \
|
||||
--output "${monitor_array[2]}" --mode 1920x1200 --pos 5360x0 --rotate right
|
||||
profile_found=true
|
||||
fi
|
||||
echo
|
||||
done
|
||||
fi
|
||||
|
||||
|
@ -76,7 +163,12 @@ main() {
|
|||
i3-msg restart >/dev/null
|
||||
}
|
||||
|
||||
# Run if invoked directly
|
||||
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
|
||||
main
|
||||
set -euo pipefail
|
||||
config_file="${1:-$HOME/.config/dabruh/xmonconf.yaml}"
|
||||
if ! [ -f "$config_file" ]; then
|
||||
echo "Config file not found: $config_file"
|
||||
exit 1
|
||||
fi
|
||||
main "$config_file"
|
||||
fi
|
||||
|
|
|
@ -60,6 +60,7 @@ monitor_exist() {
|
|||
connected_monitors=$(get_monitors connected)
|
||||
|
||||
for connected_monitor in $connected_monitors; do
|
||||
echo "Processing monitor $connected_monitor" 1>&2
|
||||
if [ "$(cut -d',' -f1 <<<"$connected_monitor")" = "$monitor" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
@ -75,6 +76,7 @@ monitors_exist() {
|
|||
local monitor matches=0
|
||||
|
||||
for monitor in "$@"; do
|
||||
echo "Checking if monitor $monitor exists" 1>&2
|
||||
if monitor_exist "$monitor"; then
|
||||
echo "$monitor"
|
||||
matches=$((matches + 1))
|
||||
|
|
Loading…
Reference in New Issue