mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-28 07:39:49 +08: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:
parent
cdf2f6b5b4
commit
1e6936a8c3
@ -20,6 +20,7 @@ AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
@ -28,7 +29,7 @@ BraceWrapping:
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
@ -90,4 +91,4 @@ SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
UseTab: Never
|
||||
|
@ -47,28 +47,42 @@ public:
|
||||
}
|
||||
|
||||
// IFancyZones
|
||||
IFACEMETHODIMP_(void) Run() noexcept;
|
||||
IFACEMETHODIMP_(void) Destroy() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
Run() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
Destroy() noexcept;
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(bool) InMoveSize() noexcept
|
||||
IFACEMETHODIMP_(bool)
|
||||
InMoveSize() noexcept
|
||||
{
|
||||
std::shared_lock readLock(m_lock);
|
||||
return m_inMoveSize;
|
||||
}
|
||||
IFACEMETHODIMP_(void) MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void) MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void) MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void) VirtualDesktopChanged() noexcept;
|
||||
IFACEMETHODIMP_(void) VirtualDesktopInitialize() noexcept;
|
||||
IFACEMETHODIMP_(void) WindowCreated(HWND window) noexcept;
|
||||
IFACEMETHODIMP_(bool) OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept;
|
||||
IFACEMETHODIMP_(void) ToggleEditor() noexcept;
|
||||
IFACEMETHODIMP_(void) SettingsChanged() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
VirtualDesktopChanged() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
VirtualDesktopInitialize() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
WindowCreated(HWND window) noexcept;
|
||||
IFACEMETHODIMP_(bool)
|
||||
OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
ToggleEditor() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
SettingsChanged() noexcept;
|
||||
|
||||
// IZoneWindowHost
|
||||
IFACEMETHODIMP_(void) MoveWindowsOnActiveZoneSetChange() noexcept;
|
||||
IFACEMETHODIMP_(COLORREF) GetZoneHighlightColor() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowsOnActiveZoneSetChange() noexcept;
|
||||
IFACEMETHODIMP_(COLORREF)
|
||||
GetZoneHighlightColor() noexcept
|
||||
{
|
||||
// Skip the leading # and convert to long
|
||||
const auto color = m_settings->GetSettings().zoneHightlightColor;
|
||||
@ -78,7 +92,8 @@ public:
|
||||
const auto nB = (tmp & 0xFF);
|
||||
return RGB(nR, nG, nB);
|
||||
}
|
||||
IFACEMETHODIMP_(IZoneWindow*)GetParentZoneWindow(HMONITOR monitor) noexcept
|
||||
IFACEMETHODIMP_(IZoneWindow*)
|
||||
GetParentZoneWindow(HMONITOR monitor) noexcept
|
||||
{
|
||||
//NOTE: as public method it's unsafe without lock, but it's called from AddZoneWindow through making ZoneWindow that causes deadlock
|
||||
//TODO: needs refactoring
|
||||
@ -89,7 +104,8 @@ public:
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
IFACEMETHODIMP_(int) GetZoneHighlightOpacity() noexcept
|
||||
IFACEMETHODIMP_(int)
|
||||
GetZoneHighlightOpacity() noexcept
|
||||
{
|
||||
return m_settings->GetSettings().zoneHighlightOpacity;
|
||||
}
|
||||
@ -176,7 +192,8 @@ UINT FancyZones::WM_PRIV_VDINIT = RegisterWindowMessage(L"{469818a8-00fa-4069-b8
|
||||
UINT FancyZones::WM_PRIV_EDITOR = RegisterWindowMessage(L"{87543824-7080-4e91-9d9c-0404642fc7b6}");
|
||||
|
||||
// IFancyZones
|
||||
IFACEMETHODIMP_(void) FancyZones::Run() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::Run() noexcept
|
||||
{
|
||||
std::unique_lock writeLock(m_lock);
|
||||
|
||||
@ -212,7 +229,8 @@ IFACEMETHODIMP_(void) FancyZones::Run() noexcept
|
||||
}
|
||||
|
||||
// IFancyZones
|
||||
IFACEMETHODIMP_(void) FancyZones::Destroy() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::Destroy() noexcept
|
||||
{
|
||||
std::unique_lock writeLock(m_lock);
|
||||
m_zoneWindowMap.clear();
|
||||
@ -234,7 +252,8 @@ IFACEMETHODIMP_(void) FancyZones::Destroy() noexcept
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||
{
|
||||
if (IsInterestingWindow(window))
|
||||
{
|
||||
@ -244,14 +263,16 @@ IFACEMETHODIMP_(void) FancyZones::MoveSizeStart(HWND window, HMONITOR monitor, P
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||
{
|
||||
std::unique_lock writeLock(m_lock);
|
||||
MoveSizeUpdateInternal(monitor, ptScreen, writeLock);
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
||||
{
|
||||
if (window == m_windowMoveSize || IsInterestingWindow(window))
|
||||
{
|
||||
@ -261,7 +282,8 @@ IFACEMETHODIMP_(void) FancyZones::MoveSizeEnd(HWND window, POINT const& ptScreen
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::VirtualDesktopChanged() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::VirtualDesktopChanged() noexcept
|
||||
{
|
||||
// VirtualDesktopChanged is called from another thread but results in new windows being created.
|
||||
// Jump over to the UI thread to handle it.
|
||||
@ -270,13 +292,15 @@ IFACEMETHODIMP_(void) FancyZones::VirtualDesktopChanged() noexcept
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::VirtualDesktopInitialize() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::VirtualDesktopInitialize() noexcept
|
||||
{
|
||||
PostMessage(m_window, WM_PRIV_VDINIT, 0, 0);
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(void) FancyZones::WindowCreated(HWND window) noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::WindowCreated(HWND window) noexcept
|
||||
{
|
||||
if (m_settings->GetSettings().appLastZone_moveWindows && IsInterestingWindow(window))
|
||||
{
|
||||
@ -308,7 +332,8 @@ IFACEMETHODIMP_(void) FancyZones::WindowCreated(HWND window) noexcept
|
||||
}
|
||||
|
||||
// IFancyZonesCallback
|
||||
IFACEMETHODIMP_(bool) FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept
|
||||
IFACEMETHODIMP_(bool)
|
||||
FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept
|
||||
{
|
||||
// Return true to swallow the keyboard event
|
||||
bool const shift = GetAsyncKeyState(VK_SHIFT) & 0x8000;
|
||||
@ -430,9 +455,13 @@ void FancyZones::ToggleEditor() noexcept
|
||||
std::to_wstring(width) + L"_" +
|
||||
std::to_wstring(height);
|
||||
|
||||
const auto& deviceInfo = fancyZonesData.GetDeviceInfoMap().at(zoneWindow->UniqueId());
|
||||
const auto deviceInfo = fancyZonesData.FindDeviceInfo(zoneWindow->UniqueId());
|
||||
if (!deviceInfo.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSONHelpers::DeviceInfoJSON deviceInfoJson{ zoneWindow->UniqueId(), deviceInfo };
|
||||
JSONHelpers::DeviceInfoJSON deviceInfoJson{ zoneWindow->UniqueId(), *deviceInfo };
|
||||
fancyZonesData.SerializeDeviceInfoToTmpFile(deviceInfoJson, ZoneWindowUtils::GetActiveZoneSetTmpPath());
|
||||
|
||||
const std::wstring params =
|
||||
@ -484,7 +513,8 @@ void FancyZones::SettingsChanged() noexcept
|
||||
}
|
||||
|
||||
// IZoneWindowHost
|
||||
IFACEMETHODIMP_(void) FancyZones::MoveWindowsOnActiveZoneSetChange() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::MoveWindowsOnActiveZoneSetChange() noexcept
|
||||
{
|
||||
if (m_settings->GetSettings().zoneSetChange_moveWindows)
|
||||
{
|
||||
@ -566,7 +596,7 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
||||
GUID currentVirtualDesktopId{};
|
||||
if (SUCCEEDED(RegistryHelpers::GetCurrentVirtualDesktop(¤tVirtualDesktopId)))
|
||||
{
|
||||
std::unique_lock writeLock(m_lock);
|
||||
std::unique_lock writeLock(m_lock);
|
||||
m_currentVirtualDesktopId = currentVirtualDesktopId;
|
||||
}
|
||||
else
|
||||
|
@ -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);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <common/settings_helpers.h>
|
||||
#include <common/json.h>
|
||||
#include <mutex>
|
||||
|
||||
#include <string>
|
||||
#include <strsafe.h>
|
||||
@ -159,12 +160,28 @@ namespace JSONHelpers
|
||||
|
||||
class FancyZonesData
|
||||
{
|
||||
mutable std::recursive_mutex dataLock;
|
||||
|
||||
public:
|
||||
FancyZonesData();
|
||||
|
||||
const std::wstring& GetPersistFancyZonesJSONPath() const;
|
||||
inline const std::wstring& GetPersistFancyZonesJSONPath() const
|
||||
{
|
||||
return jsonFilePath;
|
||||
}
|
||||
json::JsonObject GetPersistFancyZonesJSON();
|
||||
|
||||
std::optional<DeviceInfoData> FindDeviceInfo(const std::wstring& zoneWindowId) const;
|
||||
|
||||
std::optional<CustomZoneSetData> FindCustomZoneSet(const std::wstring& guuid) const;
|
||||
|
||||
inline const std::wstring GetActiveDeviceId() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return activeDeviceId;
|
||||
}
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
inline const std::unordered_map<std::wstring, DeviceInfoData>& GetDeviceInfoMap() const
|
||||
{
|
||||
return deviceInfoMap;
|
||||
@ -180,13 +197,19 @@ namespace JSONHelpers
|
||||
return appZoneHistoryMap;
|
||||
}
|
||||
|
||||
inline const std::wstring GetActiveDeviceId() const
|
||||
inline void clear_data()
|
||||
{
|
||||
return activeDeviceId;
|
||||
appliedZoneSetsMap.clear();
|
||||
appZoneHistoryMap.clear();
|
||||
deviceInfoMap.clear();
|
||||
customZoneSetsMap.clear();
|
||||
activeDeviceId.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetActiveDeviceId(const std::wstring& deviceId)
|
||||
inline void SetActiveDeviceId(const std::wstring& deviceId)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
activeDeviceId = deviceId;
|
||||
}
|
||||
|
||||
|
@ -497,13 +497,15 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
if (SUCCEEDED_LOG(StringFromCLSID(m_config.Id, &guuidStr)))
|
||||
{
|
||||
const std::wstring guuid = guuidStr.get();
|
||||
const auto& customZoneSets = JSONHelpers::FancyZonesDataInstance().GetCustomZoneSetsMap();
|
||||
if (!customZoneSets.contains(guuid))
|
||||
|
||||
const auto zoneSetSearchResult = JSONHelpers::FancyZonesDataInstance().FindCustomZoneSet(guuid);
|
||||
|
||||
if (!zoneSetSearchResult.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& zoneSet = customZoneSets.at(guuid);
|
||||
const auto& zoneSet = *zoneSetSearchResult;
|
||||
if (zoneSet.type == JSONHelpers::CustomLayoutType::Canvas && std::holds_alternative<JSONHelpers::CanvasLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& zoneSetInfo = std::get<JSONHelpers::CanvasLayoutInfo>(zoneSet.info);
|
||||
|
@ -280,14 +280,22 @@ public:
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
||||
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP MoveSizeCancel() noexcept;
|
||||
IFACEMETHODIMP_(bool) IsDragEnabled() noexcept { return m_dragEnabled; }
|
||||
IFACEMETHODIMP_(void) MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
||||
IFACEMETHODIMP_(void) MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode) noexcept;
|
||||
IFACEMETHODIMP_(void) CycleActiveZoneSet(DWORD vkCode) noexcept;
|
||||
IFACEMETHODIMP_(std::wstring) UniqueId() noexcept { return { m_uniqueId }; }
|
||||
IFACEMETHODIMP_(std::wstring) WorkAreaKey() noexcept { return { m_workArea }; }
|
||||
IFACEMETHODIMP_(void) SaveWindowProcessToZoneIndex(HWND window) noexcept;
|
||||
IFACEMETHODIMP_(IZoneSet*) ActiveZoneSet() noexcept { return m_activeZoneSet.get(); }
|
||||
IFACEMETHODIMP_(bool)
|
||||
IsDragEnabled() noexcept { return m_dragEnabled; }
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
CycleActiveZoneSet(DWORD vkCode) noexcept;
|
||||
IFACEMETHODIMP_(std::wstring)
|
||||
UniqueId() noexcept { return { m_uniqueId }; }
|
||||
IFACEMETHODIMP_(std::wstring)
|
||||
WorkAreaKey() noexcept { return { m_workArea }; }
|
||||
IFACEMETHODIMP_(void)
|
||||
SaveWindowProcessToZoneIndex(HWND window) noexcept;
|
||||
IFACEMETHODIMP_(IZoneSet*)
|
||||
ActiveZoneSet() noexcept { return m_activeZoneSet.get(); }
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
@ -559,15 +567,21 @@ void ZoneWindow::InitializeZoneSets(MONITORINFO const& mi) noexcept
|
||||
void ZoneWindow::CalculateZoneSet() noexcept
|
||||
{
|
||||
const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
const auto& deviceInfoMap = fancyZonesData.GetDeviceInfoMap();
|
||||
const auto deviceInfoData = fancyZonesData.FindDeviceInfo(m_uniqueId);
|
||||
const auto& activeDeviceId = fancyZonesData.GetActiveDeviceId();
|
||||
const auto& activeZoneSet = deviceInfoMap.at(m_uniqueId).activeZoneSet;
|
||||
|
||||
if (!activeDeviceId.empty() && activeDeviceId != m_uniqueId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!deviceInfoData.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& activeZoneSet = deviceInfoData->activeZoneSet;
|
||||
|
||||
if (activeZoneSet.uuid.empty() || activeZoneSet.type == JSONHelpers::ZoneSetLayoutType::Blank)
|
||||
{
|
||||
return;
|
||||
@ -585,9 +599,9 @@ void ZoneWindow::CalculateZoneSet() noexcept
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (GetMonitorInfoW(m_monitor, &monitorInfo))
|
||||
{
|
||||
bool showSpacing = deviceInfoMap.at(m_uniqueId).showSpacing;
|
||||
int spacing = showSpacing ? deviceInfoMap.at(m_uniqueId).spacing : 0;
|
||||
int zoneCount = deviceInfoMap.at(m_uniqueId).zoneCount;
|
||||
bool showSpacing = deviceInfoData->showSpacing;
|
||||
int spacing = showSpacing ? deviceInfoData->spacing : 0;
|
||||
int zoneCount = deviceInfoData->zoneCount;
|
||||
zoneSet->CalculateZones(monitorInfo, zoneCount, spacing);
|
||||
UpdateActiveZoneSet(zoneSet.get());
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ namespace FancyZonesUnitTests
|
||||
m_fzCallback = fancyZones.as<IFancyZonesCallback>();
|
||||
Assert::IsTrue(m_fzCallback != nullptr);
|
||||
|
||||
m_fancyZonesData = JSONHelpers::FancyZonesData();
|
||||
m_fancyZonesData.clear_data();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -60,7 +60,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\common\Telemetry;..\..\..\..\;..\..\..\..\..\deps\cpprestsdk\include;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>UNIT_TESTS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
@ -81,7 +81,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\..\common\Telemetry;..\..\..\..\;..\..\..\..\..\deps\cpprestsdk\include;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>UNIT_TESTS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
|
@ -68,7 +68,7 @@ namespace FancyZonesUnitTests
|
||||
GUID guid;
|
||||
Assert::AreEqual(S_OK, CoCreateGuid(&guid));
|
||||
|
||||
return GuidString(guid);
|
||||
return GuidString(guid);
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
@ -89,7 +89,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetAppliedZoneSetTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetCustomZoneSetsTmpPath()));
|
||||
|
||||
m_fancyZonesData = JSONHelpers::FancyZonesData();
|
||||
m_fancyZonesData.clear_data();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
@ -622,7 +622,7 @@ namespace FancyZonesUnitTests
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = m_zoneWindow->UniqueId();
|
||||
const auto zoneSetId = m_zoneWindow->ActiveZoneSet()->Id();
|
||||
|
||||
|
||||
//fill app zone history map
|
||||
Assert::IsTrue(m_fancyZonesData.SetAppLastZone(window, deviceId, GuidString(zoneSetId), 0));
|
||||
Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size());
|
||||
|
Loading…
Reference in New Issue
Block a user