[FancyZones] Monitor id comparison fix (#19312)

* added monitor number to id comparison

* added monitor number to id in editor

* empty serial number comparison
This commit is contained in:
Seraphima Zykova
2022-07-11 17:39:03 +02:00
committed by GitHub
parent c36a80dad5
commit 73c259342b
12 changed files with 150 additions and 60 deletions

View File

@@ -25,6 +25,7 @@ namespace JsonUtils
std::wstring monitorName;
std::wstring monitorInstanceId;
std::wstring monitorSerialNumber;
int monitorNumber;
std::wstring virtualDesktop;
int dpi;
int top;
@@ -42,6 +43,7 @@ namespace JsonUtils
result.SetNamedValue(NonLocalizable::EditorParametersIds::MonitorNameId, json::value(monitor.monitorName));
result.SetNamedValue(NonLocalizable::EditorParametersIds::MonitorInstanceId, json::value(monitor.monitorInstanceId));
result.SetNamedValue(NonLocalizable::EditorParametersIds::MonitorSerialNumberId, json::value(monitor.monitorSerialNumber));
result.SetNamedValue(NonLocalizable::EditorParametersIds::MonitorNumberId, json::value(monitor.monitorNumber));
result.SetNamedValue(NonLocalizable::EditorParametersIds::VirtualDesktopId, json::value(monitor.virtualDesktop));
result.SetNamedValue(NonLocalizable::EditorParametersIds::Dpi, json::value(monitor.dpi));
result.SetNamedValue(NonLocalizable::EditorParametersIds::TopCoordinate, json::value(monitor.top));
@@ -116,6 +118,7 @@ bool EditorParameters::Save() noexcept
JsonUtils::MonitorInfo monitorJson;
monitorJson.monitorName = ZonedWindowProperties::MultiMonitorName;
monitorJson.monitorInstanceId = ZonedWindowProperties::MultiMonitorInstance;
monitorJson.monitorNumber = 0;
monitorJson.virtualDesktop = virtualDesktopIdStr.value();
monitorJson.top = combinedWorkArea.top;
monitorJson.left = combinedWorkArea.left;
@@ -172,6 +175,7 @@ bool EditorParameters::Save() noexcept
monitorJson.monitorName = monitorData.deviceId.id;
monitorJson.monitorInstanceId = monitorData.deviceId.instanceId;
monitorJson.monitorNumber = monitorData.deviceId.number;
monitorJson.monitorSerialNumber = monitorData.serialNumber;
monitorJson.virtualDesktop = virtualDesktopIdStr.value();

View File

@@ -8,6 +8,7 @@ namespace NonLocalizable
const static wchar_t* MonitorNameId = L"monitor";
const static wchar_t* MonitorInstanceId = L"monitor-instance-id";
const static wchar_t* MonitorSerialNumberId = L"monitor-serial-number";
const static wchar_t* MonitorNumberId = L"monitor-number";
const static wchar_t* VirtualDesktopId = L"virtual-desktop";
const static wchar_t* TopCoordinate = L"top-coordinate";
const static wchar_t* LeftCoordinate = L"left-coordinate";

View File

@@ -27,6 +27,7 @@ namespace JsonUtils
std::wstring monitor = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorID).c_str();
std::wstring monitorInstance = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorInstanceID, L"").c_str();
std::wstring monitorSerialNumber = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::MonitorSerialNumberID, L"").c_str();
int monitorNumber = static_cast<int>(device.GetNamedNumber(NonLocalizable::AppZoneHistoryIds::MonitorNumberID, 0));
std::wstring virtualDesktop = device.GetNamedString(NonLocalizable::AppZoneHistoryIds::VirtualDesktopID).c_str();
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
@@ -45,6 +46,7 @@ namespace JsonUtils
{
deviceId.id = monitor;
deviceId.instanceId = monitorInstance;
deviceId.number = monitorNumber;
}
FancyZonesDataTypes::MonitorId monitorId{
@@ -175,6 +177,7 @@ namespace JsonUtils
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorID, json::value(data.workAreaId.monitorId.deviceId.id));
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorInstanceID, json::value(data.workAreaId.monitorId.deviceId.instanceId));
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorSerialNumberID, json::value(data.workAreaId.monitorId.serialNumber));
device.SetNamedValue(NonLocalizable::AppZoneHistoryIds::MonitorNumberID, json::value(data.workAreaId.monitorId.deviceId.number));
auto virtualDesktopStr = FancyZonesUtils::GuidToString(data.workAreaId.virtualDesktopId);
if (virtualDesktopStr)
@@ -308,13 +311,16 @@ void AppZoneHistory::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::Mo
for (auto& dataIter = data.begin(); dataIter != data.end(); ++dataIter)
{
auto& dataMonitorId = dataIter->workAreaId.monitorId;
if (dataMonitorId.serialNumber.empty() && !dataMonitorId.deviceId.isDefault())
bool serialNumberNotSet = dataMonitorId.serialNumber.empty() && !dataMonitorId.deviceId.isDefault();
bool monitorNumberNotSet = dataMonitorId.deviceId.number == 0;
if (serialNumberNotSet || monitorNumberNotSet)
{
for (const auto& monitorId : ids)
{
if (dataMonitorId.deviceId.id == monitorId.deviceId.id && dataMonitorId.deviceId.instanceId == monitorId.deviceId.instanceId)
{
dataMonitorId.serialNumber = monitorId.serialNumber;
dataMonitorId.deviceId.number = monitorId.deviceId.number;
dirtyFlag = true;
break;
}

View File

@@ -19,6 +19,7 @@ namespace NonLocalizable
const static wchar_t* MonitorID = L"monitor";
const static wchar_t* MonitorInstanceID = L"monitor-instance";
const static wchar_t* MonitorSerialNumberID = L"serial-number";
const static wchar_t* MonitorNumberID = L"monitor-number";
const static wchar_t* VirtualDesktopID = L"virtual-desktop";
}
}

View File

@@ -83,6 +83,7 @@ namespace JsonUtils
std::wstring monitor = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorID).c_str();
std::wstring monitorInstance = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, L"").c_str();
std::wstring monitorSerialNumber = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, L"").c_str();
int monitorNumber = static_cast<int>(device.GetNamedNumber(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, 0));
std::wstring virtualDesktop = device.GetNamedString(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID).c_str();
auto virtualDesktopGuid = FancyZonesUtils::GuidFromString(virtualDesktop);
@@ -101,6 +102,7 @@ namespace JsonUtils
{
deviceId.id = monitor;
deviceId.instanceId = monitorInstance;
deviceId.number = monitorNumber;
}
FancyZonesDataTypes::MonitorId monitorId{
@@ -172,6 +174,7 @@ namespace JsonUtils
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(value.workAreaId.monitorId.deviceId.id));
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(value.workAreaId.monitorId.deviceId.instanceId));
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(value.workAreaId.monitorId.serialNumber));
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, json::value(value.workAreaId.monitorId.deviceId.number));
auto virtualDesktopStr = FancyZonesUtils::GuidToString(value.workAreaId.virtualDesktopId);
if (virtualDesktopStr)
@@ -294,17 +297,22 @@ void AppliedLayouts::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::Mo
{
bool dirtyFlag = false;
std::vector<std::pair<FancyZonesDataTypes::WorkAreaId, std::wstring>> replaceWithSerialNumber{};
std::vector<std::pair<FancyZonesDataTypes::WorkAreaId, FancyZonesDataTypes::WorkAreaId>> replaceWithSerialNumber{};
for (auto iter = m_layouts.begin(); iter != m_layouts.end(); ++iter)
{
const auto& [id, layout] = *iter;
if (id.monitorId.serialNumber.empty() && !id.monitorId.deviceId.isDefault())
bool serialNumberNotSet = id.monitorId.serialNumber.empty() && !id.monitorId.deviceId.isDefault();
bool monitorNumberNotSet = id.monitorId.deviceId.number == 0;
if (serialNumberNotSet || monitorNumberNotSet)
{
for (const auto& monitorId : ids)
{
if (id.monitorId.deviceId.id == monitorId.deviceId.id && id.monitorId.deviceId.instanceId == monitorId.deviceId.instanceId)
{
replaceWithSerialNumber.push_back({ id, monitorId.serialNumber });
FancyZonesDataTypes::WorkAreaId updatedId = id;
updatedId.monitorId.serialNumber = monitorId.serialNumber;
updatedId.monitorId.deviceId.number = monitorId.deviceId.number;
replaceWithSerialNumber.push_back({ id, updatedId });
dirtyFlag = true;
break;
}
@@ -315,7 +323,7 @@ void AppliedLayouts::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::Mo
for (const auto& id : replaceWithSerialNumber)
{
auto mapEntry = m_layouts.extract(id.first);
mapEntry.key().monitorId.serialNumber = id.second;
mapEntry.key().monitorId = id.second.monitorId;
m_layouts.insert(std::move(mapEntry));
}

View File

@@ -20,6 +20,7 @@ namespace NonLocalizable
const static wchar_t* MonitorID = L"monitor";
const static wchar_t* MonitorInstanceID = L"monitor-instance";
const static wchar_t* MonitorSerialNumberID = L"serial-number";
const static wchar_t* MonitorNumberID = L"monitor-number";
const static wchar_t* VirtualDesktopID = L"virtual-desktop";
const static wchar_t* AppliedLayoutID = L"applied-layout";
const static wchar_t* UuidID = L"uuid";

View File

@@ -131,7 +131,7 @@ namespace FancyZonesDataTypes
std::wstring DeviceId::toString() const noexcept
{
return id + L"_" + instanceId;
return id + L"_" + instanceId + L"_" + std::to_wstring(number);
}
bool DeviceId::isDefault() const noexcept

View File

@@ -117,6 +117,7 @@ namespace FancyZonesDataTypes
{
std::wstring id;
std::wstring instanceId;
int number;
bool isDefault() const noexcept;
std::wstring toString() const noexcept;
@@ -169,12 +170,17 @@ namespace FancyZonesDataTypes
inline bool operator==(const DeviceId& lhs, const DeviceId& rhs)
{
if (lhs.isDefault())
if (lhs.id != rhs.id)
{
return lhs.instanceId == rhs.instanceId;
return false;
}
return lhs.id == rhs.id;
if (lhs.instanceId != rhs.instanceId)
{
return lhs.number == rhs.number;
}
return true;
}
inline bool operator<(const DeviceId& lhs, const DeviceId& rhs)
@@ -189,7 +195,7 @@ namespace FancyZonesDataTypes
return lhs.monitor == rhs.monitor;
}
if (!lhs.serialNumber.empty() || !rhs.serialNumber.empty())
if (!lhs.serialNumber.empty() && !rhs.serialNumber.empty())
{
bool serialNumbersEqual = lhs.serialNumber == rhs.serialNumber;
if (!serialNumbersEqual)

View File

@@ -207,6 +207,18 @@ namespace MonitorUtils
return { .id = str.substr(0, dividerPos), .instanceId = str.substr(dividerPos + 1) };
}
inline bool not_digit(wchar_t ch)
{
return '0' <= ch && ch <= '9';
}
std::wstring remove_non_digits(const std::wstring& input)
{
std::wstring result;
std::copy_if(input.begin(), input.end(), std::back_inserter(result), not_digit);
return result;
}
std::vector<FancyZonesDataTypes::MonitorId> GetDisplays()
{
auto allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>();
@@ -226,9 +238,24 @@ namespace MonitorUtils
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) };
Logger::info(L"Display: {}", displayDevice.DeviceID);
result.push_back({ .monitor = monitorData.first, .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);
id.deviceId.number = std::stoi(numberStr);
}
catch (...)
{
Logger::error(L"Failed to get monitor number from {}", displayDevice.DeviceName);
}
result.push_back(std::move(id));
}
return result;

View File

@@ -73,36 +73,6 @@ namespace FancyZonesUnitTests
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (NoSerialNumber)
{
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (NoSerialNumber2)
{
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (DifferentSerialNumber)
{
FancyZonesDataTypes::WorkAreaId id1{
@@ -118,15 +88,30 @@ namespace FancyZonesUnitTests
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (DefaultMonitorIdDifferentInstanceId)
TEST_METHOD (DefaultMonitorIdDifferentInstanceIdSameNumber)
{
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"instance-id" }, .serialNumber = L"" },
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"instance-id", .number = 1 }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"another-instance-id" }, .serialNumber = L"" },
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"another-instance-id", .number = 1 }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsTrue(id1 == id2);
}
TEST_METHOD (DefaultMonitorIdDifferentInstanceIdDifferentNumber)
{
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"instance-id", .number = 1 }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"Default_Monitor", .instanceId = L"another-instance-id", .number = 2 }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
@@ -163,21 +148,6 @@ namespace FancyZonesUnitTests
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (SameIdDifferentInstance)
{
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id-1" }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id-2" }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsTrue(id1 == id2);
}
TEST_METHOD (SameIdDifferentSerialNumbers)
{
FancyZonesDataTypes::WorkAreaId id1{
@@ -207,6 +177,59 @@ namespace FancyZonesUnitTests
Assert::IsFalse(id1 == id2);
}
TEST_METHOD (MonitorReconnect)
{
// same: id, serial number and monitor number
// different: instance id
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"4&125707d6&0&UID1", .number = 1 }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"4&125707d6&0&UID2", .number = 1 }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsTrue(id1 == id2);
}
TEST_METHOD (SameMonitorModels)
{
// same: id, serial number
// different: monitor number, instance id
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"4&125707d6&0&UID1", .number = 1 }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"4&125707d6&0&UID2", .number = 2 }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsFalse(id1 == id2);
}
TEST_METHOD(SerialNumberNotFoundError)
{
// serial number is empty, other values are the same
FancyZonesDataTypes::WorkAreaId id1{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id", .number = 1 }, .serialNumber = L"serial-number" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
FancyZonesDataTypes::WorkAreaId id2{
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id", .number = 1 }, .serialNumber = L"" },
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
};
Assert::IsTrue(id1 == id2);
}
};
}

View File

@@ -17,6 +17,8 @@ namespace FancyZonesEditor.Utils
public string MonitorSerialNumber { get; set; }
public int MonitorNumber { get; set; }
public Size MonitorSize { get; set; }
public string VirtualDesktopId { get; set; }

View File

@@ -81,6 +81,8 @@ namespace FancyZonesEditor.Utils
public string MonitorSerialNumber { get; set; }
public int MonitorNumber { get; set; }
public string VirtualDesktop { get; set; }
public int Dpi { get; set; }
@@ -134,6 +136,8 @@ namespace FancyZonesEditor.Utils
public string MonitorInstance { get; set; }
public int MonitorNumber { get; set; }
public string SerialNumber { get; set; }
public string VirtualDesktop { get; set; }
@@ -319,6 +323,7 @@ namespace FancyZonesEditor.Utils
string targetMonitorId = string.Empty;
string targetMonitorSerialNumber = string.Empty;
string targetVirtualDesktop = string.Empty;
int targetMonitorNumber = 0;
foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
@@ -327,6 +332,7 @@ namespace FancyZonesEditor.Utils
{
targetMonitorId = nativeData.Monitor;
targetMonitorSerialNumber = nativeData.MonitorSerialNumber;
targetMonitorNumber = nativeData.MonitorNumber;
targetVirtualDesktop = nativeData.VirtualDesktop;
}
@@ -336,6 +342,7 @@ namespace FancyZonesEditor.Utils
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
monitor.Device.Dpi = nativeData.Dpi;
@@ -349,6 +356,7 @@ namespace FancyZonesEditor.Utils
var monitor = monitors[i];
if (monitor.Device.MonitorName == targetMonitorId &&
monitor.Device.MonitorSerialNumber == targetMonitorSerialNumber &&
monitor.Device.MonitorNumber == targetMonitorNumber &&
monitor.Device.VirtualDesktopId == targetVirtualDesktop)
{
App.Overlay.CurrentDesktop = i;
@@ -371,6 +379,7 @@ namespace FancyZonesEditor.Utils
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
App.Overlay.AddMonitor(monitor);
@@ -571,6 +580,7 @@ namespace FancyZonesEditor.Utils
{
Monitor = monitor.Device.MonitorName,
MonitorInstance = monitor.Device.MonitorInstanceId,
MonitorNumber = monitor.Device.MonitorNumber,
SerialNumber = monitor.Device.MonitorSerialNumber,
VirtualDesktop = monitor.Device.VirtualDesktopId,
},
@@ -838,6 +848,7 @@ namespace FancyZonesEditor.Utils
{
if (monitor.Device.MonitorName == layout.Device.Monitor &&
monitor.Device.MonitorSerialNumber == layout.Device.SerialNumber &&
monitor.Device.MonitorNumber == layout.Device.MonitorNumber &&
(monitor.Device.VirtualDesktopId == layout.Device.VirtualDesktop ||
layout.Device.VirtualDesktop == DefaultVirtualDesktopGuid))
{