[FancyZones] Remove resolution from "device-id" (#17412)

* removed resolution from device id

* update applied layouts device id

* app zone history device id updated

* moved old device id parsing

* updated tests

* remove resolution in the editor

* remove resolution from device id generation

* update editor params
This commit is contained in:
Seraphima Zykova
2022-04-07 11:48:29 +02:00
committed by GitHub
parent 529bccc0bf
commit 98268cc10a
19 changed files with 969 additions and 928 deletions

View File

@@ -63,7 +63,8 @@ namespace NonLocalizable
// Editor arguments
const wchar_t Dpi[] = L"dpi";
const wchar_t MonitorId[] = L"monitor-id";
const wchar_t MonitorNameId[] = L"monitor";
const wchar_t VirtualDesktopId[] = L"virtual-desktop";
const wchar_t TopCoordinate[] = L"top-coordinate";
const wchar_t LeftCoordinate[] = L"left-coordinate";
const wchar_t Width[] = L"width";
@@ -74,6 +75,169 @@ namespace NonLocalizable
const wchar_t Monitors[] = L"monitors";
}
namespace BackwardsCompatibility
{
std::optional<DeviceIdData> DeviceIdData::ParseDeviceId(const std::wstring& str)
{
DeviceIdData data;
std::wstring temp;
std::wstringstream wss(str);
/*
Important fix for device info that contains a '_' in the name:
1. first search for '#'
2. Then split the remaining string by '_'
*/
// Step 1: parse the name until the #, then to the '_'
if (str.find(L'#') != std::string::npos)
{
std::getline(wss, temp, L'#');
data.deviceName = temp;
if (!std::getline(wss, temp, L'_'))
{
return std::nullopt;
}
data.deviceName += L"#" + temp;
}
else if (std::getline(wss, temp, L'_') && !temp.empty())
{
data.deviceName = temp;
}
else
{
return std::nullopt;
}
// Step 2: parse the rest of the id
std::vector<std::wstring> parts;
while (std::getline(wss, temp, L'_'))
{
parts.push_back(temp);
}
if (parts.size() != 3 && parts.size() != 4)
{
return std::nullopt;
}
/*
Refer to FancyZonesUtils::GenerateUniqueId parts contain:
1. monitor id [string]
2. width of device [int]
3. height of device [int]
4. virtual desktop id (GUID) [string]
*/
try
{
for (const auto& c : parts[0])
{
std::ignore = std::stoi(std::wstring(&c));
}
for (const auto& c : parts[1])
{
std::ignore = std::stoi(std::wstring(&c));
}
data.width = std::stoi(parts[0]);
data.height = std::stoi(parts[1]);
}
catch (const std::exception&)
{
return std::nullopt;
}
if (!SUCCEEDED(CLSIDFromString(parts[2].c_str(), &data.virtualDesktopId)))
{
return std::nullopt;
}
if (parts.size() == 4)
{
data.monitorId = parts[3]; //could be empty
}
return data;
}
bool DeviceIdData::IsValidDeviceId(const std::wstring& str)
{
std::wstring monitorName;
std::wstring temp;
std::vector<std::wstring> parts;
std::wstringstream wss(str);
/*
Important fix for device info that contains a '_' in the name:
1. first search for '#'
2. Then split the remaining string by '_'
*/
// Step 1: parse the name until the #, then to the '_'
if (str.find(L'#') != std::string::npos)
{
std::getline(wss, temp, L'#');
monitorName = temp;
if (!std::getline(wss, temp, L'_'))
{
return false;
}
monitorName += L"#" + temp;
parts.push_back(monitorName);
}
// Step 2: parse the rest of the id
while (std::getline(wss, temp, L'_'))
{
parts.push_back(temp);
}
if (parts.size() != 4)
{
return false;
}
/*
Refer to FancyZonesUtils::GenerateUniqueId parts contain:
1. monitor id [string]
2. width of device [int]
3. height of device [int]
4. virtual desktop id (GUID) [string]
*/
try
{
//check if resolution contain only digits
for (const auto& c : parts[1])
{
std::ignore = std::stoi(std::wstring(&c));
}
for (const auto& c : parts[2])
{
std::ignore = std::stoi(std::wstring(&c));
}
}
catch (const std::exception&)
{
return false;
}
if (!FancyZonesUtils::IsValidGuid(parts[3]) || parts[0].empty())
{
return false;
}
return true;
}
}
namespace
{
json::JsonArray NumVecToJsonArray(const std::vector<int>& vec)
@@ -115,13 +279,16 @@ namespace
}
std::wstring deviceIdStr = json.GetNamedString(NonLocalizable::DeviceIdStr).c_str();
auto deviceId = FancyZonesDataTypes::DeviceIdData::ParseDeviceId(deviceIdStr);
auto deviceId = BackwardsCompatibility::DeviceIdData::ParseDeviceId(deviceIdStr);
if (!deviceId.has_value())
{
return std::nullopt;
}
data.deviceId = *deviceId;
data.deviceId = FancyZonesDataTypes::DeviceIdData{
.deviceName = deviceId->deviceName,
.virtualDesktopId = deviceId->virtualDesktopId
};
data.zoneSetUuid = json.GetNamedString(NonLocalizable::ZoneSetUuidStr);
if (!FancyZonesUtils::IsValidGuid(data.zoneSetUuid))
@@ -372,88 +539,6 @@ namespace JSONHelpers
}
}
json::JsonObject AppZoneHistoryJSON::ToJson(const AppZoneHistoryJSON& appZoneHistory)
{
json::JsonObject result{};
result.SetNamedValue(NonLocalizable::AppPathStr, json::value(appZoneHistory.appPath));
json::JsonArray appHistoryArray;
for (const auto& data : appZoneHistory.data)
{
json::JsonObject desktopData;
json::JsonArray jsonIndexSet;
for (ZoneIndex index : data.zoneIndexSet)
{
jsonIndexSet.Append(json::value(static_cast<int>(index)));
}
desktopData.SetNamedValue(NonLocalizable::ZoneIndexSetStr, jsonIndexSet);
desktopData.SetNamedValue(NonLocalizable::DeviceIdStr, json::value(data.deviceId.toString()));
desktopData.SetNamedValue(NonLocalizable::ZoneSetUuidStr, json::value(data.zoneSetUuid));
appHistoryArray.Append(desktopData);
}
result.SetNamedValue(NonLocalizable::HistoryStr, appHistoryArray);
return result;
}
std::optional<AppZoneHistoryJSON> AppZoneHistoryJSON::FromJson(const json::JsonObject& zoneSet)
{
try
{
AppZoneHistoryJSON result;
result.appPath = zoneSet.GetNamedString(NonLocalizable::AppPathStr);
if (zoneSet.HasKey(NonLocalizable::HistoryStr))
{
auto appHistoryArray = zoneSet.GetNamedArray(NonLocalizable::HistoryStr);
for (uint32_t i = 0; i < appHistoryArray.Size(); ++i)
{
json::JsonObject json = appHistoryArray.GetObjectAt(i);
if (auto data = ParseSingleAppZoneHistoryItem(json); data.has_value())
{
result.data.push_back(std::move(data.value()));
}
}
}
else
{
// handle previous file format, with single desktop layout information per application
if (auto data = ParseSingleAppZoneHistoryItem(zoneSet); data.has_value())
{
result.data.push_back(std::move(data.value()));
}
}
if (result.data.empty())
{
return std::nullopt;
}
return result;
}
catch (const winrt::hresult_error&)
{
return std::nullopt;
}
}
json::JsonObject DeviceInfoJSON::ToJson(const DeviceInfoJSON& device)
{
json::JsonObject result{};
result.SetNamedValue(NonLocalizable::DeviceIdStr, json::value(device.deviceId.toString()));
result.SetNamedValue(NonLocalizable::ActiveZoneSetStr, JSONHelpers::ZoneSetDataJSON::ToJson(device.data.activeZoneSet));
result.SetNamedValue(NonLocalizable::EditorShowSpacingStr, json::value(device.data.showSpacing));
result.SetNamedValue(NonLocalizable::EditorSpacingStr, json::value(device.data.spacing));
result.SetNamedValue(NonLocalizable::EditorZoneCountStr, json::value(device.data.zoneCount));
result.SetNamedValue(NonLocalizable::EditorSensitivityRadiusStr, json::value(device.data.sensitivityRadius));
return result;
}
std::optional<DeviceInfoJSON> DeviceInfoJSON::FromJson(const json::JsonObject& device)
{
try
@@ -461,7 +546,7 @@ namespace JSONHelpers
DeviceInfoJSON result;
std::wstring deviceIdStr = device.GetNamedString(NonLocalizable::DeviceIdStr).c_str();
auto deviceId = FancyZonesDataTypes::DeviceIdData::ParseDeviceId(deviceIdStr);
auto deviceId = BackwardsCompatibility::DeviceIdData::ParseDeviceId(deviceIdStr);
if (!deviceId.has_value())
{
return std::nullopt;
@@ -527,8 +612,9 @@ namespace JSONHelpers
{
json::JsonObject result{};
result.SetNamedValue(NonLocalizable::MonitorNameId, json::value(monitor.monitorName));
result.SetNamedValue(NonLocalizable::VirtualDesktopId, json::value(monitor.virtualDesktop));
result.SetNamedValue(NonLocalizable::Dpi, json::value(monitor.dpi));
result.SetNamedValue(NonLocalizable::MonitorId, json::value(monitor.id));
result.SetNamedValue(NonLocalizable::TopCoordinate, json::value(monitor.top));
result.SetNamedValue(NonLocalizable::LeftCoordinate, json::value(monitor.left));
result.SetNamedValue(NonLocalizable::Width, json::value(monitor.width));
@@ -581,55 +667,6 @@ namespace JSONHelpers
}
}
void SaveAppZoneHistory(const std::wstring& appZoneHistoryFileName, const TAppZoneHistoryMap& appZoneHistoryMap)
{
json::JsonObject root{};
root.SetNamedValue(NonLocalizable::AppZoneHistoryStr, JSONHelpers::SerializeAppZoneHistory(appZoneHistoryMap));
auto before = json::from_file(appZoneHistoryFileName);
if (!before.has_value() || before.value().Stringify() != root.Stringify())
{
json::to_file(appZoneHistoryFileName, root);
}
}
TAppZoneHistoryMap ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON)
{
try
{
TAppZoneHistoryMap appZoneHistoryMap{};
auto appLastZones = fancyZonesDataJSON.GetNamedArray(NonLocalizable::AppZoneHistoryStr);
for (uint32_t i = 0; i < appLastZones.Size(); ++i)
{
json::JsonObject appLastZone = appLastZones.GetObjectAt(i);
if (auto appZoneHistory = AppZoneHistoryJSON::FromJson(appLastZone); appZoneHistory.has_value())
{
appZoneHistoryMap[appZoneHistory->appPath] = std::move(appZoneHistory->data);
}
}
return std::move(appZoneHistoryMap);
}
catch (const winrt::hresult_error&)
{
return {};
}
}
json::JsonArray SerializeAppZoneHistory(const TAppZoneHistoryMap& appZoneHistoryMap)
{
json::JsonArray appHistoryArray;
for (const auto& [appPath, appZoneHistoryData] : appZoneHistoryMap)
{
appHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, appZoneHistoryData }));
}
return appHistoryArray;
}
std::optional<TDeviceInfoMap> ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON)
{
try
@@ -670,7 +707,16 @@ namespace JSONHelpers
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::SensitivityRadiusID, json::value(data.sensitivityRadius));
json::JsonObject obj{};
obj.SetNamedValue(NonLocalizable::AppliedLayoutsIds::DeviceIdID, json::value(deviceID.toString()));
json::JsonObject device{};
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(deviceID.deviceName));
auto virtualDesktopStr = FancyZonesUtils::GuidToString(deviceID.virtualDesktopId);
if (virtualDesktopStr)
{
device.SetNamedValue(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID, json::value(virtualDesktopStr.value()));
}
obj.SetNamedValue(NonLocalizable::AppliedLayoutsIds::DeviceID, device);
obj.SetNamedValue(NonLocalizable::AppliedLayoutsIds::AppliedLayoutID, layout);
layoutsArray.Append(obj);