Skip to content

Instantly share code, notes, and snippets.

@GetVladimir
Last active September 10, 2024 15:03
Show Gist options
  • Save GetVladimir/c89a26df1806001543bef4c8d90cc2f8 to your computer and use it in GitHub Desktop.
Save GetVladimir/c89a26df1806001543bef4c8d90cc2f8 to your computer and use it in GitHub Desktop.
Force RGB Color on M1 Mac

Force RGB Color on M1 Mac

How to Force RGB Color Output instead of YPbPr on your M1 Apple Silicon Mac for an External Monitor.

This step-by-step video tutorial will guide you through the procedure of forcing RGB color output on your M1 Mac.

Force RGB Color on M1 Mac

Here is the direct link to the video tutorial: https://www.youtube.com/watch?v=Z1EqH3fd0V4

The video also has Closed Captions (Subtitles) that you can enable, to make it easier to follow if needed.



Please note that you're doing any changes on your own risk.

Terminal commands used in the video

Here are each of the Terminal commands mentioned in the tutorial, so that you can just copy and paste them:

open /Library/Preferences

plutil -convert xml1

plutil -convert binary1

plutil -lint



The step-by-step procedure on how to force RGB Color Output on M1 and M2 based Macs with Terminal commands

  1. Open Terminal and use this command to make Finder select the displays plist file:
    open -R /Library/Preferences/com.apple.windowserver.displays.plist

  2. Drag and drop the com.apple.windowserver.displays.plist file to Desktop manually. Don't use the cp command, as it won't add your current user with writing privileges.

  3. Convert the file to XML:
    plutil -convert xml1 ~/Desktop/com.apple.windowserver.displays.plist

  4. Open the converted file with the default plain text editor (avoid using the built-in TextEdit app if possible, since it might modify the file and make it unreadable by the system)
    open -t ~/Desktop/com.apple.windowserver.displays.plist
    or
    open -a CotEditor.app ~/Desktop/com.apple.windowserver.displays.plist

  5. Copy and paste the missing LinkDesription Key under the current display (check the screenshot below for an example of how it should look like):

				<key>LinkDescription</key>
				<dict>
					<key>BitDepth</key>
					<integer>8</integer>
					<key>EOTF</key>
					<integer>0</integer>
					<key>PixelEncoding</key>
					<integer>0</integer>
					<key>Range</key>
					<integer>1</integer>
				</dict>
  1. Save the file and then convert it to binary again:
    plutil -convert binary1 ~/Desktop/com.apple.windowserver.displays.plist

  2. Check if the plist file is valid:
    plutil -lint ~/Desktop/com.apple.windowserver.displays.plist

  3. Open the /Library/Preferences/ folder again:
    open /Library/Preferences/

  4. Drag and drop the updated com.apple.windowserver.displays.plist file from Desktop to the Library folder manually. Don't use the cp command, as it won't add your current user with writing privileges.

  5. Right Click on the com.apple.windowserver.displays.plist file in the Library folder and click on Get Info

  6. Check the boxes for Stationery and Locked.

  7. Reboot the Mac.

That's it!



(Alternative) Terminal commands to force RGB Color Output on M1 and M2 based Macs and workaround for losing RGB color after waking up from sleep

  1. Open Terminal

  2. Paste the following commands to edit the User's displays plist file com.apple.windowserver.displays.[UUID].plist using the built-in PlistBuddy function in macOS:

/usr/libexec/PlistBuddy -c "add DisplaySets:Configs:DisplayConfig:DisplayConfig:DisplayConfig:LinkDescription:BitDepth integer" ~/Library/Preferences/ByHost/com.apple.windowserver.displays.*.plist
/usr/libexec/PlistBuddy -c "set DisplaySets:Configs:DisplayConfig:DisplayConfig:DisplayConfig:LinkDescription:BitDepth 8" ~/Library/Preferences/ByHost/com.apple.windowserver.displays.*.plist
/usr/libexec/PlistBuddy -c "add DisplaySets:Configs:DisplayConfig:DisplayConfig:DisplayConfig:LinkDescription:EOTF integer" ~/Library/Preferences/ByHost/com.apple.windowserver.displays.*.plist
/usr/libexec/PlistBuddy -c "add DisplaySets:Configs:DisplayConfig:DisplayConfig:DisplayConfig:LinkDescription:PixelEncoding integer" ~/Library/Preferences/ByHost/com.apple.windowserver.displays.*.plist
/usr/libexec/PlistBuddy -c "add DisplaySets:Configs:DisplayConfig:DisplayConfig:DisplayConfig:LinkDescription:Range integer" ~/Library/Preferences/ByHost/com.apple.windowserver.displays.*.plist
  1. Reboot your Mac

(Workaround) If your Mac loses RGB color after waking up from sleep mode, either Reboot your Mac (recommended) or use this Terminal command to stop the WindowServer and login again (not recommended):

sudo killall -HUP WindowServer



End result

The end result is having your M1 mac output RGB color to your external monitor instead of YPbPr, potentially making the colors more accurate and the text a bit more crisp, even on older 1080p monitors.

Hopefully this tutorial would be useful to someone.

Please feel free to ask in the comment section if you have any questions regarding this procedure.



Background

While doing a lot of testing on how the Dual-Cable workaround makes RGB to work on M1, I've discovered what changes it makes to macOS, and managed to create a more streamlined workaround without the need to use a second cable.

To make things easier, I've created a step-by-step video tutorial of the whole procedure that should force RGB color output on your M1 Mac connected to an external monitor, and works on an HDMI-to-HDMI cable connection.

Credits

Big thanks goes to the amazing community and all their help over the years to solve issues like this:
https://gist.github.com/ejdyksen/8302862
https://gist.github.com/adaugherity/7435890

Useful Sources

Apple Open Source Project Files for Displays and Graphics
https://opensource.apple.com/source/IOKitUser/IOKitUser-1445.60.1/graphics.subproj/IODisplayLib.c
https://opensource.apple.com/source/IOGraphics/IOGraphics-517.17/IOGraphicsFamily/IOFramebuffer.cpp.auto.html

How to Edit and Convert binary plist files
http://hints.macworld.com/article.php?story=20050803111126899
https://apple.stackexchange.com/questions/155393/how-to-beautify-binary-dict-files
https://discussions.apple.com/thread/1768480

How to Edit plist files using defaults and PlistBuddy
https://ss64.com/osx/defaults.html
https://github.com/mathiasbynens/dotfiles/blob/master/.macos

Apps based on this method

@sudowork has created an awesome script written in Phyton that automates the steps and checks for duplicate files.
You can find more info about it here: https://github.com/sudowork/fix_m1_rgb

@dangh has created an alernative script for fishshell.
You can find more info about it here: https://github.com/dangh/force-rgb.fish

@GetVladimir I've also created a Shortcut to Force RGB Color Output using the built-in Shortcuts app.
You can find how to create the Shortcut here: https://gist.github.com/GetVladimir/c89a26df1806001543bef4c8d90cc2f8?permalink_comment_id=4531552#gistcomment-4531552

@entropyconquers has created a script based on this method written in Phyton that automates the steps, makes a backup and checks for duplicate files.
You can find more info about it here: https://github.com/entropyconquers/Force-RGB-Color-on-M1-M2-Mac-Script

Additional notes

Multiple PixelEncoding and Range keys in the same plist file
Note that there might be multiple instances of the PixelEncoding and Range keys in the same file, one for each output of your monitor and for different AirPlay devices. You might need to update the integer on each one to get RGB color output on all displays.

Getting RGB color only before login
There might be multiple duplicate plist files with the same name in different locations.

Make sure that you only have the main modified file in:
/Library/Preferences

Then make a backup and remove duplicate displays plist files from these locations (if any):
~/Library/Preferences
or
/Users/username/Library/Preferences
and
/Users/username/Library/Preferences/ByHost


Please note that you'll need to have administrator privileges in order to modify the file in /Library/Preferences. Thanks goes to @keegandent and @StrategicalIT for pointing this out.

Updates regarding macOS Monterey

USB-C to DisplayPort
From what I've seen, it seems that macOS Monterey 12.0.1 finally outputs RGB color by default on some monitors when using USB-C to DisplayPort cable on M1 Apple Silicone Macs.

You might need to make a backup and delete these 2 files:
/Library/Preferences/com.apple.windowserver.displays.plist
and
/Users/yourname/Library/Preferences/ByHost/com.apple.windowserver.displays.[UDID].plist

Restart your Mac and it should properly output RGB color on the monitor on the next boot.

HDMI to HDMI
The situation with HDMI seems to got a bit more complicated. Now the whole section for the LinkDescription might be missing from the com.apple.windowserver.displays.plist on a clean install and doesn't seem to be recreated when rotating the screen either.

Luckily, the solution still works, but you might need to manually add this whole section in the displays plist file:

					<key>LinkDescription</key>
					<dict>
						<key>BitDepth</key>
						<integer>8</integer>
						<key>EOTF</key>
						<integer>0</integer>
						<key>PixelEncoding</key>
						<integer>0</integer>
						<key>Range</key>
						<integer>1</integer>
					</dict>



The section usually goes right under the CurrentInfo key, and it should look something like this:

pixelencoding

This should get your RGB color output working on M1 Mac mini, even when connected with HDMI to HDMI cable.

Multiple monitors when one them is using HDMI to HDMI
Additional thanks goes to @somogyi-ede who tested this with multiple monitors and confirmed that the LinkDescription key needs to be added under each monitor instance in order for all of them to receive RGB color output. Link to the comment

Updates regarding macOS 13 Ventura

USB-C to DisplayPort
The macOS 13 Ventura beta seems to outputs RGB color by default on some monitors when using USB-C to DisplayPort cable on M1 Apple Silicone Macs.

You might need to make a backup and delete these 2 files:
/Library/Preferences/com.apple.windowserver.displays.plist
and
/Users/yourname/Library/Preferences/ByHost/com.apple.windowserver.displays.[UDID].plist

Restart your Mac and it should properly output RGB color on the monitor on the next boot.

HDMI to HDMI
Similar as macOS Monterey, the situation with HDMI on macOS Venturs seems a bit more complicated. Usually the whole section for the LinkDescription might be missing from the com.apple.windowserver.displays.plist on a clean install and doesn't seem to be recreated when rotating the screen either.

Luckily, the solution still works, and you still need to manually add this whole section in the displays plist file:

					<key>LinkDescription</key>
					<dict>
						<key>BitDepth</key>
						<integer>8</integer>
						<key>EOTF</key>
						<integer>0</integer>
						<key>PixelEncoding</key>
						<integer>0</integer>
						<key>Range</key>
						<integer>1</integer>
					</dict>



The section usually goes right under the CurrentInfo key, and it should look something like this:

pixelencoding

This should get your RGB color output working on M1 Mac mini, even when connected with HDMI to HDMI cable.

(Optional) Lock the plist file and set it as stationary
After the macOS Ventura 13.3 update, the plist file seems to get overwritten on reboot.

After you make the edits in the file, you can try setting the file /Library/Preferences/com.apple.windowserver.displays.plist as Stationery pad and Locked, so that it doesn't get overwritten on every reboot

Stationery Pad Locked

To do this, right click on the plist file, click on Get Info and check the boxes next to Stationery pad and Locked

This requires further testing and might cause some issues, like not being able to remember new resolutions or display settings. Please note that you're making any changes at your own risk.

Updates regarding macOS 14 Sonoma Beta

USB-C to DisplayPort
The macOS 14 Sonoma seems to outputs RGB color by default when using USB-C to DisplayPort cable.

HDMI to HDMI
The macOS 14 Sonoma seems to outputs YCbCr color by default when using HDMI to HDMI cable.

  • Forcing RGB Color Output still seems to work with the original procedure of modifying the plist files

  • Modifying the display plist files still works with the alternative version

  • After the plist files are modified, putting the Mac to sleep and waking it, it seem to keep the RGB Color output (this seems to be fixed at least on a M1 Mac mini)

If you have any additional questions, please feel free to contact me.

@StrategicalIT
Copy link

Hi @GetVladimir thanks for all your amazing work on this. I'm trying to get this working on my setup but I have a question please:
M1 Mac Mini (MacOS 12.3.1) HDMI -> HDMI using a Dell U4320Q.

My problem is I have a basically blank windowserver.display.plist file, even after trying the rotation trick.

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>DisplayUUIDMappings</key>
	<dict>
		<key>C6509A39-06DF-B92D-0F93-5A69417CA049</key>
		<string>7F878A30-4357-4DFD-8BF0-1E5CF9BC123A</string>
	</dict>
</dict>
</plist>

So from your notes I've read about having to manually add the LinkDescription, but given I don't even have a CurrentInfo section I don't really know were/how to add this.

Any advice appreciated. Cheers :-)

@keegandent
Copy link

@StrategicalIT I had a issues with that file not getting updated from settings changed in System Preferences, and the solution was usually to just do a reboot.

@GetVladimir
Copy link
Author

@StrategicalIT Thank you so much for your comment!

Yes, if the file doesn't get generated right away, it's best to try a reboot as @keegandent suggested.

If that doesn't work, you can try to AirPlay to another device (like an Apple TV) or add an iPad as a second screen (Sidecar). This should generate the file.

If nothing else works, you can test the example plist file and replace the resolution, refresh and placeholder UUIDs with your own (Fully at your own risk, I don't recommend using this):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>DisplayAnyUserSets</key>
	<dict>
		<key>Configs</key>
		<array>
			<array>
				<dict>
					<key>CurrentInfo</key>
					<dict>
						<key>Depth</key>
						<integer>8</integer>
						<key>High</key>
						<real>1200</real>
						<key>Hz</key>
						<real>60</real>
						<key>IsLink</key>
						<false/>
						<key>OriginX</key>
						<real>0.0</real>
						<key>OriginY</key>
						<real>0.0</real>
						<key>Rotation</key>
						<integer>0</integer>
						<key>Scale</key>
						<real>1</real>
						<key>Wide</key>
						<real>1920</real>
					</dict>
					<key>LinkDescription</key>
					<dict>
						<key>BitDepth</key>
						<integer>8</integer>
						<key>EOTF</key>
						<integer>0</integer>
						<key>PixelEncoding</key>
						<integer>0</integer>
						<key>Range</key>
						<integer>1</integer>
					</dict>
					<key>Rotation</key>
					<real>0.0</real>
					<key>UUID</key>
					<string>0283FB79-6CDA-45AC-9193-C57F848688E5</string>
					<key>UnmirrorInfo</key>
					<dict>
						<key>Depth</key>
						<integer>4</integer>
						<key>High</key>
						<real>1</real>
						<key>Hz</key>
						<real>60</real>
						<key>IsLink</key>
						<false/>
						<key>OriginX</key>
						<real>0.0</real>
						<key>OriginY</key>
						<real>0.0</real>
						<key>Rotation</key>
						<integer>0</integer>
						<key>Scale</key>
						<real>1</real>
						<key>Wide</key>
						<real>1</real>
					</dict>
				</dict>
			</array>
		</array>
		<key>Orientations</key>
		<dict>
			<key>0283FB79-6CDA-45AC-9193-C57F848688E5</key>
			<integer>0</integer>
		</dict>
		<key>Underscan</key>
		<dict>
			<key>0283FB79-6CDA-45AC-9193-C57F848688E5</key>
			<real>1</real>
		</dict>
		<key>Version</key>
		<integer>1</integer>
	</dict>
	<key>DisplayUUIDMappings</key>
	<dict>
		<key>975F020A-2B06-A110-0F93-5A69417CA049</key>
		<string>0283FB79-6CDA-45AC-9193-C57F848688E5</string>
	</dict>
</dict>
</plist>

That being said, there was an issue with certain older macOS versions and generating the display files. You might want to update to macOS 12.4 or 12.5 if you haven't done that already.

@keegandent Thank you so much for the reply and for the useful suggestions! I appreciate them a lot

@StrategicalIT
Copy link

@keegandent and @GetVladimir thank you both so much for you fast response. I had tried a reboot, but I hadn't done an MacOS update, so updating to 12.4 now and will try again. Cheers :-)

@GetVladimir
Copy link
Author

@StrategicalIT Awesome! Let us know how it goes.

@StrategicalIT
Copy link

@StrategicalIT Awesome! Let us know how it goes.

SUCCESS :-)

So post update (MacOS 12.4) and reboot I tried the rotate trick and sidecar (mirror) to my iPad (via USB) and neither had the desired result of adding info to the windowserver.display.plist file.

At this point I wondered if it might be a user/permission type problem... the user account I use on my Mac has no admin privledges, so I logged out and logged in with my admin account, did the rotation trick and success, fully populated windowserver.display.plist file.

I copied the new plist file to a shared folder were my standard user could access it, logged out admin and login as standard user.

Run through the steps above including having to manually add the LinkDescription section (as per HDMI -> HDMI notes) and I now have RGB colour space.

Thanks again for all your help @GetVladimir & @keegandent

@keegandent
Copy link

@GetVladimir Could you add a note to the gist saying that admin is required? I think for those not used to *nix systems it might not be obvious.

@GetVladimir
Copy link
Author

@StrategicalIT Thank you for the update and I'm glad to hear that you got RGB color output working!

@GetVladimir
Copy link
Author

GetVladimir commented Jul 20, 2022

@keegandent Thank you for pointing this out! Good suggestion, I've added it to the gist under Additional Notes (with credit, hope that is ok)

@StrategicalIT
Copy link

@keegandent Thank you for pointing this out! Good suggestion, I've added it to the gist under Additional Notes (with credit, hope that is ok)

No problem. Glad I was able to help.

@dangh
Copy link

dangh commented Jul 21, 2022

If anyone use fishshell, I have a script to patch the plist files here https://github.com/dangh/force-rgb.fish

@GetVladimir
Copy link
Author

@dangh Nice work! Thank you for creating and for sharing the script.

I've added it to the Apps based on this method section in this gist with a link to your profile.

I've looked over the code, but I'm not sure what happens when there is a plist file in /Library/Preferences/, but no file found in ~/Library/Preferences/ByHost/. Does it skip the second one and continues?

@dangh
Copy link

dangh commented Jul 21, 2022

@GetVladimir yes it will proceed with existing files only.

@n1trousx
Copy link

Hi @GetVladimir!
Thanks a mil!
I had to do a bunch of troubleshooting to get my monitor to output RGB.
The displays file in /ByHosts was overriding the file in the normal /Preferences files. This seems to happen if you've fiddled with something like BetterDummy.
Deleted both files in both locations, redid the tutorial and it finally worked! (HDMI to HDMI).
This is for anyone reading this thread that might not have done this!
Again, thank you so much, the display looks a ton better now!

@rohit267 try what I mentioned here perhaps?

This worked for me on my M1 Pro 16". Thank you so much!!!

@aurimasniekis
Copy link

Hi @GetVladimir!
Thanks a mil!
I had to do a bunch of troubleshooting to get my monitor to output RGB.
The displays file in /ByHosts was overriding the file in the normal /Preferences files. This seems to happen if you've fiddled with something like BetterDummy.
Deleted both files in both locations, redid the tutorial and it finally worked! (HDMI to HDMI).
This is for anyone reading this thread that might not have done this!
Again, thank you so much, the display looks a ton better now!

@rohit267 try what I mentioned here perhaps?

This worked for me on my M1 Pro 16". Thank you so much!!!

Did same just now, with all the possible tips here, but I can't get any of the monitors to go into RGB mode on M1 Pro 16" :(

@dangh
Copy link

dangh commented Aug 10, 2022

@aurimasniekis did you check the plist files after reboot? For me after patching the files using script, I had to copy the file to desktop, and copy it back for macOS to stop overriding my changes. Then I have to log out, then shutdown for it to work. A normal restart doesn't do it for me.

@aurimasniekis
Copy link

@dangh I have checked after reboot, and nothing has changed, but I haven't tried logout and then restart

@aurimasniekis
Copy link

aurimasniekis commented Aug 10, 2022

Okay, the logout and reboot didn't help, but I figured it out in the end. So even changing plist file in /Library/Preferences which after reboot did nothing (even with deleted all window files), I managed to get it work with trying to edit also the ~/Library/Preferences/ByHost file and it worked

EDIT: I know now the reason it didn't work, the RGB only works with Native resolution enabled (Most space). Tried all other scalings and none of them worked, only with native resolution 3840x2160

@dangh
Copy link

dangh commented Aug 10, 2022

@aurimasniekis it works for me. I delete the file in ~/Library/Preferences/ByHost, change the /Library/Preferences after I set the scale to 5k for my 4k monitor.

@TheFermi0n
Copy link

TheFermi0n commented Aug 12, 2022

apparently, if you close your MBP m1's lid and use the external monitor as standalone display. The RGB thing doesn't work but the HiDPI ( Scaled 2 ) trick is working and I can finally see things properly in this external display!!

Edit: Never mind it's fixed.

What you need to do is, after macOS finishes overwriting your file when you close the lid. Add the codes shown here once again to the same file under the newly added display settings also change the scaled to 2. and it's done.

@GetVladimir
Copy link
Author

Thank you for the comment and the info, and I'm glad to hear that you got RGB color output and HiDPI working

@GetVladimir
Copy link
Author

@JO-KENNEDY thank you for your comment and the details.

From what you've posted, it seems that you have done everything correctly.

I saw that you have multiple UUID entries in the plist file, which might make things more complicated.

What I can suggest is to do a backup of the displays plist file and delete it. Then do a restart of the Mac, so that it will generate a fresh displays plist file.

Usually, direct USB-C to USB-C connections don't need any modifications to work.

If that doesn't work, you might want to check if any options are enabled on the monitor itself, like HDR or cool blue filter.

If none of that works, you might want to connect the monitor to a different device, just to make sure whether the issue is with the Mac or with the Monitor.

@GetVladimir
Copy link
Author

@JO-KENNEDY thank you for the update.

Try disabling HDR in the macOS settings and see if that helps.

Other than that, you might need to start the Mac in safe mode and see if that will make any difference: https://support.apple.com/en-ie/guide/mac-help/mh21245/mac

Still worth to try connecting the Monitor to a different device to check if it still shows the same

@GetVladimir
Copy link
Author

@JO-KENNEDY It's very likely an issue with the Monitor or the Monitor built-in settings.

If it has an HDMI or DisplaysPort, try connecting to it instead. But if not, you might need to call in the warranty

@Cybermonkey342
Copy link

I have bought a Mac Mini M1. One of my monitors showed a greenish picture. It's connected via HDMI. I started the Python script and afterwards everything is allright. That's great! My question is: I am still on Big Sur, when I update to Monterey will the change still be applied or do I have to fiddle again with the terminal?

@GetVladimir
Copy link
Author

@MarkusMangold thank you for your question and I'm glad to hear that you got RGB color output working.

Usually, the changes will be persistent between updates, so you can upgrade to Monterey or Ventura.

Please note that the plist file might be overwritten if you change the resolution though.

To be safe, you can just make a backup of the displays plist file located in /Library/Preferences so that you can easily restore it in the future if needed

@Cybermonkey342
Copy link

@GetVladimir; Thanks for your answer. Now I feel rather stupid ... 🙂 Of course I can just backup the plist file ... 🤦‍♂️

@GetVladimir
Copy link
Author

@MarkusMangold No worries about it :) The important thing is that you got RGB color output working.

Thank you for the reply

@bombjoke
Copy link

bombjoke commented Oct 8, 2022

My new 14in 2021 M1 MBP displays an inch black border all around my new samsung UJ59 monitor.
im using samsung recommended hdmi cable.
works great, but the diagonal is 28.5in instead of 31.5in. annoying!

with my old 2018 MBP the monitor displays perfectly, filling whole screen, with no black border.
I've tried all the Monterey preferences, and the hardware monitor menu settings. cannot find anyone else complaining about this in apple forums, samsung, or amazon reviewers.
do you have any guidance?

@GetVladimir
Copy link
Author

@bombjoke Thank you for your question.

From what you've posted, if you've already tried all the settings and the procedure above, and you're sure there is no underscan setting, your next option would be to check with an USB-C to DisplayPort cable to connect to this specific monitor

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