The standard Qt method counts logical desktops, which differs from physical monitor count in two primary scenarios:
- Remote Desktop Sessions (Windows): When a user connects via Remote Desktop Protocol (RDP), the session may report zero active screens depending on the connection state, or the screen count might reflect the client's configuration differently than expected.
- Display Cloning (Mirror Mode): When two physical monitors are set to "Clone" or "Duplicate" mode, the operating system presents them as a single logical desktop. Consequent, Qt reports a screen count of 1, eventhough multiple physical displays are attached.
To address these limitations, platform-specific APIs must be utilized alongside Qt.
Windows Implementation
On Windows, the QueryDisplayConfig API from the Windows Display Driver Model (WDDM) allows developers to query the active display paths. This method can distinguish between logical desktops and active physical outputs, effectively identifying clone mode scenarios.
The following example demonstrates how to retrieve the count of active display paths using C++ and the Windows API:
#include <windows.h>
#include <vector>
int getActiveDisplayPathCount()
{
UINT32 pathCount = 0;
UINT32 modeCount = 0;
// Determine the buffer size required
LONG result = GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount);
if (result != ERROR_SUCCESS) {
return -1;
}
// Allocate buffers
std::vector<DISPLAYCONFIG_PATH_INFO> pathArray(pathCount);
std::vector<DISPLAYCONFIG_MODE_INFO> modeArray(modeCount);
// Query the active display configuration
result = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS,
&pathCount, pathArray.data(),
&modeCount, modeArray.data(),
nullptr);
if (result == ERROR_SUCCESS) {
return static_cast<int>(pathCount);
}
return -1;
}
In this function, QDC_ONLY_ACTIVE_PATHS ensures that only connected and active monitors are counted. If two monitors are in clone mode, this method may still report one path depending on driver implementation, but it is generally more reliable for detecting active outputs than basic desktop enumeration. Note that deep analysis of clone mode specifically often requires iterating through the path array to check sourceInfo and targetInfo details, but counting active paths is a strong baseline.
macOS Implementation
On macOS, the Core Graphics framework offers robust tools for display detection. The function CGGetActiveDisplayList retrieves a list of active displays. However, similar to Windows, mirroring can cause ambiguity. To handle this, CGDisplayIsInHWMirrorSet can verify if a display is part of a hardware mirroring set.
#include <CoreGraphics/CoreGraphics.h>
#include <qdebug.h>
int getMacosPhysicalDisplayCount()
{
uint32_t displayCount = 0;
CGError err = CGGetActiveDisplayList(0, nullptr, &displayCount);
if (err != kCGErrorSuccess) {
qDebug() << "Error retrieving display list";
return 0;
}
// If the count is greater than 1, we have multiple distinct displays
if (displayCount > 1) {
return displayCount;
}
// If count is 1, we must check if it is actually a mirror set
// CGMainDisplayID() gives us the ID of the primary display
bool isInMirror = CGDisplayIsInHWMirrorSet(CGMainDisplayID());
if (isInMirror) {
// Hardware mirror set implies multiple physical displays
// acting as one logical display
return 2;
}
return 1;
}
This logic ensures that if the system reports a single active display, the application checks if that display is mirroring content to another screen, thereby correctly identifying the multi-monitor setup.