Most users of my Lunar app (<a href="https://lunar.fyi" rel="nofollow">https://lunar.fyi</a>) that were coming from Windows, have been praising the Windows multi monitor experience while the Mac felt limited in the handling of external monitors.<p>I admit that finding a way to change monitor brightness [1] or turn off individual displays [2] wasn’t as straightforward and needed a lot of reverse engineering. But macOS has a much nicer API [3] for configuring screen position, resolution, mirroring etc.<p>It’s not without its quirks however, I ran into a lot of bugs while developing the Blackout feature when having to create multiple mirror sets with multiple displays in each one. I finally had to reverse engineer the MonitorPanel.framework that’s used by System Preferences to get that functionality. [4]<p>From my understanding, Windows has a native way of disabling a display in software so this wouldn’t even be needed there.<p>[1] <a href="https://alinpanaitiu.com/blog/journey-to-ddc-on-m1-macs/" rel="nofollow">https://alinpanaitiu.com/blog/journey-to-ddc-on-m1-macs/</a><p>[2] <a href="https://lunar.fyi/#blackout" rel="nofollow">https://lunar.fyi/#blackout</a><p>[3] <a href="https://developer.apple.com/documentation/coregraphics/quartz_display_services" rel="nofollow">https://developer.apple.com/documentation/coregraphics/quart...</a><p>[4] <a href="https://github.com/alin23/monitorpanel" rel="nofollow">https://github.com/alin23/monitorpanel</a>
The documentation--the very links that OP provided--<i>does</i> say all of this. Look in the "Remarks" section of EnumDisplayDevices and ChangeDisplaySettings.
I wrote an F# tool specifically for changing the primary display not too long ago. This is the code that calls the Win32 API to query the displays and set the primary one.<p><a href="https://github.com/steinuil/SatouinDp/blob/master/DisplayDevice.fs" rel="nofollow">https://github.com/steinuil/SatouinDp/blob/master/DisplayDev...</a><p>One thing I never figured out was how to map the displays you get from EnumDisplayDevices to the names you see in the display settings, or how to list them in a consistent order.
I thought ChangeDisplaySettingsEx and EnumDisplaySettings are superseded by SetDisplayConfig and QueryDisplayConfig, respectively? <a href="https://github.com/MicrosoftDocs/windows-driver-docs/blob/staging/windows-driver-docs-pr/display/scaling-the-desktop-image.md" rel="nofollow">https://github.com/MicrosoftDocs/windows-driver-docs/blob/st...</a> calls ChangeDisplaySettingsEx "legacy API".<p>From my experience, changing topology using SetDisplayConfig is straightforward.
I have been thinking to automate "when an app enters fullscreen, disable all the non-primary screens". mostly for gaming. Thanks for the MultiMonitorTool hint as that will probably help in combination with AHK! I'm trying to avoid composite.
On a somehow related note, I can't recommend MouseUnSnag enough for multimonitors setups <a href="https://github.com/MouseUnSnag/MouseUnSnag" rel="nofollow">https://github.com/MouseUnSnag/MouseUnSnag</a>
The coordinate system reminds me of an interesting trivia I read from The Old New Thing:<p>Windows 9x “parks” minimized windows at (3000, 3000) , a coordinate that is unlikely to be seen, at the time (remember 1024x768 was hi-res?)<p><a href="https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453" rel="nofollow">https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37...</a>
When you have used the display config tool in Windows 9x to XP, you see why this API is like this.<p>The API lets you position each monitor independently on the 'virtual desktop', and sometimes there are constraints which mean certain positions aren't possible - and the API needs to give feedback on if a position, colour depth and resolution is allowed. Then you hit 'apply' and the change takes effect.<p>I don't really see any better way to implement the API without leaking implementation details which might change in future windows versions.
nircmd has this functionality (haven't tried it myself so no guarantees)<p><a href="https://nircmd.nirsoft.net/setprimarydisplay.html" rel="nofollow">https://nircmd.nirsoft.net/setprimarydisplay.html</a><p>It also has a bunch of other useful features like changing the default audio device (something I use every day) and opening the CD tray ;)<p>Anyway, it's the best tool I've used for scripting stuff on windows. No GUI, just a bunch of useful or less useful command line utilities.
Respect to all those folks who seem to comfortably write Win32 code in Rust. I'm so used to the original C/C++ syntax I need to constantly translate between these in my brain, it hurts.