#!/bin/bash # shellcheck disable=SC1090 # This script is used to apply monitor profiles based on the connected monitors and USB devices. # 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 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" if [ "$monitor_count" -eq 1 ]; then echo "Applying laptop-only profile" xrandr --auto profile_found=true else local config_count config_count=$(yq e '.displayConfig | length' "$config_file") 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 echo done fi if ! "$profile_found"; then echo "No profile found" return 1 fi disable_disconnected_monitors move_nonexistent_i3_workspaces "$primary_monitor" 10 i3-msg restart >/dev/null } if [ "$0" = "${BASH_SOURCE[0]}" ]; then 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