#!/bin/sh ## Set this values on new system! ########################################## NOTE_NAME="eDP1" DPI="96" ########################################## ## Settings SAVEPATH="/tmp/wpos" LAST_FILE="LAST" PROG_PATH="$(dirname "$0")" ## Init COMMAND="$1" EXT1_NAME="none" EXT2_NAME="none" EXT1_STATUS="disconnected" EXT2_STATUS="disconnected" ## Query current settings XRANDR="$(xrandr -q)" ## Some functions get_resolution() { grep -A1 "^$1\s*connected" | tail -n1 | awk '{ print $1 }' } detect_status() { sed -n -e "s/^$1\s*\([a-z]*\)\s*.*$/\1/p" } detect_connected() { sed -n -e 's/^\([A-Za-z0-9-]*\)\s*connected.*$/\1/p' } detect_all() { sed -n -e 's/^\([A-Za-z0-9-]*\)\s*\(dis\)*connected.*$/\1/p' } detect_active() { grep -A1 "^$1\s*connected" | tail -n1 | awk '{ print $2 }' | grep '\*' } off_except() { OFF_STRING="" for device in $(echo "$XRANDR" | detect_all); do for ignore in $@ ; do [ "$device" = "$ignore" ] && continue 2 done OFF_STRING="$OFF_STRING --output $device --off" done echo "$OFF_STRING" } handle_non_exist_mode() { xrandr --dpi "$DPI" $(off_except "$1" "$2") --output $2 --mode $4 --output $1 --mode $3 --left-of $2 } compute_hash() { INPUT="$1" NOTE_ACTIVE="$(echo "$INPUT" | detect_active "$NOTE_NAME")" HASH_DATA="${NOTE_NAME}${NOTE_STATUS}${NOTE_MAX}${NOTE_ACTIVE}" if [ -n "$EXT1_NAME" ]; then EXT1_ACTIVE="$(echo "$INPUT" | detect_active "$EXT1_NAME")" HASH_DATA="${HASH_DATA}${EXT1_NAME}${EXT1_STATUS}${EXT1_MAX}${EXT1_ACTIVE}" fi if [ -n "$EXT2_NAME" ]; then EXT2_ACTIVE="$(echo "$INPUT" | detect_active "$EXT2_NAME")" HASH_DATA="${HASH_DATA}${EXT2_NAME}${EXT2_STATUS}${EXT2_MAX}${EXT2_ACTIVE}" fi echo "$HASH_DATA" | sha1sum | awk '{ print $1 }' } ## Get notebook display status NOTE_STATUS="$(echo "$XRANDR" | detect_status "$NOTE_NAME")" ## Try to detect some external displays and theirs resolution EXT1_NAME="$(echo "$XRANDR" | grep -v "$NOTE_NAME" | detect_connected | head -n 1)" if [ -n "$EXT1_NAME" ]; then EXT1_STATUS="$(echo "$XRANDR" | detect_status "$EXT1_NAME")" EXT2_NAME="$(echo "$XRANDR" | grep -v "\($NOTE_NAME\|$EXT1_NAME\)" | detect_connected | head -n 1)" [ -n "$EXT2_NAME" ] && EXT2_STATUS="$(echo "$XRANDR" | detect_status "$EXT2_NAME")" fi NOTE_MAX="$(echo "$XRANDR" | get_resolution "$NOTE_NAME")" EXT1_MAX="$(echo "$XRANDR" | get_resolution "$EXT1_NAME")" EXT2_MAX="$(echo "$XRANDR" | get_resolution "$EXT2_NAME")" ## Save windows' positions before autodetection [ ! -d "$SAVEPATH" ] && mkdir -p "$SAVEPATH" if [ -f "$SAVEPATH"/"$LAST_FILE" ]; then "$PROG_PATH"/wpos.sh save "$(cat "$SAVEPATH"/"$LAST_FILE")" fi ## Main "profiles" logic ## Start with some special command if [ "$COMMAND" = "profile" ]; then HASH="$(compute_hash "$XRANDR")" echo "$HASH" exit 0 ## And "regular" display setting commands elif [ "$COMMAND" = "external" -a "$EXT1_STATUS" = "connected" ]; then xrandr --dpi "$DPI" $(off_except "$EXT1_NAME") --output "$EXT1_NAME" --mode "$EXT1_MAX" elif [ "$COMMAND" = "external2" -a "$EXT2_STATUS" = "connected" ]; then xrandr --dpi "$DPI" $(off_except "$EXT2_NAME") --output "$EXT2_NAME" --mode "$EXT2_MAX" elif [ "$COMMAND" = "mirror" -a "$NOTE_STATUS" = "connected" -a "$EXT1_STATUS" = "connected" ]; then if [ "$(echo "$NOTE_MAX" | cut -dx -f1)" -le "$(echo "$EXT1_MAX" | cut -dx -f1)" ]; then MUTUAL_RESOLUTION="$NOTE_MAX" else MUTUAL_RESOLUTION="$EXT1_MAX" fi xrandr --dpi "$DPI" $(off_except "$NOTE_NAME" "$EXT1_NAME") \ --output "$NOTE_NAME" --mode "$MUTUAL_RESOLUTION" \ --output "$EXT1_NAME" --mode "$MUTUAL_RESOLUTION" --same-as "$NOTE_NAME" elif [ "$COMMAND" = "2external" -a "$EXT1_STATUS" = "connected" -a "$EXT2_STATUS" = "connected" ]; then handle_non_exist_mode "$EXT2_NAME" "$EXT1_NAME" "$EXT2_MAX" "$EXT1_MAX" elif [ "$COMMAND" = "note" -a "$NOTE_STATUS" = "connected" ]; then xrandr --dpi "$DPI" $(off_except "$NOTE_NAME") --output "$NOTE_NAME" --mode "$NOTE_MAX" elif [ "$EXT1_STATUS" = "connected" -a "$NOTE_STATUS" = "connected" -a "$EXT2_STATUS" = "disconnected" ]; then handle_non_exist_mode "$EXT1_NAME" "$NOTE_NAME" "$EXT1_MAX" "$NOTE_MAX" elif [ "$EXT1_STATUS" = "connected" -a "$NOTE_STATUS" = "connected" -a "$EXT2_STATUS" = "connected" ]; then # This isn't one command, because there is some weird error in xrandr. # That is the only way that this thing works. xrandr --dpi "$DPI" $(off_except "$NOTE_NAME" "$EXT1_NAME" "$EXT2_NAME") xrandr --dpi "$DPI" --output "$NOTE_NAME" --mode "$NOTE_MAX" xrandr --dpi "$DPI" --output "$EXT1_NAME" --mode "$EXT1_MAX" --left-of "$NOTE_NAME" xrandr --dpi "$DPI" --output "$EXT2_NAME" --mode "$EXT2_MAX" --left-of "$EXT1_NAME" elif [ "$EXT2_STATUS" = "disconnected" -a "$NOTE_STATUS" = "connected" -a "$EXT1_STATUS" = "disconnected" ]; then xrandr --dpi "$DPI" $(off_except "$NOTE_NAME") --output "$NOTE_NAME" --mode "$NOTE_MAX" fi ## Query current status XRANDR="$(xrandr -q)" HASH="$(compute_hash "$XRANDR")" ## Update LAST echo "$HASH" > "$SAVEPATH"/"$LAST_FILE" ## Restore known profile if [ -f "$SAVEPATH"/"$HASH" ]; then "$PROG_PATH"/wpos.sh restore "$HASH" fi