From a Qt application I want to report the actual screen resolution, not the virtual one available from QScreen. I tried:
[[NSScreen mainScreen] backingScaleFactor]
but it returns the same value as QScreen (2 for a high dpi screen). However, in macOS, if the user has chosen a scaled resolution then this does not work.
For example, on a macbookpro with the 2880x1800 resolution and the display resolution set to default then
CGDisplayPixelsWide(CGMainDisplayID()) //returns 1440
[[NSScreen mainScreen] backingScaleFactor] //returns 2
2 * 1440 = 2880 and it works
However, when the display resolution is set to more space in system preferences:
CGDisplayPixelsWide(CGMainDisplayID()) //returns 1920
[[NSScreen mainScreen] backingScaleFactor] // still returns 2
How can I get the actual resolution?
Okay, here is my solution, which returns the monitor native resolution to my app as it is moved from one monitor to another.
// triggered by app move event
QPoint loc = centralWidget->window()->geometry().center();
// get displayID for monitor at point
CGPoint point = loc.toCGPoint();
const int maxDisplays = 8;
CGDisplayCount displayCount;
CGDirectDisplayID displayIDs[maxDisplays];
CGGetDisplaysWithPoint (point, maxDisplays, displayIDs, &displayCount);
auto displayID;
if (displayCount == 1) displayID = displayIDs[0];
else displayID = CGMainDisplayID();
// get list of all display modes for the monitor
auto modes = CGDisplayCopyAllDisplayModes(displayID, nullptr);
auto count = CFArrayGetCount(modes);
CGDisplayModeRef mode;
int displayHorizontalPixels, displayVerticalPixels = 0;
// the native resolution is the largest display mode
for(auto c = count; c--;) {
mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, c);
auto w = CGDisplayModeGetWidth(mode);
auto h = CGDisplayModeGetHeight(mode);
if (w > displayHorizontalPixels) displayHorizontalPixels = (int)w;
if (h > displayVerticalPixels) displayVerticalPixels = (int)h;
}