From 0fbec1ca023c2ee2cdc842c3720118d3f3a8e95a Mon Sep 17 00:00:00 2001 From: Jaime Bernardo Date: Wed, 13 Jul 2022 11:53:18 +0100 Subject: [PATCH] [FancyZones]Fallback and fixes for GetDisplays (#19380) * [FancyZones]Fallback and fixes for GetDisplays * fix infinite cycle --- .../fancyzones/FancyZonesLib/MonitorUtils.cpp | 75 +++++++++++++------ 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp b/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp index 6cda1408cb..70209a16c0 100644 --- a/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp +++ b/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp @@ -222,7 +222,6 @@ namespace MonitorUtils std::vector GetDisplays() { auto allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); - std::unordered_map displayDeviceIdxMap; std::vector result{}; for (auto& monitorData : allMonitors) @@ -230,32 +229,64 @@ namespace MonitorUtils auto monitorInfo = monitorData.second; DISPLAY_DEVICE displayDevice{ .cb = sizeof(displayDevice) }; - std::wstring deviceId; - auto enumRes = EnumDisplayDevicesW(monitorInfo.szDevice, displayDeviceIdxMap[monitorInfo.szDevice], &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME); - if (!enumRes) - { - Logger::error(L"EnumDisplayDevicesW error: {}", get_last_error_or_default(GetLastError())); - continue; - } - - Logger::info(L"Display: {}, number: {}", displayDevice.DeviceID); - FancyZonesDataTypes::MonitorId id{ .monitor = monitorData.first, .deviceId = SplitDisplayDeviceId(displayDevice.DeviceID) }; + FancyZonesDataTypes::MonitorId monitorId { + .monitor = monitorData.first + }; - try + bool foundActiveMonitor = false; + + DWORD displayDeviceIndex = 0; + + while (EnumDisplayDevicesW(monitorInfo.szDevice, displayDeviceIndex, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME)) { - std::wstring numberStr = displayDevice.DeviceName; // \\.\DISPLAY1\Monitor0 - numberStr = numberStr.substr(0, numberStr.find_last_of('\\')); // \\.\DISPLAY1 - numberStr = remove_non_digits(numberStr); - id.deviceId.number = std::stoi(numberStr); - } - catch (...) - { - Logger::error(L"Failed to get monitor number from {}", displayDevice.DeviceName); + Logger::info(L"Get display device for display {} : {}", monitorInfo.szDevice, displayDevice.DeviceID); + if (WI_IsFlagSet(displayDevice.StateFlags, DISPLAY_DEVICE_ACTIVE) && + WI_IsFlagClear(displayDevice.StateFlags, DISPLAY_DEVICE_MIRRORING_DRIVER)) + { + // Find display devices associated with the display. + foundActiveMonitor = true; + break; + } + displayDeviceIndex++; } - result.push_back(std::move(id)); - + if (foundActiveMonitor) + { + monitorId.deviceId = SplitDisplayDeviceId(displayDevice.DeviceID); + try + { + std::wstring numberStr = displayDevice.DeviceName; // \\.\DISPLAY1\Monitor0 + numberStr = numberStr.substr(0, numberStr.find_last_of('\\')); // \\.\DISPLAY1 + numberStr = remove_non_digits(numberStr); + monitorId.deviceId.number = std::stoi(numberStr); + } + catch (...) + { + Logger::error(L"Failed to get monitor number from {}", displayDevice.DeviceName); + monitorId.deviceId.number = 0; + } + } + else + { + // Use the display name when no proper device was found. + monitorId.deviceId.id = monitorInfo.szDevice; + monitorId.deviceId.instanceId = L""; + Logger::info(L"No active monitor found for {} : {}", monitorInfo.szDevice, get_last_error_or_default(GetLastError())); + try + { + std::wstring numberStr = monitorInfo.szDevice; // \\.\DISPLAY1 + numberStr = remove_non_digits(numberStr); + monitorId.deviceId.number = std::stoi(numberStr); + } + catch (...) + { + Logger::error(L"Failed to get display number from {}", monitorInfo.szDevice); + monitorId.deviceId.number = 0; + } + } + + result.push_back(std::move(monitorId)); } return result;