Skip to content

Instantly share code, notes, and snippets.

@GetVladimir
Last active December 26, 2024 09:43
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.

@GetVladimir
Copy link
Author

@somogyi-ede Thank you so much for testing this and for the confirmation that it works on macOS Ventura too!

@jackson-57
Copy link

jackson-57 commented Nov 16, 2022

I may be wrong, but it seems as if the issue might be properly fixed in the latest macOS Ventura patch (as in, no workarounds needed). I tried plugging my laptop into a DVI monitor I've never used before and it worked immediately. I tried two more HDMI monitors (one of which I had modified the plist for) and RGB mode seemed to persist across display setting changes.

@GetVladimir
Copy link
Author

GetVladimir commented Nov 16, 2022

@jackson-57 Thank you so much for the update.

From my testing, I did a clean install on Ventura 13.0 and updated to 13.0.1, but the issue with HDMI doesn't seem to be fixed. It still requires the displays plist modifications.

That being said, DVI only seems to support RGB color, so it might be forcing the Mac to output properly to it.

When you connected the Mac again after the DVI to an HDMI monitor, you might have achieved the Dual-cable method to Force RGB Color on M1 Mac described here: https://gist.github.com/GetVladimir/ed6b7daa09b1092608fee82fd0559098

Let me know if that is the case

@jackson-57
Copy link

I'm not exactly sure what's going on, but I don't think the dual-cable workaround is at play. I only had one external display connected at a time to my MacBook Air, and whether or not I unplugged my USB-C hub between tests didn't seem to change anything.

I deleted the plist files and restarted, and tested everything again. It seems to always work on my 1080p HDMI monitor, but not on my 4K HDMI monitor. If I set the 4K monitor to 30hz, it uses RGB mode. I then retested the plist workaround (which thankfully is working again), so I imagine the reason the 4K monitor worked initially was that I had the plist modified. As for why my 1080p monitor works, I have no idea, maybe it uses DVI internally?

I know that previously, one DVI monitor I tested refused to work at all on 13.0 unless I messed with the plist, which got promptly reverted the moment the machine went to sleep. I haven't had the opportunity to test with that monitor on 13.0.1. My other DVI monitor seems to work perfectly, but I don't know if it worked on 13.0, because I never tested it. I'll have to check tomorrow whether both DVI monitors are working properly on 13.0.1.

Thank you for looking into this. It's definitely a confusing problem.

@GetVladimir
Copy link
Author

@jackson-57 thank you for the detailed explanation. That is indeed interesting.

There might be some older monitors that don't have support for YCbCr color at all, so that might also force the M1 Mac to output properly in RGB color.

Let us know if you find out what exactly is causing this, or if you need anything tested on another setup.

Either way, great find and thank you so much for sharing this.

@csergiu
Copy link

csergiu commented Nov 16, 2022

Thanks so much for this! The difference is night and day.

@GetVladimir
Copy link
Author

@csergiu you're very welcome! Thank you so much for your comment and glad to hear that you got RGB color output working

@ahuse
Copy link

ahuse commented Nov 17, 2022

I can sadly confirm, the editing of the plists worked for me (M1 MacBook Air, Dell P3421W) until i recently updated to Ventura. Now it is resetting the plist every time i plug in my USB-C cable. I have to copy the modified plist to /Library/Preferences and reboot to restore RGB.

Has anyone tested 13.1 Beta?

@GetVladimir
Copy link
Author

@ahuse thank you for your comment.

Yes, other users also reported that the plist gets deleted after waking from sleep on Ventura 13.0.1

It seems to affect Macs that don't have/don't use the built-in HDMI port.

The workaround at the moment is to create a backup of the working displays plist so that you can easily restore it, and to disable sleep (which is not ideal)

We'll see if it gets fixed in the next macOS update

@somogyi-ede
Copy link

somogyi-ede commented Nov 17, 2022

Hello @GetVladimir, @ahuse,
as I mentioned in my previous comment, it used to work for me initially as well, but I just noticed that it did indeed revert to YCbCr after waking from sleep/restarting.
Unfortunately it does affect the built-in HDMI ports as well as the monitor in question is connected via HDMI to an M1 Mac Mini. (I also have another monitor connected via the USB-C port, that one continues to be fine). None of the monitors have been disconnected physically, the only change that happened on my end was a couple of sleeps / restarts.

I have to mention that I didn't immediately notice that the monitor was reverted to YCbCr as it looks pretty much the same, no immediately visible artifacts on my end (aside from font smoothing, which sucks on macOS anyway and it doesn't seem to look better on RGB either).

I'm on Ventura 13.0.1.

@GetVladimir
Copy link
Author

@somogyi-ede Thank you for the update and the details.

I can't seem to replicate the issue on my end with an HDMI-to-HDMI connection on M1 Mac mini and Ventura 13.0.1

It seems to continue outputting in RGB color even after sleep/wake and restart.

I only have one modified displays plist file in /Library/Preferences and use only one monitor

@jackson-57
Copy link

I was able to test with my first DVI monitor (the one requiring plist editing on 13.0). On 13.0.1, it still doesn't work without plist editing, and the changes still don't persist properly. I think I jumped to conclusions too soon when I suggested that 13.0.1 fixed the problem, because now that I've tested more monitors, 13.0.1's behavior doesn't seem to be any different than 13.0, as far as I can tell. At least one takeaway from my testing is that not all monitors are affected by the issue. It doesn't seem to matter whether the monitor is using HDMI or DVI, some work and some don't. Same goes with whether the plist changes persist. As an example, I applied the fix just once to my 4K monitor, and it's kept working across reboots and sleep.

I do however have a potential workaround for the plist getting overwritten. I don't know if this works for all affected monitors (and it might not be practical in some scenarios), but what has worked for me is unplugging my monitor (or USB-C hub) before I close the lid on my laptop. That way, after the laptop resumes from sleep, I can just plug the monitor back in and it'll work.

I hope I haven't confused anyone too much with all of this! I'm certainly looking forward to a proper fix from Apple.

@GetVladimir
Copy link
Author

@jackson-57 thank you so much for testing this in detail and for the results!

Also, great find regarding removing the monitor/dock before sleep to prevent the plist overwriting on Ventura. This could help in finding a more persistent workaround

@csergiu
Copy link

csergiu commented Nov 19, 2022

Hmm, it seems that if I disconnect the cable (USB-C <-> USB-C), and then plug it back in, it resets to YPbPr and I have to edit the plist file again. Anyone have any idea how to force it to stay in RGB? I'm on Monterey 12.4. Thanks!

@GetVladimir
Copy link
Author

@csergiu thank you for your comment.

As a workaround, you can make a backup of the working displays plist file, so that you can restore it more easily when needed.

You can also check if it assigns a different UUID each time you connect the cable, which might also be causing the issue

@xilopaint
Copy link

Hey @GetVladimir I just received my new monitor. How can I check if my M2 Mac is outputting RGB color to the monitor?

@GetVladimir
Copy link
Author

GetVladimir commented Nov 19, 2022

@xilopaint thank you for the question and congrats on the new Mac!

The most reliable way is if there is a On-Screen Display menu (OSD) on the monitor itself where it shows the color output.

If it doesn't have the feature, then you can also tell from your Mac by going into Settings > Display and check the Color profile drop-down menu.

When you open the drop-down menu, if there is a color profile with the name starting with SD 170M-A close to the very top of the list, then your Mac is most likely outputting YCbCr color.

If the SD 170M-A profile is all the way down on the list, then it's most likely outputting correctly in RGB color.

@xilopaint
Copy link

xilopaint commented Nov 19, 2022

When you open the drop-down menu, if there is a color profile with the name starting with SD7xxx close to the very top of the list, then your Mac is most likely outputting YCbCr color.

@GetVladimir the first option is my monitor's model name and the second one is SD 170M-A. What does it indicate?

@GetVladimir
Copy link
Author

@xilopaint thanks for checking. Yes, that means it outputs in YCbCr color.

When the Mac outputs RGB color, you will just see the monitor name on top above the line. The SD 170M-A color profile will be way down on the list.

I'll update the correct name in the original comment.

@xilopaint
Copy link

@GetVladimir choosing Generic RGB Profile is not enough for fixing the issue?

@GetVladimir
Copy link
Author

@xilopaint good question. That only changes the color profile, but not the actual color output of the Mac. It still outputs in YCbCr even if you select that profile. The colors might be even less accurate in that case

@xilopaint
Copy link

@GetVladimir now I see I don't have the SD 170M-A option if I choose 100Hz as refresh rate instead of 120 Hz. Also, the colors seem to improve. Is there any other way (maybe some file I can check) to make sure my Mac outputs RGB using 100 Hz? I don't see anything like that on the display's built-in menu.

@GetVladimir
Copy link
Author

@xilopaint it's very likely that your Mac outputs in RGB color when you no longer see the SD 170M-A profile near the top. You can also notice the color difference right away, as you've said.

Except those 2 ways, there is no other easy method (that I know of) that confirms RGB color output

@xilopaint
Copy link

@GetVladimir ok, I think I feel comfortable with the colors now. Thanks for all the the fast and kind answers!

@GetVladimir
Copy link
Author

@xilopaint not a problem, glad if it helps and I'm happy to hear that you got RGB color output working

@sarabveer
Copy link

sarabveer commented Nov 20, 2022

Currently on Ventura 13.0.1. I tested my Dell S2721QS with a USB-C to DP cable. It defaults to 60Hz (not Variable which causes flickering) and the color mode shows RGB in the OSD. Seems like the issue has been fixed.

@GetVladimir
Copy link
Author

@sarabveer Awesome, thank you for the details and for the confirmation that RGB color output works on Ventura 13.0.1 with USB-C to DisplayPort cable

@skorphil
Copy link

Ventura 13.0 + Macbook Air 2020 M1 + DELL S2722QC + USB-C cable

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

Not working. After restart i still get ycbcr input format in monitor OCD and default of 40-60hz in monitor settings in MacOs

@GetVladimir
Copy link
Author

@skorphil Thank you for your comment and the info.

Could you tell me more about the connection? Is it a direct USB-C to USB-C cable or are there any docks/adapters?

@skorphil
Copy link

@skorphil Thank you for your comment and the info.

Could you tell me more about the connection? Is it a direct USB-C to USB-C cable or are there any docks/adapters?

It’s a direct connection usb-c to usb-c cable. This connection also used for charging macbook via monitor and to communicate with stuff connected to usb port inside monitor

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