Skip to content

Instantly share code, notes, and snippets.

@michaelmrose
Created October 29, 2024 04:47
Show Gist options
  • Save michaelmrose/1aaf71b0d691b9be6f66d7887c5fba93 to your computer and use it in GitHub Desktop.
Save michaelmrose/1aaf71b0d691b9be6f66d7887c5fba93 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Get the list of connected monitors
connected_monitors=$(xrandr --query | grep " connected" | awk '{print $1}')
declare -A monitor_max_res
for monitor in $connected_monitors; do
# Get the preferred mode for this monitor
preferred_mode=$(xrandr --query | sed -n "/^$monitor connected/,/^[^ ]/p" | grep -Eo '[0-9]+x[0-9]+\s+\S+\s+\*' | head -n1 | awk '{print $1}')
if [ -n "$preferred_mode" ]; then
monitor_max_res["$monitor"]="$preferred_mode"
else
# If no preferred mode, use the first mode listed
modes=$(xrandr --query | sed -n "/^$monitor connected/,/^[^ ]/p" | grep -Eo '^[ ]+[0-9]+x[0-9]+' | tr -d ' ')
max_res=$(echo "$modes" | head -n1)
monitor_max_res["$monitor"]="$max_res"
fi
done
# Check if any monitors were detected
if [ "${#monitor_max_res[@]}" -eq 0 ]; then
echo "No connected monitors detected."
exit 1
fi
# Process command-line arguments
if [ "$#" -gt 0 ]; then
monitors=()
declare -A monitor_options
current_monitor=""
connected_monitors_array=("${!monitor_max_res[@]}")
for arg in "$@"; do
if [[ " ${connected_monitors_array[@]} " =~ " ${arg} " ]]; then
# It's a monitor name
current_monitor="$arg"
monitors+=("$arg")
monitor_options["$current_monitor"]=""
else
# It's an option
if [ -z "$current_monitor" ]; then
echo "Error: Option '$arg' provided before any monitor name."
exit 1
fi
monitor_options["$current_monitor"]+=" $arg"
fi
done
else
# No arguments provided, use all connected monitors
monitors=("${!monitor_max_res[@]}")
for monitor in "${monitors[@]}"; do
monitor_options["$monitor"]=""
done
fi
# Build the xrandr command
command="xrandr"
# Variables to calculate positions
x_offset=0
for monitor in "${monitors[@]}"; do
options="${monitor_options[$monitor]}"
resolution="${monitor_max_res[$monitor]}"
if [ -z "$resolution" ]; then
echo "Error: No maximum resolution found for monitor $monitor."
exit 1
fi
width=$(echo "$resolution" | cut -d'x' -f1)
height=$(echo "$resolution" | cut -d'x' -f2)
# Position calculation
position="--pos ${x_offset}x0"
# Add the monitor to the command
command+=" --output $monitor --mode $resolution $position$options"
# Update x_offset for the next monitor
x_offset=$((x_offset + width))
done
# Print the constructed command for debugging
echo "Executing command: $command"
# Execute the xrandr command
echo $command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment