#!/usr/bin/env bash ################################################################################ # # Small script using `xrandr` and `fzf` to quickly select connected monitors. # # TODO: # - Add possibility to not only mirror onto all outputs but use the total # screen space. ################################################################################ command -v xrandr &>/dev/null || exit 1 command -v fzf &>/dev/null || exit 1 xrandr_q="$(xrandr -q)" # Get outputs currently in use as regex matching either one (e.g. `HDMI-0|DP-0`) in_use="$( <<<"$xrandr_q" \ tac | # Reverse for non-greedy matches sed -En '/\*/,/ connected/p' | # lines from selected config to it's name grep -Po '^.*(?= connected)' | # only the name tr '\n' '|' # format into regex )" in_use="${in_use%|}" # remove trailing `|` # Get all outputs in a table in the form ` [*]` formatted="$(<<<"$xrandr_q" \ grep -wA1 connected | # output line and highest res awk '{ print $1 }' | # only name and resolution grep -ve -- | # remove grep's match separator paste - - | # join name and res sed -E "s/($in_use).*/&\t*/" | # append `*` to all in-use column -t # tabularize )" # Select all outputs to-use selected=( $(<<<"$formatted" \ fzf -m --cycle --header "Select outputs" | # select cut -d' ' -f1 # only output name ) ) # Abort if nothing was selected (( ${#selected[@]} )) || exit 1 # Regex to match either one of the selected outputs selected_regex="$(<<<"${selected[@]}" tr ' ' '|')" # Gather non-selected outputs non_selected=( $(<<<"$xrandr_q" \ grep connected | # list lines with output ({,dis}connected) grep -Ev "$selected_regex" | # filter out selected ones cut -d' ' -f1 # only output name ) ) # Choose primary primary="$(<<<"$formatted" \ grep -E "$selected_regex" | # use formatted for more information fzf --cycle --select-1 --header "Select primary" | cut -d' ' -f1 # name only )" [[ $primary ]] || exit 1 # Build the `xrandr` command xrandr_cmd=(xrandr) for out in "${selected[@]}"; do xrandr_cmd+=(--output "$out" --rotate normal --auto) [[ $out != $primary ]] || xrandr_cmd+=(--primary) done for out in "${non_selected[@]}"; do xrandr_cmd+=(--output "$out" --off) done # Print for debugging purposes and finally execute it printf "%s\n" "${xrandr_cmd[*]}" "${xrandr_cmd[@]}"