mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-07 11:46:30 +02:00
Thread safety for FanncyZonesData (#1281)
* FancyZones: make FancyZonesData thread-safe * fixup: format affected sources * fixup: clang-format case-style and format FancyZones.cpp * fixup! add missing lock
This commit is contained in:
@@ -135,13 +135,10 @@ namespace JSONHelpers
|
||||
jsonFilePath = result + L"\\" + std::wstring(FANCY_ZONES_DATA_FILE);
|
||||
}
|
||||
|
||||
const std::wstring& FancyZonesData::GetPersistFancyZonesJSONPath() const
|
||||
{
|
||||
return jsonFilePath;
|
||||
}
|
||||
|
||||
json::JsonObject FancyZonesData::GetPersistFancyZonesJSON()
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
|
||||
std::wstring save_file_path = GetPersistFancyZonesJSONPath();
|
||||
|
||||
auto result = json::from_file(save_file_path);
|
||||
@@ -155,12 +152,27 @@ namespace JSONHelpers
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<DeviceInfoData> FancyZonesData::FindDeviceInfo(const std::wstring& zoneWindowId) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = deviceInfoMap.find(zoneWindowId);
|
||||
return it != end(deviceInfoMap) ? std::optional{ it->second } : std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<CustomZoneSetData> FancyZonesData::FindCustomZoneSet(const std::wstring& guuid) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = customZoneSetsMap.find(guuid);
|
||||
return it != end(customZoneSetsMap) ? std::optional{ it->second } : std::nullopt;
|
||||
}
|
||||
|
||||
void FancyZonesData::AddDevice(const std::wstring& deviceId)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
if (!deviceInfoMap.contains(deviceId))
|
||||
{
|
||||
// Creates default entry in map when ZoneWindow is created
|
||||
deviceInfoMap[deviceId] = DeviceInfoData{ ZoneSetData{ L"null", ZoneSetLayoutType::Blank } };
|
||||
deviceInfoMap[deviceId] = DeviceInfoData{ ZoneSetData{ L"null", ZoneSetLayoutType::Blank } };
|
||||
|
||||
MigrateDeviceInfoFromRegistry(deviceId);
|
||||
}
|
||||
@@ -168,6 +180,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::CloneDeviceInfo(const std::wstring& source, const std::wstring& destination)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
// Clone information from source device if destination device is uninitialized (Blank).
|
||||
auto& destInfo = deviceInfoMap[destination];
|
||||
if (destInfo.activeZoneSet.type == ZoneSetLayoutType::Blank)
|
||||
@@ -178,6 +191,7 @@ namespace JSONHelpers
|
||||
|
||||
int FancyZonesData::GetAppLastZoneIndex(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto processPath = get_process_path(window);
|
||||
if (!processPath.empty())
|
||||
{
|
||||
@@ -188,7 +202,7 @@ namespace JSONHelpers
|
||||
if (data.zoneSetUuid == zoneSetId && data.deviceId == deviceId)
|
||||
{
|
||||
return history->second.zoneIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +211,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::RemoveAppLastZone(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto processPath = get_process_path(window);
|
||||
if (!processPath.empty())
|
||||
{
|
||||
@@ -218,6 +233,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::SetAppLastZone(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, int zoneIndex)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto processPath = get_process_path(window);
|
||||
if (processPath.empty())
|
||||
{
|
||||
@@ -231,6 +247,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::SetActiveZoneSet(const std::wstring& deviceId, const ZoneSetData& data)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = deviceInfoMap.find(deviceId);
|
||||
if (it != deviceInfoMap.end())
|
||||
{
|
||||
@@ -240,12 +257,14 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::SerializeDeviceInfoToTmpFile(const DeviceInfoJSON& deviceInfo, std::wstring_view tmpFilePath) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
json::JsonObject deviceInfoJson = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(tmpFilePath, deviceInfoJson);
|
||||
}
|
||||
|
||||
void FancyZonesData::ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
if (std::filesystem::exists(tmpFilePath))
|
||||
{
|
||||
if (auto zoneSetJson = json::from_file(tmpFilePath); zoneSetJson.has_value())
|
||||
@@ -266,6 +285,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
bool res = true;
|
||||
if (std::filesystem::exists(tmpFilePath))
|
||||
{
|
||||
@@ -291,6 +311,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
bool res = true;
|
||||
if (std::filesystem::exists(tmpFilePath))
|
||||
{
|
||||
@@ -317,6 +338,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
try
|
||||
{
|
||||
auto appLastZones = fancyZonesDataJSON.GetNamedArray(L"app-zone-history");
|
||||
@@ -344,6 +366,7 @@ namespace JSONHelpers
|
||||
|
||||
json::JsonArray FancyZonesData::SerializeAppZoneHistory() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
json::JsonArray appHistoryArray;
|
||||
|
||||
for (const auto& [appPath, appZoneHistoryData] : appZoneHistoryMap)
|
||||
@@ -356,6 +379,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
try
|
||||
{
|
||||
auto devices = fancyZonesDataJSON.GetNamedArray(L"devices");
|
||||
@@ -382,11 +406,13 @@ namespace JSONHelpers
|
||||
|
||||
json::JsonArray FancyZonesData::SerializeDeviceInfos() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
json::JsonArray DeviceInfosJSON{};
|
||||
|
||||
for (const auto& [deviceID, deviceData] : deviceInfoMap)
|
||||
{
|
||||
if (deviceData.activeZoneSet.type != ZoneSetLayoutType::Blank) {
|
||||
if (deviceData.activeZoneSet.type != ZoneSetLayoutType::Blank)
|
||||
{
|
||||
DeviceInfosJSON.Append(DeviceInfoJSON::DeviceInfoJSON::ToJson(DeviceInfoJSON{ deviceID, deviceData }));
|
||||
}
|
||||
}
|
||||
@@ -396,6 +422,7 @@ namespace JSONHelpers
|
||||
|
||||
bool FancyZonesData::ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
try
|
||||
{
|
||||
auto customZoneSets = fancyZonesDataJSON.GetNamedArray(L"custom-zone-sets");
|
||||
@@ -418,6 +445,7 @@ namespace JSONHelpers
|
||||
|
||||
json::JsonArray FancyZonesData::SerializeCustomZoneSets() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
json::JsonArray customZoneSetsJSON{};
|
||||
|
||||
for (const auto& [zoneSetId, zoneSetData] : customZoneSetsMap)
|
||||
@@ -430,6 +458,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::CustomZoneSetsToJsonFile(std::wstring_view filePath) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
const auto& customZoneSetsJson = SerializeCustomZoneSets();
|
||||
json::JsonObject root{};
|
||||
root.SetNamedValue(L"custom-zone-sets", customZoneSetsJson);
|
||||
@@ -438,6 +467,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::LoadFancyZonesData()
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
std::wstring jsonFilePath = GetPersistFancyZonesJSONPath();
|
||||
|
||||
if (!std::filesystem::exists(jsonFilePath))
|
||||
@@ -461,6 +491,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::SaveFancyZonesData() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
json::JsonObject root{};
|
||||
|
||||
root.SetNamedValue(L"app-zone-history", SerializeAppZoneHistory());
|
||||
@@ -474,6 +505,7 @@ namespace JSONHelpers
|
||||
{
|
||||
std::wregex ex(L"^[0-9]{3,4}_[0-9]{3,4}$");
|
||||
|
||||
std::scoped_lock lock{ dataLock };
|
||||
wchar_t key[256];
|
||||
StringCchPrintf(key, ARRAYSIZE(key), L"%s", RegistryHelpers::REG_SETTINGS);
|
||||
HKEY hkey;
|
||||
@@ -521,6 +553,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::MigrateDeviceInfoFromRegistry(const std::wstring& deviceId)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
wchar_t key[256];
|
||||
StringCchPrintf(key, ARRAYSIZE(key), L"%s\\%s", RegistryHelpers::REG_SETTINGS, deviceId.c_str());
|
||||
|
||||
@@ -546,6 +579,7 @@ namespace JSONHelpers
|
||||
|
||||
void FancyZonesData::MigrateCustomZoneSetsFromRegistry()
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
wchar_t key[256];
|
||||
StringCchPrintf(key, ARRAYSIZE(key), L"%s\\%s", RegistryHelpers::REG_SETTINGS, L"Layouts");
|
||||
HKEY hkey;
|
||||
@@ -574,8 +608,7 @@ namespace JSONHelpers
|
||||
}
|
||||
switch (zoneSetData.type)
|
||||
{
|
||||
case CustomLayoutType::Grid:
|
||||
{
|
||||
case CustomLayoutType::Grid: {
|
||||
int j = 5;
|
||||
GridLayoutInfo zoneSetInfo(GridLayoutInfo::Minimal{ .rows = data[j++], .columns = data[j++] });
|
||||
|
||||
@@ -599,8 +632,7 @@ namespace JSONHelpers
|
||||
zoneSetData.info = zoneSetInfo;
|
||||
break;
|
||||
}
|
||||
case CustomLayoutType::Canvas:
|
||||
{
|
||||
case CustomLayoutType::Canvas: {
|
||||
CanvasLayoutInfo info;
|
||||
|
||||
int j = 5;
|
||||
@@ -880,8 +912,7 @@ namespace JSONHelpers
|
||||
result.SetNamedValue(L"name", json::value(customZoneSet.data.name));
|
||||
switch (customZoneSet.data.type)
|
||||
{
|
||||
case CustomLayoutType::Canvas:
|
||||
{
|
||||
case CustomLayoutType::Canvas: {
|
||||
result.SetNamedValue(L"type", json::value(L"canvas"));
|
||||
|
||||
CanvasLayoutInfo info = std::get<CanvasLayoutInfo>(customZoneSet.data.info);
|
||||
@@ -889,8 +920,7 @@ namespace JSONHelpers
|
||||
|
||||
break;
|
||||
}
|
||||
case CustomLayoutType::Grid:
|
||||
{
|
||||
case CustomLayoutType::Grid: {
|
||||
result.SetNamedValue(L"type", json::value(L"grid"));
|
||||
|
||||
GridLayoutInfo gridInfo = std::get<GridLayoutInfo>(customZoneSet.data.info);
|
||||
|
||||
Reference in New Issue
Block a user