displayplacer screen resolutions, mirror display settings and configurations

Hasibravo
New Contributor III

This script automates the configuration of display settings on macOS by checking the system architecture, downloading and installing the correct version of `displayplacer`, and setting up display mirroring with specified parameters. It ensures compatibility with ARM64 and Intel systems while optimizing display settings such as resolution, refresh rate, color depth, and scaling. The script uses JAMF parameters to adjust these settings dynamically.

Feel free to adjust the description if you have any specific points you'd like to highlight!

DisplayPlacer: https://github.com/jakehilborn/displayplacer

 

#!/bin/bash

# -----------------------------------------------------------------------------
# Script Name:     DisplayPlacer.sh
# Author:          [Muhammad Hasib]
# Created:         25Jul2024
# Last Modified:   25Jul2024
# Description:     This script checks the system architecture, downloads and
#                  installs the appropriate version of displayplacer, and 
#                  configures display settings for mirroring built-in and 
#                  external screens with specified resolution, refresh rate, 
#                  color depth, and scaling.
#                  It will 'OPTIMISE FOR' with an external display.	
# -----------------------------------------------------------------------------


# Define variables for display settings
RESOLUTION="1920x1080"
HZ="60"
COLOR_DEPTH="8"
SCALING="off"

# Define paths
DISPLAYPLACER_PATH="/usr/local/bin/displayplacer"
DISPLAYPLACER_URL_APPLE="https://github.com/jakehilborn/displayplacer/releases/download/v1.4.0/displayplacer-apple-v140"
DISPLAYPLACER_URL_INTEL="https://github.com/jakehilborn/displayplacer/releases/download/v1.4.0/displayplacer-intel-v140"

# Determine the architecture
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
    DISPLAYPLACER_URL="$DISPLAYPLACER_URL_APPLE"
else
    DISPLAYPLACER_URL="$DISPLAYPLACER_URL_INTEL"
fi

# Download and install displayplacer if not found
if [ ! -f "$DISPLAYPLACER_PATH" ]; then
    echo "displayplacer not found. Downloading and installing..."
    curl -L "$DISPLAYPLACER_URL" -o /tmp/displayplacer
    chmod +x /tmp/displayplacer
    sudo mv /tmp/displayplacer "$DISPLAYPLACER_PATH"
    echo "displayplacer installed at $DISPLAYPLACER_PATH."
fi

# List current display configurations and store the output
DISPLAY_CONFIG=$($DISPLAYPLACER_PATH list)

# Initialize arrays
BUILT_IN_ID=""
EXTERNAL_ID=""

# Process the display configurations
while read -r line; do
    if [[ "$line" =~ Persistent\ screen\ id:\ ([^ ]+) ]]; then
        PERSISTENT_ID="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ Type:\ (.+) ]]; then
        TYPE="${BASH_REMATCH[1]}"
        
        # Assign persistent ID based on screen type
        if [[ "$TYPE" == *"built in"* ]]; then
            BUILT_IN_ID="$PERSISTENT_ID"
        else
            EXTERNAL_ID="$PERSISTENT_ID"
        fi
    fi
done <<< "$DISPLAY_CONFIG"

# Check if both screen IDs are found
if [ -z "$BUILT_IN_ID" ] || [ -z "$EXTERNAL_ID" ]; then
    echo "Could not find both built-in and external screens."
    exit 1
fi

# Debug: print extracted persistent ids
echo "Built-in screen ID: $BUILT_IN_ID"
echo "External screen ID: $EXTERNAL_ID"

# Construct the displayplacer command for mirroring
CMD="$DISPLAYPLACER_PATH"
CMD+=" \"id:$EXTERNAL_ID+${BUILT_IN_ID} res:$RESOLUTION hz:$HZ color_depth:$COLOR_DEPTH enabled:true scaling:$SCALING\""

# Debug: print the command that will be executed
echo "Executing command: $CMD"

# Execute the constructed command
eval $CMD

 

4 REPLIES 4

fgonzale
Contributor

This works great! Though I did have to make a small addition to the script as the path "/usr/local/bin" doesn't usually exist in a clean state (at least not in Sonoma). So I added a mkdir /usr/local/bin line

mkdir /usr/local/bin

 

Modified script:

#!/bin/bash

# -----------------------------------------------------------------------------
# Script Name:     DisplayPlacer.sh
# Author:          [Muhammad Hasib]
# Created:         25Jul2024
# Last Modified:   25Jul2024
# Description:     This script checks the system architecture, downloads and
#                  installs the appropriate version of displayplacer, and 
#                  configures display settings for mirroring built-in and 
#                  external screens with specified resolution, refresh rate, 
#                  color depth, and scaling.
#                  It will 'OPTIMISE FOR' with an external display.	
# -----------------------------------------------------------------------------


# Define variables for display settings
RESOLUTION="1920x1080"
HZ="60"
COLOR_DEPTH="8"
SCALING="off"

# Define paths
DISPLAYPLACER_PATH="/usr/local/bin/displayplacer"
DISPLAYPLACER_URL_APPLE="https://github.com/jakehilborn/displayplacer/releases/download/v1.4.0/displayplacer-apple-v140"
DISPLAYPLACER_URL_INTEL="https://github.com/jakehilborn/displayplacer/releases/download/v1.4.0/displayplacer-intel-v140"

# Determine the architecture
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
    DISPLAYPLACER_URL="$DISPLAYPLACER_URL_APPLE"
else
    DISPLAYPLACER_URL="$DISPLAYPLACER_URL_INTEL"
fi

# Download and install displayplacer if not found
if [ ! -f "$DISPLAYPLACER_PATH" ]; then
    echo "displayplacer not found. Downloading and installing..."
    curl -L "$DISPLAYPLACER_URL" -o /tmp/displayplacer
    chmod +x /tmp/displayplacer
    mkdir /usr/local/bin
    sudo mv /tmp/displayplacer "$DISPLAYPLACER_PATH"
    echo "displayplacer installed at $DISPLAYPLACER_PATH."
fi

# List current display configurations and store the output
DISPLAY_CONFIG=$($DISPLAYPLACER_PATH list)

# Initialize arrays
BUILT_IN_ID=""
EXTERNAL_ID=""

# Process the display configurations
while read -r line; do
    if [[ "$line" =~ Persistent\ screen\ id:\ ([^ ]+) ]]; then
        PERSISTENT_ID="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ Type:\ (.+) ]]; then
        TYPE="${BASH_REMATCH[1]}"
        
        # Assign persistent ID based on screen type
        if [[ "$TYPE" == *"built in"* ]]; then
            BUILT_IN_ID="$PERSISTENT_ID"
        else
            EXTERNAL_ID="$PERSISTENT_ID"
        fi
    fi
done <<< "$DISPLAY_CONFIG"

# Check if both screen IDs are found
if [ -z "$BUILT_IN_ID" ] || [ -z "$EXTERNAL_ID" ]; then
    echo "Could not find both built-in and external screens."
    exit 1
fi

# Debug: print extracted persistent ids
echo "Built-in screen ID: $BUILT_IN_ID"
echo "External screen ID: $EXTERNAL_ID"

# Construct the displayplacer command for mirroring
CMD="$DISPLAYPLACER_PATH"
CMD+=" \"id:$EXTERNAL_ID+${BUILT_IN_ID} res:$RESOLUTION hz:$HZ color_depth:$COLOR_DEPTH enabled:true scaling:$SCALING\""

# Debug: print the command that will be executed
echo "Executing command: $CMD"

# Execute the constructed command
eval $CMD

 

probably could have made the new mkdir part a conditional statement but if the directory already exists then mkdir wont do anything

miniberry
New Contributor III

Hi guys, 
Just wanted to make sure I'm correctly understanding how this works, since it seems awesome but when I looked in the instructions on github, there seem to be some additional manual steps? 

I need a tool that allows mac minis that are in classrooms and connected to other monitors and projectors in the class, to have display settings locked on "mirrored" so that professors don't have to go into settings to change from "extended display" to "mirrored display". 
From what I'm understanding I have to manually change settings on the device each time? Or is this wrong? This is what I read in the instructions. 

Instructions:

  1. Manually set rotations 1st*, resolutions 2nd, and arrangement 3rd. For extra resolutions and rotations read 'Notes' below.
    • Open System Preferences -> Displays
    • Choose desired screen rotations (use displayplacer for rotating internal MacBook screen).
    • Choose desired resolutions (use displayplacer for extra resolutions).
    • Drag the white bar to your desired primary screen.
    • Arrange screens as desired and/or enable mirroring. To enable partial mirroring hold the alt/option key and drag a display on top of another.
  2. Use displayplacer list to print your current layout's args, so you can create profiles for scripting/hotkeys with Automator, BetterTouchTool, etc.

So I implement this exact mirroring request using displayplacer for one of our iMacs connected to a monitor in a classroom lab.

This way it always mirrors everytime a professors log into their specific profile.

Even if the prof changes the display settings, once someone else logs in, the display settings get set back to mirroring. I have a Jamf policy that I ran once that installs the displayplacer binary and sets the script.
I put displayplacer in a directory that I created called /Library/Payloads/

 

So displayplacer will have a path of:
/Library/Payloads/displayplacer

I do also as it installs run a line to remove any quarantine bits (could be optional depending on how you package it and deploy):
xattr -d -r com.apple.quarantine "/Library/Payloads/displayplacer"

 

To that Jamf policy I then run the following script in the script section which sets up everything including the launchagent that runs each time anybody logs into the computer:

#!/bin/sh

if [ -d "/Library/Scripts/MyCompanyScripts" ]
then
echo "directory /Library/Scripts/MyCompanyScripts already exist. Continuing..."
else
echo "creating directory /Library/Scripts/MyCompanyScripts since it does not already exist..."
mkdir /Library/Scripts/MyCompanyScripts
fi



echo "creating plist file com.MyCompany.displayplacerAddendum.plist LaunchAgent..."

cat <<'EOM' > "/Library/LaunchAgents/com.MyCompany.displayplacerAddendum.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.MyCompany.displayplacerAddendum.plist</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Library/Scripts/MyCompanyScripts/displayplacerAddendum.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>LaunchOnlyOnce</key>
	<true/>
</dict>
</plist>
EOM

echo "setting 755 permissions on com.MyCompany.displayplacerAddendum.plist directory..."
chmod 755 "/Library/LaunchAgents/com.MyCompany.displayplacerAddendum.plist"


echo "creating script displayplacerAddendum.sh..."

cat <<'EOM' > /Library/Scripts/MyCompanyScripts/displayplacerAddendum.sh
#!/bin/sh

# -----------------------------------------------------------------------------
# Script Name:     DisplayPlacer.sh
# Author:          [Muhammad Hasib]
# Created:         25Jul2024
# Last Modified:   25Jul2024
# Description:     This script checks the system architecture, downloads and
#                  installs the appropriate version of displayplacer, and 
#                  configures display settings for mirroring built-in and 
#                  external screens with specified resolution, refresh rate, 
#                  color depth, and scaling.
#                  It will 'OPTIMISE FOR' with an external display.
# Additional Modification: Fernando Gonzalez	
# -----------------------------------------------------------------------------


# Define variables for display settings
RESOLUTION="1920x1080"
HZ="60"
COLOR_DEPTH="8"
SCALING="off"

# Define paths
DISPLAYPLACER_PATH="/Library/Payloads/displayplacer"


# List current display configurations and store the output
DISPLAY_CONFIG=$($DISPLAYPLACER_PATH list)

# Initialize arrays
BUILT_IN_ID=""
EXTERNAL_ID=""

# Process the display configurations
while read -r line; do
    if [[ "$line" =~ Persistent\ screen\ id:\ ([^ ]+) ]]; then
        PERSISTENT_ID="${BASH_REMATCH[1]}"
    elif [[ "$line" =~ Type:\ (.+) ]]; then
        TYPE="${BASH_REMATCH[1]}"
        
        # Assign persistent ID based on screen type
        if [[ "$TYPE" == *"built in"* ]]; then
            BUILT_IN_ID="$PERSISTENT_ID"
        else
            EXTERNAL_ID="$PERSISTENT_ID"
        fi
    fi
done <<< "$DISPLAY_CONFIG"

# Check if both screen IDs are found
if [ -z "$BUILT_IN_ID" ] || [ -z "$EXTERNAL_ID" ]; then
    echo "Could not find both built-in and external screens."
    exit 1
fi

# Debug: print extracted persistent ids
echo "Built-in screen ID: $BUILT_IN_ID"
echo "External screen ID: $EXTERNAL_ID"

# Construct the displayplacer command for mirroring
CMD="$DISPLAYPLACER_PATH"
CMD+=" \"id:$EXTERNAL_ID+${BUILT_IN_ID} res:$RESOLUTION hz:$HZ color_depth:$COLOR_DEPTH enabled:true scaling:$SCALING\""

# Debug: print the command that will be executed
echo "Executing command: $CMD"

# Execute the constructed command
eval $CMD
EOM

echo "settings 755 permissions on displayplacerAddendum.sh..."
chmod 755 /Library/Scripts/MyCompanyScripts/displayplacerAddendum.sh

exit

 

 

miniberry
New Contributor III

Fantastic!! This is exactly what I was looking to implement as well. Thank you so very much, you made my week! 🙏 I will test this out and see if I run into any issues and then deploy it to our podiums. 

Thank you!