Skip to content

Instantly share code, notes, and snippets.

@xdhmoore
Created September 9, 2020 13:32
Show Gist options
  • Select an option

  • Save xdhmoore/cb8321bbd00f2fe07e418d9fa93367ca to your computer and use it in GitHub Desktop.

Select an option

Save xdhmoore/cb8321bbd00f2fe07e418d9fa93367ca to your computer and use it in GitHub Desktop.
Bash script to swap monitor configurations
#!/usr/bin/env bash
# Sometimes mac os assigns different ids to external monitors. The ids can swap back and forth (based on
# the order in which they are attached?). When the ids of two displays are switched, it's impossible
# (as far as I know) to determine which external monitor id goes with which physical device. Instead,
# this script just assumes the ids are backwards and switches the configuration for them.
# After all, you are calling the scripit, so something must be wrong...
#
# Note that this script depends heavily on the text output of displayplacer, so it may be somewhat brittle...
built_in_id=$(displayplacer list | grep -iB2 ' *Type *:.*built *in' | grep -i '^Persistent *screen *id' | sed -E 's/^[^:]*: *//g')
# Everything that is not a built-in is an external display
ext_ids=$(displayplacer list | grep -i '^Persistent *screen *id' | grep -v "$built_in_id" | sed -E 's/^[^:]*: *//g')
# Assuming two external displays:
first_ext_id=$(echo "$ext_ids" | sort | head -n1)
second_ext_id=$(echo "$ext_ids" | sort -r | head -n1)
# Get the current display config, swap the external display ids, and rerun it
my_config="$(displayplacer list | grep -E '^ *displayplacer *')"
toggle_config=$(echo "$my_config" | sed "s/${first_ext_id}/frogdinosaurcat/g")
toggle_config=$(echo "$toggle_config" | sed "s/${second_ext_id}/${first_ext_id}/g")
toggle_config=$(echo "$toggle_config" | sed "s/frogdinosaurcat/${second_ext_id}/g")
eval $toggle_config
@xdhmoore
Copy link
Copy Markdown
Author

I don't have that work Mac anymore but I think I created a file with extension sh and then searched and invoked it via spotlight. But for starters you probably will want to try running the file from the command line.

@xdhmoore
Copy link
Copy Markdown
Author

To debug you might try adding echo statements to see what the variable values are being set to. Maybe your monitor configuration is different than mine. I had a laptop screen and two identical external screens, but there also may be different versions of that scenario I hadn't considered.

@FloWi
Copy link
Copy Markdown

FloWi commented Nov 28, 2021

@xdhmoore Thanks a lot for that script! Made my day!

@rafaelmaeuer
Copy link
Copy Markdown

Thanks a lot for providing the script. I needed to fix recognition of internal monitor (-iB3) and handle case when lid is closed. Here my updated script if anyone else needs this:

#!/usr/bin/env bash

# Sometimes mac os assigns different ids to external monitors. The ids can swap back and forth (based on 
# the order in which they are attached?). When the ids of two displays are switched, it's impossible
# (as far as I know) to determine which external monitor id goes with which physical device. Instead,
# this script just assumes the ids are backwards and switches the configuration for them.
# After all, you are calling the scripit, so something must be wrong...
#
# Note that this script depends heavily on the text output of displayplacer, so it may be somewhat brittle...

built_in_id=$(displayplacer list | grep -iB3 ' *Type *:.*built *in' | grep -i '^Persistent *screen *id' | sed -E 's/^[^:]*: *//g')

# Everything that is not a built-in is an external display
if [[ -n "$built_in_id" ]]; then
  ext_ids=$(displayplacer list | grep -i '^Persistent *screen *id' | grep -v "$built_in_id" | sed -E 's/^[^:]*: *//g')
else
  ext_ids=$(displayplacer list | grep -i '^Persistent *screen *id' | sed -E 's/^[^:]*: *//g')
fi

# Assuming two external displays:
first_ext_id=$(echo "$ext_ids" | sort | head -n1)
second_ext_id=$(echo "$ext_ids" | sort -r | head -n1)

# Get the current display config, swap the external display ids, and rerun it
my_config="$(displayplacer list | grep -E '^ *displayplacer *')"
toggle_config=$(echo "$my_config" | sed "s/${first_ext_id}/frogdinosaurcat/g")
toggle_config=$(echo "$toggle_config" | sed "s/${second_ext_id}/${first_ext_id}/g")
toggle_config=$(echo "$toggle_config" | sed "s/frogdinosaurcat/${second_ext_id}/g")
eval $toggle_config

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