Skip to content

Instantly share code, notes, and snippets.

@manuhabitela
Last active July 26, 2021 05:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manuhabitela/51cbdfad79a5af3dbc45f548f746e860 to your computer and use it in GitHub Desktop.
Save manuhabitela/51cbdfad79a5af3dbc45f548f746e860 to your computer and use it in GitHub Desktop.
Easy monitor switch
#!/bin/bash
# see help section below for script description
# change the four "constants" below to match your config
# this is the xrandr monitor name for the "temporary" monitors you connect often on your laptop,
# via the HDMI or VGA cable directly, for projecting on TV or whatever
DEFAULT_OTHER_MONITOR="VGA-1"
# this is the xrandr monitor name of your usual external monitor you use 99% of the time
DEFAULT_WORK_MONITOR="DP-2"
DEFAULT_POSITION="above"
INTERNAL_MONITOR="LVDS-1"
cmd="${1}"
other_monitor="${2:-$DEFAULT_OTHER_MONITOR}"
mode="${3:-$DEFAULT_POSITION}"
internal_monitor=$INTERNAL_MONITOR
work_monitor=$DEFAULT_WORK_MONITOR
active_monitors=$(xrandr | grep -E " connected (primary )?[1-9]+" | sed -e "s/\([A-Z0-9]\+\) connected.*/\1/")
if [[ $other_monitor == "above" || $other_monitor == "below" ||
$other_monitor == "left-of" || $other_monitor == "right-of" ]]; then
mode=$other_monitor
other_monitor=$DEFAULT_OTHER_MONITOR
fi
external_monitor=$other_monitor
if xrandr -q | grep -q "^$other_monitor connected"; then
external_monitor="$other_monitor"
elif xrandr -q | grep -q "^$work_monitor connected"; then
external_monitor="$work_monitor"
else
echo 'No external monitor connected.'
cmd="in"
fi
internal_is_active=0
if [[ $active_monitors == *"$internal_monitor"* ]]; then
internal_is_active=1
fi
external_is_active=0
if [[ $active_monitors == *"$external_monitor"* ]]; then
external_is_active=1
fi
current_state=""
next_state=""
if [[ $internal_is_active -eq 1 && $external_is_active -eq 1 ]]; then
current_state="all"
next_state="in"
elif [[ $internal_is_active -eq 1 ]]; then
current_state="in"
next_state="out"
else
current_state="out"
next_state="all"
fi
case "$cmd" in
-h|--help|'')
echo "Toggle your laptop monitor and one external monitor with ease"
echo ""
echo "Usage:"
echo ""
echo -e "\e[92m${0##*/} all [monitor_name] [position]\e[39m"
echo " activate both the internal and the external monitor"
echo ""
echo " [monitor_name] is optional and lets you specify the external monitor xrandr name."
echo " By default, the scripts looks for connected monitors named, in order,"
echo " \"$other_monitor\" and \"$work_monitor\" if no monitor_name is given."
echo ""
echo " [position] is optional and lets you specify the position of the external monitor"
echo " around the internal one: above, below, left-of and right-of. Default is \"$DEFAULT_POSITION\"."
echo ""
echo -e "\e[92m${0##*/} in [monitor_name]\e[39m"
echo " activate only the internal monitor"
echo ""
echo " [monitor_name] works the same as in the \`all\` command. Specifying this here will"
echo " make the script turn off the given monitor and the fallback \"$work_monitor\"."
echo ""
echo -e "\e[92m${0##*/} out [monitor_name]\e[39m"
echo " activate only the external monitor"
echo ""
echo " [monitor_name] works the same as in the \`all\` command."
echo ""
echo -e "\e[92m${0##*/} switch [monitor_name] [position]\e[39m"
echo " call this script with the next possible state"
echo ""
echo " states are switched in order: all, in, out."
echo " [monitor_name] and [position] work the same as in the \`all\` command."
;;
status)
echo "current state: $current_state"
echo "next switch state: $next_state"
echo "internal monitor xrandr name: $internal_monitor"
echo "external monitor xrandr name: $external_monitor"
;;
all)
echo xrandr --output "$internal_monitor" --primary --auto --output "$external_monitor" --auto "--$mode" "$internal_monitor"
xrandr --output "$internal_monitor" --primary --auto --output "$external_monitor" --auto "--$mode" "$internal_monitor" > /dev/null &
;;
in)
echo xrandr --output "$internal_monitor" --auto --output "$other_monitor" --off --output "$work_monitor" --off
xrandr --output "$internal_monitor" --auto --output "$other_monitor" --off --output "$work_monitor" --off > /dev/null &
;;
out)
echo --output "$internal_monitor" --off --output "$external_monitor" --auto
xrandr --output "$internal_monitor" --off --output "$external_monitor" --auto > /dev/null &
;;
switch)
echo $0 $next_state $other_monitor $mode
$0 $next_state $other_monitor $mode
;;
*)
echo "Command '$cmd' not supported."
esac
exit 0
@KimJi55
Copy link

KimJi55 commented Jul 26, 2021

Thanks, but I still can't use it, will try to connect to TV via hdmi cable, don't know if tv will support it 😅😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment