mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[FancyZones] Split and reorganize FancyZonesData and JSON Helpers (#5028)
* Rename JsonHelpers to FancyZonesData Add new JsonHelpers.[h|cpp] files * Introduce FancyZonesDataTypes * Move first part of JSON related stuff to JsonHelpers files * Small refactor * Move all json related stuff to JsonHelpers * Minor refactoring * Fix formating * Remove GetPersistFancyZonesJSONPath() and GetPersistAppZoneHistoryFilePath() Remove GetActiveZoneSetTmpPath(), GetDeletedCustomZoneSetsTmpPath and GetAppliedZoneSetTmpPath() Simplify tests * Address PR comment - Rename FancyZonesDataNS to FancyZonesData * Address PR comment - Rename local var * Delete obsolete stuff * Remove double and uneeded includes Introduce const non-localizable string variables Address all othe PR comments * Add comments to explain hardcoded values * Remove FancyZonesData namespace * Introduce const non-localizable string variables in FancyZonesDataTypes * Add comments to explain FancyZonesData maps Co-authored-by: Clint Rutkas <clint@rutkas.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <lib/trace.h>
|
||||
#include <lib/Settings.h>
|
||||
#include <lib/FancyZones.h>
|
||||
#include <lib/FancyZonesData.h>
|
||||
#include <lib/FancyZonesWinHookEventIDs.h>
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
@@ -153,7 +154,7 @@ public:
|
||||
{
|
||||
app_name = GET_RESOURCE_STRING(IDS_FANCYZONES);
|
||||
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), FancyZonesModule::get_name());
|
||||
JSONHelpers::FancyZonesDataInstance().LoadFancyZonesData();
|
||||
FancyZonesDataInstance().LoadFancyZonesData();
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,5 @@ namespace FancyZonesEditor
|
||||
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
internal delegate int PersistZoneSet(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string activeKey,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string resolutionKey,
|
||||
uint monitor,
|
||||
ushort layoutId,
|
||||
int zoneCount,
|
||||
[MarshalAs(UnmanagedType.LPArray)] int[] zoneArray);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "FancyZones.h"
|
||||
#include "lib/Settings.h"
|
||||
#include "lib/ZoneWindow.h"
|
||||
#include "lib/JsonHelpers.h"
|
||||
#include "lib/FancyZonesData.h"
|
||||
#include "lib/ZoneSet.h"
|
||||
#include "lib/WindowMoveHandler.h"
|
||||
#include "lib/FancyZonesWinHookEventIDs.h"
|
||||
@@ -373,7 +373,7 @@ std::vector<int> FancyZones::GetZoneIndexSetFromWorkAreaHistory(
|
||||
wil::unique_cotaskmem_string zoneSetId;
|
||||
if (SUCCEEDED(StringFromCLSID(activeZoneSet->Id(), &zoneSetId)))
|
||||
{
|
||||
return JSONHelpers::FancyZonesDataInstance().GetAppLastZoneIndexSet(window, workArea->UniqueId(), zoneSetId.get());
|
||||
return FancyZonesDataInstance().GetAppLastZoneIndexSet(window, workArea->UniqueId(), zoneSetId.get());
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@@ -419,7 +419,7 @@ std::pair<winrt::com_ptr<IZoneWindow>, std::vector<int>> FancyZones::GetAppZoneH
|
||||
|
||||
void FancyZones::MoveWindowIntoZone(HWND window, winrt::com_ptr<IZoneWindow> zoneWindow, const std::vector<int>& zoneIndexSet) noexcept
|
||||
{
|
||||
auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
auto& fancyZonesData = FancyZonesDataInstance();
|
||||
if (!fancyZonesData.IsAnotherWindowOfApplicationInstanceZoned(window, zoneWindow->UniqueId()))
|
||||
{
|
||||
m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, zoneWindow);
|
||||
@@ -650,17 +650,13 @@ void FancyZones::ToggleEditor() noexcept
|
||||
std::to_wstring(width) + L"_" +
|
||||
std::to_wstring(height);
|
||||
|
||||
const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
const auto& fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
const auto deviceInfo = fancyZonesData.FindDeviceInfo(zoneWindow->UniqueId());
|
||||
if (!deviceInfo.has_value())
|
||||
if (!fancyZonesData.SerializeDeviceInfoToTmpFile(zoneWindow->UniqueId()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSONHelpers::DeviceInfoJSON deviceInfoJson{ zoneWindow->UniqueId(), *deviceInfo };
|
||||
fancyZonesData.SerializeDeviceInfoToTmpFile(deviceInfoJson, ZoneWindowUtils::GetActiveZoneSetTmpPath());
|
||||
|
||||
const std::wstring params =
|
||||
/*1*/ editorLocation + L" " +
|
||||
/*2*/ L"\"" + std::to_wstring(GetCurrentProcessId()) + L"\"";
|
||||
@@ -842,8 +838,8 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
||||
std::vector<std::wstring> ids{};
|
||||
if (VirtualDesktopUtils::GetVirtualDesktopIds(ids) && !ids.empty())
|
||||
{
|
||||
JSONHelpers::FancyZonesDataInstance().UpdatePrimaryDesktopData(ids[0]);
|
||||
JSONHelpers::FancyZonesDataInstance().RemoveDeletedDesktops(ids);
|
||||
FancyZonesDataInstance().UpdatePrimaryDesktopData(ids[0]);
|
||||
FancyZonesDataInstance().RemoveDeletedDesktops(ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -884,7 +880,7 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
|
||||
if (workArea)
|
||||
{
|
||||
m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea);
|
||||
JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData();
|
||||
FancyZonesDataInstance().SaveFancyZonesData();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1065,7 +1061,7 @@ void FancyZones::RegisterVirtualDesktopUpdates(std::vector<GUID>& ids) noexcept
|
||||
std::vector<std::wstring> active{};
|
||||
if (VirtualDesktopUtils::GetVirtualDesktopIds(active))
|
||||
{
|
||||
JSONHelpers::FancyZonesDataInstance().RemoveDeletedDesktops(active);
|
||||
FancyZonesDataInstance().RemoveDeletedDesktops(active);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,10 +1080,7 @@ bool FancyZones::IsSplashScreen(HWND window)
|
||||
void FancyZones::OnEditorExitEvent() noexcept
|
||||
{
|
||||
// Collect information about changes in zone layout after editor exited.
|
||||
JSONHelpers::FancyZonesDataInstance().ParseDeviceInfoFromTmpFile(ZoneWindowUtils::GetActiveZoneSetTmpPath());
|
||||
JSONHelpers::FancyZonesDataInstance().ParseDeletedCustomZoneSetsFromTmpFile(ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath());
|
||||
JSONHelpers::FancyZonesDataInstance().ParseCustomZoneSetFromTmpFile(ZoneWindowUtils::GetAppliedZoneSetTmpPath());
|
||||
JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData();
|
||||
FancyZonesDataInstance().ParseDataFromTmpFiles();
|
||||
|
||||
for (auto workArea : m_workAreaHandler.GetAllWorkAreas())
|
||||
{
|
||||
|
||||
604
src/modules/fancyzones/lib/FancyZonesData.cpp
Normal file
604
src/modules/fancyzones/lib/FancyZonesData.cpp
Normal file
@@ -0,0 +1,604 @@
|
||||
#include "pch.h"
|
||||
#include "FancyZonesData.h"
|
||||
#include "FancyZonesDataTypes.h"
|
||||
#include "JsonHelpers.h"
|
||||
#include "ZoneSet.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <common/common.h>
|
||||
#include <common/json.h>
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
// Non-localizable strings
|
||||
namespace NonLocalizable
|
||||
{
|
||||
const wchar_t FancyZonesStr[] = L"FancyZones";
|
||||
const wchar_t LayoutsStr[] = L"Layouts";
|
||||
const wchar_t NullStr[] = L"null";
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t* FANCY_ZONES_DATA_FILE = L"zones-settings.json";
|
||||
const wchar_t* FANCY_ZONES_APP_ZONE_HISTORY_FILE = L"app-zone-history.json";
|
||||
const wchar_t* DEFAULT_GUID = L"{00000000-0000-0000-0000-000000000000}";
|
||||
const wchar_t* REG_SETTINGS = L"Software\\SuperFancyZones";
|
||||
|
||||
const wchar_t ActiveZoneSetsTmpFileName[] = L"FancyZonesActiveZoneSets.json";
|
||||
const wchar_t AppliedZoneSetsTmpFileName[] = L"FancyZonesAppliedZoneSets.json";
|
||||
const wchar_t DeletedCustomZoneSetsTmpFileName[] = L"FancyZonesDeletedCustomZoneSets.json";
|
||||
|
||||
std::wstring ExtractVirtualDesktopId(const std::wstring& deviceId)
|
||||
{
|
||||
// Format: <device-id>_<resolution>_<virtual-desktop-id>
|
||||
return deviceId.substr(deviceId.rfind('_') + 1);
|
||||
}
|
||||
|
||||
const std::wstring& GetTempDirPath()
|
||||
{
|
||||
static std::wstring tmpDirPath;
|
||||
static std::once_flag flag;
|
||||
|
||||
std::call_once(flag, []() {
|
||||
wchar_t buffer[MAX_PATH];
|
||||
|
||||
auto charsWritten = GetTempPath(MAX_PATH, buffer);
|
||||
if (charsWritten > MAX_PATH || (charsWritten == 0))
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
tmpDirPath = std::wstring{ buffer };
|
||||
});
|
||||
|
||||
return tmpDirPath;
|
||||
}
|
||||
}
|
||||
|
||||
FancyZonesData& FancyZonesDataInstance()
|
||||
{
|
||||
static FancyZonesData instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
FancyZonesData::FancyZonesData()
|
||||
{
|
||||
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::FancyZonesStr);
|
||||
zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(FANCY_ZONES_DATA_FILE);
|
||||
appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(FANCY_ZONES_APP_ZONE_HISTORY_FILE);
|
||||
|
||||
activeZoneSetTmpFileName = GetTempDirPath() + ActiveZoneSetsTmpFileName;
|
||||
appliedZoneSetTmpFileName = GetTempDirPath() + AppliedZoneSetsTmpFileName;
|
||||
deletedCustomZoneSetsTmpFileName = GetTempDirPath() + DeletedCustomZoneSetsTmpFileName;
|
||||
}
|
||||
|
||||
std::optional<FancyZonesDataTypes::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<FancyZonesDataTypes::CustomZoneSetData> FancyZonesData::FindCustomZoneSet(const std::wstring& guid) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = customZoneSetsMap.find(guid);
|
||||
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] = FancyZonesDataTypes::DeviceInfoData{ FancyZonesDataTypes::ZoneSetData{ NonLocalizable::NullStr, FancyZonesDataTypes::ZoneSetLayoutType::Blank } };
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::CloneDeviceInfo(const std::wstring& source, const std::wstring& destination)
|
||||
{
|
||||
if (source == destination)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::scoped_lock lock{ dataLock };
|
||||
|
||||
// The source virtual desktop is deleted, simply ignore it.
|
||||
if (!deviceInfoMap.contains(source))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone information from source device if destination device is uninitialized (Blank).
|
||||
auto& destInfo = deviceInfoMap[destination];
|
||||
if (destInfo.activeZoneSet.type == FancyZonesDataTypes::ZoneSetLayoutType::Blank)
|
||||
{
|
||||
destInfo = deviceInfoMap[source];
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::UpdatePrimaryDesktopData(const std::wstring& desktopId)
|
||||
{
|
||||
// Explorer persists current virtual desktop identifier to registry on a per session basis,
|
||||
// but only after first virtual desktop switch happens. If the user hasn't switched virtual
|
||||
// desktops in this session value in registry will be empty and we will use default GUID in
|
||||
// that case (00000000-0000-0000-0000-000000000000).
|
||||
// This method will go through all our persisted data with default GUID and update it with
|
||||
// valid one.
|
||||
auto replaceDesktopId = [&desktopId](const std::wstring& deviceId) {
|
||||
return deviceId.substr(0, deviceId.rfind('_') + 1) + desktopId;
|
||||
};
|
||||
std::scoped_lock lock{ dataLock };
|
||||
for (auto& [path, perDesktopData] : appZoneHistoryMap)
|
||||
{
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (ExtractVirtualDesktopId(data.deviceId) == DEFAULT_GUID)
|
||||
{
|
||||
data.deviceId = replaceDesktopId(data.deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<std::wstring> toReplace{};
|
||||
for (const auto& [id, data] : deviceInfoMap)
|
||||
{
|
||||
if (ExtractVirtualDesktopId(id) == DEFAULT_GUID)
|
||||
{
|
||||
toReplace.push_back(id);
|
||||
}
|
||||
}
|
||||
for (const auto& id : toReplace)
|
||||
{
|
||||
auto mapEntry = deviceInfoMap.extract(id);
|
||||
mapEntry.key() = replaceDesktopId(id);
|
||||
deviceInfoMap.insert(std::move(mapEntry));
|
||||
}
|
||||
SaveFancyZonesData();
|
||||
}
|
||||
|
||||
void FancyZonesData::RemoveDeletedDesktops(const std::vector<std::wstring>& activeDesktops)
|
||||
{
|
||||
std::unordered_set<std::wstring> active(std::begin(activeDesktops), std::end(activeDesktops));
|
||||
std::scoped_lock lock{ dataLock };
|
||||
for (auto it = std::begin(deviceInfoMap); it != std::end(deviceInfoMap);)
|
||||
{
|
||||
std::wstring desktopId = ExtractVirtualDesktopId(it->first);
|
||||
auto foundId = active.find(desktopId);
|
||||
if (foundId == std::end(active))
|
||||
{
|
||||
RemoveDesktopAppZoneHistory(desktopId);
|
||||
it = deviceInfoMap.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
SaveFancyZonesData();
|
||||
}
|
||||
|
||||
bool FancyZonesData::IsAnotherWindowOfApplicationInstanceZoned(HWND window, const std::wstring_view& deviceId) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto processPath = get_process_path(window);
|
||||
if (!processPath.empty())
|
||||
{
|
||||
auto history = appZoneHistoryMap.find(processPath);
|
||||
if (history != std::end(appZoneHistoryMap))
|
||||
{
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
|
||||
auto processIdIt = data.processIdToHandleMap.find(processId);
|
||||
|
||||
if (processIdIt == std::end(data.processIdToHandleMap))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (processIdIt->second != window && IsWindow(processIdIt->second))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FancyZonesData::UpdateProcessIdToHandleMap(HWND window, const std::wstring_view& deviceId)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto processPath = get_process_path(window);
|
||||
if (!processPath.empty())
|
||||
{
|
||||
auto history = appZoneHistoryMap.find(processPath);
|
||||
if (history != std::end(appZoneHistoryMap))
|
||||
{
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
data.processIdToHandleMap[processId] = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> FancyZonesData::GetAppLastZoneIndexSet(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())
|
||||
{
|
||||
auto history = appZoneHistoryMap.find(processPath);
|
||||
if (history != std::end(appZoneHistoryMap))
|
||||
{
|
||||
const auto& perDesktopData = history->second;
|
||||
for (const auto& data : perDesktopData)
|
||||
{
|
||||
if (data.zoneSetUuid == zoneSetId && data.deviceId == deviceId)
|
||||
{
|
||||
return data.zoneIndexSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
auto history = appZoneHistoryMap.find(processPath);
|
||||
if (history != std::end(appZoneHistoryMap))
|
||||
{
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto data = std::begin(perDesktopData); data != std::end(perDesktopData);)
|
||||
{
|
||||
if (data->deviceId == deviceId && data->zoneSetUuid == zoneSetId)
|
||||
{
|
||||
if (!IsAnotherWindowOfApplicationInstanceZoned(window, deviceId))
|
||||
{
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
|
||||
data->processIdToHandleMap.erase(processId);
|
||||
}
|
||||
|
||||
// if there is another instance of same application placed in the same zone don't erase history
|
||||
size_t windowZoneStamp = reinterpret_cast<size_t>(::GetProp(window, MULTI_ZONE_STAMP));
|
||||
for (auto placedWindow : data->processIdToHandleMap)
|
||||
{
|
||||
size_t placedWindowZoneStamp = reinterpret_cast<size_t>(::GetProp(placedWindow.second, MULTI_ZONE_STAMP));
|
||||
if (IsWindow(placedWindow.second) && (windowZoneStamp == placedWindowZoneStamp))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
data = perDesktopData.erase(data);
|
||||
if (perDesktopData.empty())
|
||||
{
|
||||
appZoneHistoryMap.erase(processPath);
|
||||
}
|
||||
SaveFancyZonesData();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FancyZonesData::SetAppLastZones(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, const std::vector<int>& zoneIndexSet)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
|
||||
if (IsAnotherWindowOfApplicationInstanceZoned(window, deviceId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto processPath = get_process_path(window);
|
||||
if (processPath.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(window, &processId);
|
||||
|
||||
auto history = appZoneHistoryMap.find(processPath);
|
||||
if (history != std::end(appZoneHistoryMap))
|
||||
{
|
||||
auto& perDesktopData = history->second;
|
||||
for (auto& data : perDesktopData)
|
||||
{
|
||||
if (data.deviceId == deviceId)
|
||||
{
|
||||
// application already has history on this work area, update it with new window position
|
||||
data.processIdToHandleMap[processId] = window;
|
||||
data.zoneSetUuid = zoneSetId;
|
||||
data.zoneIndexSet = zoneIndexSet;
|
||||
SaveFancyZonesData();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<DWORD, HWND> processIdToHandleMap{};
|
||||
processIdToHandleMap[processId] = window;
|
||||
FancyZonesDataTypes::AppZoneHistoryData data{ .processIdToHandleMap = processIdToHandleMap,
|
||||
.zoneSetUuid = zoneSetId,
|
||||
.deviceId = deviceId,
|
||||
.zoneIndexSet = zoneIndexSet };
|
||||
|
||||
if (appZoneHistoryMap.contains(processPath))
|
||||
{
|
||||
// application already has history but on other desktop, add with new desktop info
|
||||
appZoneHistoryMap[processPath].push_back(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// new application, create entry in app zone history map
|
||||
appZoneHistoryMap[processPath] = std::vector<FancyZonesDataTypes::AppZoneHistoryData>{ data };
|
||||
}
|
||||
|
||||
SaveFancyZonesData();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FancyZonesData::SetActiveZoneSet(const std::wstring& deviceId, const FancyZonesDataTypes::ZoneSetData& data)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = deviceInfoMap.find(deviceId);
|
||||
if (it != deviceInfoMap.end())
|
||||
{
|
||||
it->second.activeZoneSet = data;
|
||||
}
|
||||
}
|
||||
|
||||
bool FancyZonesData::SerializeDeviceInfoToTmpFile(const std::wstring& uniqueId) const
|
||||
{
|
||||
const auto deviceInfo = FindDeviceInfo(uniqueId);
|
||||
if (!deviceInfo.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSONHelpers::DeviceInfoJSON deviceInfoJson{ uniqueId, *deviceInfo };
|
||||
JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoJson, activeZoneSetTmpFileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FancyZonesData::ParseDataFromTmpFiles()
|
||||
{
|
||||
ParseDeviceInfoFromTmpFile(activeZoneSetTmpFileName);
|
||||
ParseDeletedCustomZoneSetsFromTmpFile(deletedCustomZoneSetsTmpFileName);
|
||||
ParseCustomZoneSetFromTmpFile(appliedZoneSetTmpFileName);
|
||||
SaveFancyZonesData();
|
||||
}
|
||||
|
||||
void FancyZonesData::ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
const auto& deviceInfo = JSONHelpers::ParseDeviceInfoFromTmpFile(tmpFilePath);
|
||||
|
||||
if (deviceInfo)
|
||||
{
|
||||
deviceInfoMap[deviceInfo->deviceId] = std::move(deviceInfo->data);
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
const auto& customZoneSet = JSONHelpers::ParseCustomZoneSetFromTmpFile(tmpFilePath);
|
||||
|
||||
if (customZoneSet)
|
||||
{
|
||||
customZoneSetsMap[customZoneSet->uuid] = std::move(customZoneSet->data);
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath)
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
const auto& deletedCustomZoneSets = JSONHelpers::ParseDeletedCustomZoneSetsFromTmpFile(tmpFilePath);
|
||||
for (const auto& zoneSet : deletedCustomZoneSets)
|
||||
{
|
||||
customZoneSetsMap.erase(zoneSet);
|
||||
}
|
||||
}
|
||||
|
||||
json::JsonObject FancyZonesData::GetPersistFancyZonesJSON()
|
||||
{
|
||||
return JSONHelpers::GetPersistFancyZonesJSON(zonesSettingsFileName, appZoneHistoryFileName);
|
||||
}
|
||||
|
||||
void FancyZonesData::LoadFancyZonesData()
|
||||
{
|
||||
if (!std::filesystem::exists(zonesSettingsFileName))
|
||||
{
|
||||
MigrateCustomZoneSetsFromRegistry();
|
||||
SaveFancyZonesData();
|
||||
}
|
||||
else
|
||||
{
|
||||
json::JsonObject fancyZonesDataJSON = GetPersistFancyZonesJSON();
|
||||
|
||||
appZoneHistoryMap = JSONHelpers::ParseAppZoneHistory(fancyZonesDataJSON);
|
||||
deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON);
|
||||
customZoneSetsMap = JSONHelpers::ParseCustomZoneSets(fancyZonesDataJSON);
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::SaveFancyZonesData() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
JSONHelpers::SaveFancyZonesData(zonesSettingsFileName,
|
||||
appZoneHistoryFileName,
|
||||
deviceInfoMap,
|
||||
customZoneSetsMap,
|
||||
appZoneHistoryMap);
|
||||
}
|
||||
|
||||
void FancyZonesData::MigrateCustomZoneSetsFromRegistry()
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
wchar_t key[256];
|
||||
StringCchPrintf(key, ARRAYSIZE(key), L"%s\\%s", REG_SETTINGS, NonLocalizable::LayoutsStr);
|
||||
HKEY hkey;
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS)
|
||||
{
|
||||
BYTE data[256];
|
||||
DWORD dataSize = ARRAYSIZE(data);
|
||||
wchar_t value[256]{};
|
||||
DWORD valueLength = ARRAYSIZE(value);
|
||||
DWORD i = 0;
|
||||
while (RegEnumValueW(hkey, i++, value, &valueLength, nullptr, nullptr, reinterpret_cast<BYTE*>(&data), &dataSize) == ERROR_SUCCESS)
|
||||
{
|
||||
FancyZonesDataTypes::CustomZoneSetData zoneSetData;
|
||||
zoneSetData.name = std::wstring{ value };
|
||||
zoneSetData.type = static_cast<FancyZonesDataTypes::CustomLayoutType>(data[2]);
|
||||
|
||||
GUID guid;
|
||||
auto result = CoCreateGuid(&guid);
|
||||
if (result != S_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
wil::unique_cotaskmem_string guidString;
|
||||
if (!SUCCEEDED(StringFromCLSID(guid, &guidString)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::wstring uuid = guidString.get();
|
||||
|
||||
switch (zoneSetData.type)
|
||||
{
|
||||
case FancyZonesDataTypes::CustomLayoutType::Grid:
|
||||
{
|
||||
// Visit https://github.com/microsoft/PowerToys/blob/v0.14.0/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs#L183
|
||||
// To see how custom Grid layout was packed in registry
|
||||
int j = 5;
|
||||
FancyZonesDataTypes::GridLayoutInfo zoneSetInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = data[j++], .columns = data[j++] });
|
||||
|
||||
for (int row = 0; row < zoneSetInfo.rows(); row++, j += 2)
|
||||
{
|
||||
zoneSetInfo.rowsPercents()[row] = data[j] * 256 + data[j + 1];
|
||||
}
|
||||
|
||||
for (int col = 0; col < zoneSetInfo.columns(); col++, j += 2)
|
||||
{
|
||||
zoneSetInfo.columnsPercents()[col] = data[j] * 256 + data[j + 1];
|
||||
}
|
||||
|
||||
for (int row = 0; row < zoneSetInfo.rows(); row++)
|
||||
{
|
||||
for (int col = 0; col < zoneSetInfo.columns(); col++)
|
||||
{
|
||||
zoneSetInfo.cellChildMap()[row][col] = data[j++];
|
||||
}
|
||||
}
|
||||
zoneSetData.info = zoneSetInfo;
|
||||
break;
|
||||
}
|
||||
case FancyZonesDataTypes::CustomLayoutType::Canvas:
|
||||
{
|
||||
// Visit https://github.com/microsoft/PowerToys/blob/v0.14.0/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs#L128
|
||||
// To see how custom Canvas layout was packed in registry
|
||||
int j = 5;
|
||||
FancyZonesDataTypes::CanvasLayoutInfo info;
|
||||
info.lastWorkAreaWidth = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
info.lastWorkAreaHeight = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
|
||||
int count = data[j++];
|
||||
info.zones.reserve(count);
|
||||
while (count-- > 0)
|
||||
{
|
||||
int x = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
int y = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
int width = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
int height = data[j] * 256 + data[j + 1];
|
||||
j += 2;
|
||||
info.zones.push_back(FancyZonesDataTypes::CanvasLayoutInfo::Rect{
|
||||
x, y, width, height });
|
||||
}
|
||||
zoneSetData.info = info;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
customZoneSetsMap[uuid] = zoneSetData;
|
||||
|
||||
valueLength = ARRAYSIZE(value);
|
||||
dataSize = ARRAYSIZE(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::RemoveDesktopAppZoneHistory(const std::wstring& desktopId)
|
||||
{
|
||||
for (auto it = std::begin(appZoneHistoryMap); it != std::end(appZoneHistoryMap);)
|
||||
{
|
||||
auto& perDesktopData = it->second;
|
||||
for (auto desktopIt = std::begin(perDesktopData); desktopIt != std::end(perDesktopData);)
|
||||
{
|
||||
if (ExtractVirtualDesktopId(desktopIt->deviceId) == desktopId)
|
||||
{
|
||||
desktopIt = perDesktopData.erase(desktopIt);
|
||||
}
|
||||
else
|
||||
{
|
||||
++desktopIt;
|
||||
}
|
||||
}
|
||||
|
||||
if (perDesktopData.empty())
|
||||
{
|
||||
it = appZoneHistoryMap.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
137
src/modules/fancyzones/lib/FancyZonesData.h
Normal file
137
src/modules/fancyzones/lib/FancyZonesData.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include "JsonHelpers.h"
|
||||
|
||||
#include <common/settings_helpers.h>
|
||||
#include <common/json.h>
|
||||
#include <mutex>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <winnt.h>
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
{
|
||||
struct ZoneSetData;
|
||||
struct DeviceInfoData;
|
||||
struct CustomZoneSetData;
|
||||
struct AppZoneHistoryData;
|
||||
}
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
class FancyZonesDataUnitTests;
|
||||
class FancyZonesIFancyZonesCallbackUnitTests;
|
||||
class ZoneSetCalculateZonesUnitTests;
|
||||
class ZoneWindowUnitTests;
|
||||
}
|
||||
#endif
|
||||
|
||||
class FancyZonesData
|
||||
{
|
||||
public:
|
||||
FancyZonesData();
|
||||
|
||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FindDeviceInfo(const std::wstring& zoneWindowId) const;
|
||||
|
||||
std::optional<FancyZonesDataTypes::CustomZoneSetData> FindCustomZoneSet(const std::wstring& guid) const;
|
||||
|
||||
inline const std::unordered_map<std::wstring, FancyZonesDataTypes::DeviceInfoData>& GetDeviceInfoMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return deviceInfoMap;
|
||||
}
|
||||
|
||||
inline const std::unordered_map<std::wstring, FancyZonesDataTypes::CustomZoneSetData>& GetCustomZoneSetsMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return customZoneSetsMap;
|
||||
}
|
||||
|
||||
inline const std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>>& GetAppZoneHistoryMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return appZoneHistoryMap;
|
||||
}
|
||||
|
||||
void AddDevice(const std::wstring& deviceId);
|
||||
void CloneDeviceInfo(const std::wstring& source, const std::wstring& destination);
|
||||
void UpdatePrimaryDesktopData(const std::wstring& desktopId);
|
||||
void RemoveDeletedDesktops(const std::vector<std::wstring>& activeDesktops);
|
||||
|
||||
bool IsAnotherWindowOfApplicationInstanceZoned(HWND window, const std::wstring_view& deviceId) const;
|
||||
void UpdateProcessIdToHandleMap(HWND window, const std::wstring_view& deviceId);
|
||||
std::vector<int> GetAppLastZoneIndexSet(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const;
|
||||
bool RemoveAppLastZone(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId);
|
||||
bool SetAppLastZones(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, const std::vector<int>& zoneIndexSet);
|
||||
|
||||
void SetActiveZoneSet(const std::wstring& deviceId, const FancyZonesDataTypes::ZoneSetData& zoneSet);
|
||||
|
||||
bool SerializeDeviceInfoToTmpFile(const std::wstring& uniqueId) const;
|
||||
void ParseDataFromTmpFiles();
|
||||
|
||||
json::JsonObject GetPersistFancyZonesJSON();
|
||||
|
||||
void LoadFancyZonesData();
|
||||
void SaveFancyZonesData() const;
|
||||
|
||||
private:
|
||||
#if defined(UNIT_TESTS)
|
||||
friend class FancyZonesUnitTests::FancyZonesDataUnitTests;
|
||||
friend class FancyZonesUnitTests::FancyZonesIFancyZonesCallbackUnitTests;
|
||||
friend class FancyZonesUnitTests::ZoneWindowUnitTests;
|
||||
friend class FancyZonesUnitTests::ZoneSetCalculateZonesUnitTests;
|
||||
|
||||
inline void SetDeviceInfo(const std::wstring& deviceId, FancyZonesDataTypes::DeviceInfoData data)
|
||||
{
|
||||
deviceInfoMap[deviceId] = data;
|
||||
}
|
||||
|
||||
inline bool ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON)
|
||||
{
|
||||
deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON);
|
||||
return !deviceInfoMap.empty();
|
||||
}
|
||||
|
||||
inline void clear_data()
|
||||
{
|
||||
appZoneHistoryMap.clear();
|
||||
deviceInfoMap.clear();
|
||||
customZoneSetsMap.clear();
|
||||
}
|
||||
|
||||
inline void SetSettingsModulePath(std::wstring_view moduleName)
|
||||
{
|
||||
std::wstring result = PTSettingsHelper::get_module_save_folder_location(moduleName);
|
||||
zonesSettingsFileName = result + L"\\" + std::wstring(L"zones-settings.json");
|
||||
appZoneHistoryFileName = result + L"\\" + std::wstring(L"app-zone-history.json");
|
||||
}
|
||||
#endif
|
||||
void ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath);
|
||||
void ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath);
|
||||
void ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath);
|
||||
|
||||
void MigrateCustomZoneSetsFromRegistry();
|
||||
void RemoveDesktopAppZoneHistory(const std::wstring& desktopId);
|
||||
|
||||
// Maps app path to app's zone history data
|
||||
std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>> appZoneHistoryMap{};
|
||||
// Maps device unique ID to device data
|
||||
std::unordered_map<std::wstring, FancyZonesDataTypes::DeviceInfoData> deviceInfoMap{};
|
||||
// Maps custom zoneset UUID to it's data
|
||||
std::unordered_map<std::wstring, FancyZonesDataTypes::CustomZoneSetData> customZoneSetsMap{};
|
||||
|
||||
std::wstring zonesSettingsFileName;
|
||||
std::wstring appZoneHistoryFileName;
|
||||
|
||||
std::wstring activeZoneSetTmpFileName;
|
||||
std::wstring appliedZoneSetTmpFileName;
|
||||
std::wstring deletedCustomZoneSetsTmpFileName;
|
||||
|
||||
mutable std::recursive_mutex dataLock;
|
||||
};
|
||||
|
||||
FancyZonesData& FancyZonesDataInstance();
|
||||
115
src/modules/fancyzones/lib/FancyZonesDataTypes.cpp
Normal file
115
src/modules/fancyzones/lib/FancyZonesDataTypes.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include "pch.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "FancyZonesDataTypes.h"
|
||||
|
||||
// Non-Localizable strings
|
||||
namespace NonLocalizable
|
||||
{
|
||||
const wchar_t BlankStr[] = L"blank";
|
||||
const wchar_t ColumnsStr[] = L"columns";
|
||||
const wchar_t CustomStr[] = L"custom";
|
||||
const wchar_t FocusStr[] = L"focus";
|
||||
const wchar_t GridStr[] = L"grid";
|
||||
const wchar_t PriorityGridStr[] = L"priority-grid";
|
||||
const wchar_t RowsStr[] = L"rows";
|
||||
const wchar_t TypeToStringErrorStr[] = L"TypeToString_ERROR";
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// From Settings.cs
|
||||
constexpr int c_focusModelId = 0xFFFF;
|
||||
constexpr int c_rowsModelId = 0xFFFE;
|
||||
constexpr int c_columnsModelId = 0xFFFD;
|
||||
constexpr int c_gridModelId = 0xFFFC;
|
||||
constexpr int c_priorityGridModelId = 0xFFFB;
|
||||
constexpr int c_blankCustomModelId = 0xFFFA;
|
||||
}
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
{
|
||||
std::wstring TypeToString(ZoneSetLayoutType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ZoneSetLayoutType::Blank:
|
||||
return NonLocalizable::BlankStr;
|
||||
case ZoneSetLayoutType::Focus:
|
||||
return NonLocalizable::FocusStr;
|
||||
case ZoneSetLayoutType::Columns:
|
||||
return NonLocalizable::ColumnsStr;
|
||||
case ZoneSetLayoutType::Rows:
|
||||
return NonLocalizable::RowsStr;
|
||||
case ZoneSetLayoutType::Grid:
|
||||
return NonLocalizable::GridStr;
|
||||
case ZoneSetLayoutType::PriorityGrid:
|
||||
return NonLocalizable::PriorityGridStr;
|
||||
case ZoneSetLayoutType::Custom:
|
||||
return NonLocalizable::CustomStr;
|
||||
default:
|
||||
return NonLocalizable::TypeToStringErrorStr;
|
||||
}
|
||||
}
|
||||
|
||||
ZoneSetLayoutType TypeFromString(const std::wstring& typeStr)
|
||||
{
|
||||
if (typeStr == NonLocalizable::FocusStr)
|
||||
{
|
||||
return ZoneSetLayoutType::Focus;
|
||||
}
|
||||
else if (typeStr == NonLocalizable::ColumnsStr)
|
||||
{
|
||||
return ZoneSetLayoutType::Columns;
|
||||
}
|
||||
else if (typeStr == NonLocalizable::RowsStr)
|
||||
{
|
||||
return ZoneSetLayoutType::Rows;
|
||||
}
|
||||
else if (typeStr == NonLocalizable::GridStr)
|
||||
{
|
||||
return ZoneSetLayoutType::Grid;
|
||||
}
|
||||
else if (typeStr == NonLocalizable::PriorityGridStr)
|
||||
{
|
||||
return ZoneSetLayoutType::PriorityGrid;
|
||||
}
|
||||
else if (typeStr == NonLocalizable::CustomStr)
|
||||
{
|
||||
return ZoneSetLayoutType::Custom;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ZoneSetLayoutType::Blank;
|
||||
}
|
||||
}
|
||||
|
||||
GridLayoutInfo::GridLayoutInfo(const Minimal& info) :
|
||||
m_rows(info.rows),
|
||||
m_columns(info.columns)
|
||||
{
|
||||
m_rowsPercents.resize(m_rows, 0);
|
||||
m_columnsPercents.resize(m_columns, 0);
|
||||
m_cellChildMap.resize(m_rows, {});
|
||||
for (auto& cellRow : m_cellChildMap)
|
||||
{
|
||||
cellRow.resize(m_columns, 0);
|
||||
}
|
||||
}
|
||||
|
||||
GridLayoutInfo::GridLayoutInfo(const Full& info) :
|
||||
m_rows(info.rows),
|
||||
m_columns(info.columns),
|
||||
m_rowsPercents(info.rowsPercents),
|
||||
m_columnsPercents(info.columnsPercents),
|
||||
m_cellChildMap(info.cellChildMap)
|
||||
{
|
||||
m_rowsPercents.resize(m_rows, 0);
|
||||
m_columnsPercents.resize(m_columns, 0);
|
||||
m_cellChildMap.resize(m_rows, {});
|
||||
for (auto& cellRow : m_cellChildMap)
|
||||
{
|
||||
cellRow.resize(m_columns, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
118
src/modules/fancyzones/lib/FancyZonesDataTypes.h
Normal file
118
src/modules/fancyzones/lib/FancyZonesDataTypes.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/json.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
{
|
||||
enum class ZoneSetLayoutType : int
|
||||
{
|
||||
Blank = -1,
|
||||
Focus,
|
||||
Columns,
|
||||
Rows,
|
||||
Grid,
|
||||
PriorityGrid,
|
||||
Custom
|
||||
};
|
||||
|
||||
std::wstring TypeToString(ZoneSetLayoutType type);
|
||||
ZoneSetLayoutType TypeFromString(const std::wstring& typeStr);
|
||||
|
||||
enum class CustomLayoutType : int
|
||||
{
|
||||
Grid = 0,
|
||||
Canvas
|
||||
};
|
||||
|
||||
struct CanvasLayoutInfo
|
||||
{
|
||||
int lastWorkAreaWidth;
|
||||
int lastWorkAreaHeight;
|
||||
|
||||
struct Rect
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
std::vector<CanvasLayoutInfo::Rect> zones;
|
||||
};
|
||||
|
||||
struct GridLayoutInfo
|
||||
{
|
||||
struct Minimal
|
||||
{
|
||||
int rows;
|
||||
int columns;
|
||||
};
|
||||
|
||||
struct Full
|
||||
{
|
||||
int rows;
|
||||
int columns;
|
||||
const std::vector<int>& rowsPercents;
|
||||
const std::vector<int>& columnsPercents;
|
||||
const std::vector<std::vector<int>>& cellChildMap;
|
||||
};
|
||||
|
||||
GridLayoutInfo(const Minimal& info);
|
||||
GridLayoutInfo(const Full& info);
|
||||
~GridLayoutInfo() = default;
|
||||
|
||||
inline std::vector<int>& rowsPercents() { return m_rowsPercents; };
|
||||
inline std::vector<int>& columnsPercents() { return m_columnsPercents; };
|
||||
inline std::vector<std::vector<int>>& cellChildMap() { return m_cellChildMap; };
|
||||
|
||||
inline int rows() const { return m_rows; }
|
||||
inline int columns() const { return m_columns; }
|
||||
|
||||
inline const std::vector<int>& rowsPercents() const { return m_rowsPercents; };
|
||||
inline const std::vector<int>& columnsPercents() const { return m_columnsPercents; };
|
||||
inline const std::vector<std::vector<int>>& cellChildMap() const { return m_cellChildMap; };
|
||||
|
||||
int m_rows;
|
||||
int m_columns;
|
||||
std::vector<int> m_rowsPercents;
|
||||
std::vector<int> m_columnsPercents;
|
||||
std::vector<std::vector<int>> m_cellChildMap;
|
||||
};
|
||||
|
||||
struct CustomZoneSetData
|
||||
{
|
||||
std::wstring name;
|
||||
CustomLayoutType type;
|
||||
std::variant<CanvasLayoutInfo, GridLayoutInfo> info;
|
||||
};
|
||||
|
||||
struct ZoneSetData
|
||||
{
|
||||
std::wstring uuid;
|
||||
ZoneSetLayoutType type;
|
||||
};
|
||||
|
||||
struct AppZoneHistoryData
|
||||
{
|
||||
std::unordered_map<DWORD, HWND> processIdToHandleMap; // Maps process id(DWORD) of application to zoned window handle(HWND)
|
||||
|
||||
std::wstring zoneSetUuid;
|
||||
std::wstring deviceId;
|
||||
std::vector<int> zoneIndexSet;
|
||||
};
|
||||
|
||||
struct DeviceInfoData
|
||||
{
|
||||
ZoneSetData activeZoneSet;
|
||||
bool showSpacing;
|
||||
int spacing;
|
||||
int zoneCount;
|
||||
};
|
||||
}
|
||||
@@ -99,8 +99,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="FancyZones.h" />
|
||||
<ClInclude Include="FancyZonesDataTypes.h" />
|
||||
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
|
||||
<ClInclude Include="GenericKeyHook.h" />
|
||||
<ClInclude Include="FancyZonesData.h" />
|
||||
<ClInclude Include="JsonHelpers.h" />
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -117,8 +119,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FancyZones.cpp" />
|
||||
<ClCompile Include="FancyZonesDataTypes.cpp" />
|
||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
|
||||
<ClCompile Include="GenericKeyHook.cpp" />
|
||||
<ClCompile Include="FancyZonesData.cpp" />
|
||||
<ClCompile Include="JsonHelpers.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
||||
@@ -42,9 +42,6 @@
|
||||
<ClInclude Include="trace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonHelpers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VirtualDesktopUtils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -63,6 +60,15 @@
|
||||
<ClInclude Include="GenericKeyHook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FancyZonesData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonHelpers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FancyZonesDataTypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
@@ -86,9 +92,6 @@
|
||||
<ClCompile Include="trace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonHelpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -110,6 +113,15 @@
|
||||
<ClCompile Include="GenericKeyHook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonHelpers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesDataTypes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="fancyzones.rc">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,278 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/settings_helpers.h>
|
||||
#include "FancyZonesDataTypes.h"
|
||||
|
||||
#include <common/json.h>
|
||||
#include <mutex>
|
||||
|
||||
#include <string>
|
||||
#include <strsafe.h>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <winnt.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace JSONHelpers
|
||||
{
|
||||
constexpr int MAX_ZONE_COUNT = 50;
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
bool isValidGuid(const std::wstring& str);
|
||||
bool isValidDeviceId(const std::wstring& str);
|
||||
#endif
|
||||
|
||||
enum class ZoneSetLayoutType : int
|
||||
namespace CanvasLayoutInfoJSON
|
||||
{
|
||||
Blank = -1,
|
||||
Focus,
|
||||
Columns,
|
||||
Rows,
|
||||
Grid,
|
||||
PriorityGrid,
|
||||
Custom
|
||||
};
|
||||
json::JsonObject ToJson(const FancyZonesDataTypes::CanvasLayoutInfo& canvasInfo);
|
||||
std::optional<FancyZonesDataTypes::CanvasLayoutInfo> FromJson(const json::JsonObject& infoJson);
|
||||
}
|
||||
|
||||
enum class CustomLayoutType : int
|
||||
namespace GridLayoutInfoJSON
|
||||
{
|
||||
Grid = 0,
|
||||
Canvas
|
||||
};
|
||||
|
||||
std::wstring TypeToString(ZoneSetLayoutType type);
|
||||
ZoneSetLayoutType TypeFromString(const std::wstring& typeStr);
|
||||
|
||||
ZoneSetLayoutType TypeFromLayoutId(int layoutID);
|
||||
|
||||
struct CanvasLayoutInfo
|
||||
{
|
||||
int lastWorkAreaWidth;
|
||||
int lastWorkAreaHeight;
|
||||
|
||||
struct Rect
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
std::vector<CanvasLayoutInfo::Rect> zones;
|
||||
|
||||
static json::JsonObject ToJson(const CanvasLayoutInfo& canvasInfo);
|
||||
static std::optional<CanvasLayoutInfo> FromJson(const json::JsonObject& infoJson);
|
||||
};
|
||||
|
||||
class GridLayoutInfo
|
||||
{
|
||||
public:
|
||||
struct Minimal
|
||||
{
|
||||
int rows;
|
||||
int columns;
|
||||
};
|
||||
|
||||
struct Full
|
||||
{
|
||||
int rows;
|
||||
int columns;
|
||||
const std::vector<int>& rowsPercents;
|
||||
const std::vector<int>& columnsPercents;
|
||||
const std::vector<std::vector<int>>& cellChildMap;
|
||||
};
|
||||
|
||||
GridLayoutInfo(const Minimal& info);
|
||||
GridLayoutInfo(const Full& info);
|
||||
~GridLayoutInfo() = default;
|
||||
|
||||
static json::JsonObject ToJson(const GridLayoutInfo& gridInfo);
|
||||
static std::optional<GridLayoutInfo> FromJson(const json::JsonObject& infoJson);
|
||||
|
||||
inline std::vector<int>& rowsPercents() { return m_rowsPercents; };
|
||||
inline std::vector<int>& columnsPercents() { return m_columnsPercents; };
|
||||
inline std::vector<std::vector<int>>& cellChildMap() { return m_cellChildMap; };
|
||||
|
||||
inline int rows() const { return m_rows; }
|
||||
inline int columns() const { return m_columns; }
|
||||
|
||||
inline const std::vector<int>& rowsPercents() const { return m_rowsPercents; };
|
||||
inline const std::vector<int>& columnsPercents() const { return m_columnsPercents; };
|
||||
inline const std::vector<std::vector<int>>& cellChildMap() const { return m_cellChildMap; };
|
||||
|
||||
private:
|
||||
int m_rows;
|
||||
int m_columns;
|
||||
std::vector<int> m_rowsPercents;
|
||||
std::vector<int> m_columnsPercents;
|
||||
std::vector<std::vector<int>> m_cellChildMap;
|
||||
};
|
||||
|
||||
struct CustomZoneSetData
|
||||
{
|
||||
std::wstring name;
|
||||
CustomLayoutType type;
|
||||
std::variant<CanvasLayoutInfo, GridLayoutInfo> info;
|
||||
};
|
||||
json::JsonObject ToJson(const FancyZonesDataTypes::GridLayoutInfo& gridInfo);
|
||||
std::optional<FancyZonesDataTypes::GridLayoutInfo> FromJson(const json::JsonObject& infoJson);
|
||||
}
|
||||
|
||||
struct CustomZoneSetJSON
|
||||
{
|
||||
std::wstring uuid;
|
||||
CustomZoneSetData data;
|
||||
FancyZonesDataTypes::CustomZoneSetData data;
|
||||
|
||||
static json::JsonObject ToJson(const CustomZoneSetJSON& device);
|
||||
static std::optional<CustomZoneSetJSON> FromJson(const json::JsonObject& customZoneSet);
|
||||
};
|
||||
|
||||
// TODO(stefan): This needs to be moved to ZoneSet.h (probably)
|
||||
struct ZoneSetData
|
||||
namespace ZoneSetDataJSON
|
||||
{
|
||||
std::wstring uuid;
|
||||
ZoneSetLayoutType type;
|
||||
|
||||
static json::JsonObject ToJson(const ZoneSetData& zoneSet);
|
||||
static std::optional<ZoneSetData> FromJson(const json::JsonObject& zoneSet);
|
||||
};
|
||||
|
||||
struct AppZoneHistoryData
|
||||
{
|
||||
std::unordered_map<DWORD, HWND> processIdToHandleMap; // Maps process id(DWORD) of application to zoned window handle(HWND)
|
||||
|
||||
std::wstring zoneSetUuid;
|
||||
std::wstring deviceId;
|
||||
std::vector<int> zoneIndexSet;
|
||||
json::JsonObject ToJson(const FancyZonesDataTypes::ZoneSetData& zoneSet);
|
||||
std::optional<FancyZonesDataTypes::ZoneSetData> FromJson(const json::JsonObject& zoneSet);
|
||||
};
|
||||
|
||||
struct AppZoneHistoryJSON
|
||||
{
|
||||
std::wstring appPath;
|
||||
std::vector<AppZoneHistoryData> data;
|
||||
std::vector<FancyZonesDataTypes::AppZoneHistoryData> data;
|
||||
|
||||
static json::JsonObject ToJson(const AppZoneHistoryJSON& appZoneHistory);
|
||||
static std::optional<AppZoneHistoryJSON> FromJson(const json::JsonObject& zoneSet);
|
||||
};
|
||||
|
||||
struct DeviceInfoData
|
||||
{
|
||||
ZoneSetData activeZoneSet;
|
||||
bool showSpacing;
|
||||
int spacing;
|
||||
int zoneCount;
|
||||
};
|
||||
|
||||
struct DeviceInfoJSON
|
||||
{
|
||||
std::wstring deviceId;
|
||||
DeviceInfoData data;
|
||||
FancyZonesDataTypes::DeviceInfoData data;
|
||||
|
||||
static json::JsonObject ToJson(const DeviceInfoJSON& device);
|
||||
static std::optional<DeviceInfoJSON> FromJson(const json::JsonObject& device);
|
||||
};
|
||||
|
||||
class FancyZonesData
|
||||
{
|
||||
mutable std::recursive_mutex dataLock;
|
||||
using TAppZoneHistoryMap = std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>>;
|
||||
using TDeviceInfoMap = std::unordered_map<std::wstring, FancyZonesDataTypes::DeviceInfoData>;
|
||||
using TCustomZoneSetsMap = std::unordered_map<std::wstring, FancyZonesDataTypes::CustomZoneSetData>;
|
||||
|
||||
public:
|
||||
FancyZonesData();
|
||||
json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName);
|
||||
void SaveFancyZonesData(const std::wstring& zonesSettingsFileName,
|
||||
const std::wstring& appZoneHistoryFileName,
|
||||
const TDeviceInfoMap& deviceInfoMap,
|
||||
const TCustomZoneSetsMap& customZoneSetsMap,
|
||||
const TAppZoneHistoryMap& appZoneHistoryMap);
|
||||
|
||||
inline const std::wstring& GetPersistFancyZonesJSONPath() const
|
||||
{
|
||||
return jsonFilePath;
|
||||
}
|
||||
TAppZoneHistoryMap ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeAppZoneHistory(const TAppZoneHistoryMap& appZoneHistoryMap);
|
||||
|
||||
inline const std::wstring& GetPersistAppZoneHistoryFilePath() const
|
||||
{
|
||||
return appZoneHistoryFilePath;
|
||||
}
|
||||
TDeviceInfoMap ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeDeviceInfos(const TDeviceInfoMap& deviceInfoMap);
|
||||
|
||||
json::JsonObject GetPersistFancyZonesJSON();
|
||||
TCustomZoneSetsMap ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeCustomZoneSets(const TCustomZoneSetsMap& customZoneSetsMap);
|
||||
|
||||
std::optional<DeviceInfoData> FindDeviceInfo(const std::wstring& zoneWindowId) const;
|
||||
|
||||
std::optional<CustomZoneSetData> FindCustomZoneSet(const std::wstring& guid) const;
|
||||
|
||||
inline const std::unordered_map<std::wstring, DeviceInfoData>& GetDeviceInfoMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return deviceInfoMap;
|
||||
}
|
||||
|
||||
inline const std::unordered_map<std::wstring, CustomZoneSetData>& GetCustomZoneSetsMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return customZoneSetsMap;
|
||||
}
|
||||
|
||||
inline const std::unordered_map<std::wstring, std::vector<AppZoneHistoryData>>& GetAppZoneHistoryMap() const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
return appZoneHistoryMap;
|
||||
}
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
inline void clear_data()
|
||||
{
|
||||
appZoneHistoryMap.clear();
|
||||
deviceInfoMap.clear();
|
||||
customZoneSetsMap.clear();
|
||||
}
|
||||
|
||||
inline void SetDeviceInfo(const std::wstring& deviceId, DeviceInfoData data)
|
||||
{
|
||||
deviceInfoMap[deviceId] = data;
|
||||
}
|
||||
|
||||
inline void SetSettingsModulePath(std::wstring_view moduleName)
|
||||
{
|
||||
std::wstring result = PTSettingsHelper::get_module_save_folder_location(moduleName);
|
||||
jsonFilePath = result + L"\\" + std::wstring(L"zones-settings.json");
|
||||
appZoneHistoryFilePath = result + L"\\" + std::wstring(L"app-zone-history.json");
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool DeleteTmpFile(std::wstring_view tmpFilePath) const
|
||||
{
|
||||
return DeleteFileW(tmpFilePath.data());
|
||||
}
|
||||
|
||||
void AddDevice(const std::wstring& deviceId);
|
||||
void CloneDeviceInfo(const std::wstring& source, const std::wstring& destination);
|
||||
void UpdatePrimaryDesktopData(const std::wstring& desktopId);
|
||||
void RemoveDeletedDesktops(const std::vector<std::wstring>& activeDesktops);
|
||||
|
||||
bool IsAnotherWindowOfApplicationInstanceZoned(HWND window, const std::wstring_view& deviceId) const;
|
||||
void UpdateProcessIdToHandleMap(HWND window, const std::wstring_view& deviceId);
|
||||
std::vector<int> GetAppLastZoneIndexSet(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const;
|
||||
bool RemoveAppLastZone(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId);
|
||||
bool SetAppLastZones(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, const std::vector<int>& zoneIndexSet);
|
||||
|
||||
void SetActiveZoneSet(const std::wstring& deviceId, const ZoneSetData& zoneSet);
|
||||
|
||||
void SerializeDeviceInfoToTmpFile(const DeviceInfoJSON& deviceInfo, std::wstring_view tmpFilePath) const;
|
||||
|
||||
void ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath);
|
||||
bool ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath);
|
||||
bool ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath);
|
||||
|
||||
bool ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeAppZoneHistory() const;
|
||||
bool ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeDeviceInfos() const;
|
||||
bool ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON);
|
||||
json::JsonArray SerializeCustomZoneSets() const;
|
||||
|
||||
void LoadFancyZonesData();
|
||||
void SaveFancyZonesData() const;
|
||||
|
||||
private:
|
||||
void MigrateCustomZoneSetsFromRegistry();
|
||||
void RemoveDesktopAppZoneHistory(const std::wstring& desktopId);
|
||||
|
||||
std::unordered_map<std::wstring, std::vector<AppZoneHistoryData>> appZoneHistoryMap{};
|
||||
std::unordered_map<std::wstring, DeviceInfoData> deviceInfoMap{};
|
||||
std::unordered_map<std::wstring, CustomZoneSetData> customZoneSetsMap{};
|
||||
|
||||
std::wstring jsonFilePath;
|
||||
std::wstring appZoneHistoryFilePath;
|
||||
};
|
||||
|
||||
FancyZonesData& FancyZonesDataInstance();
|
||||
void SerializeDeviceInfoToTmpFile(const JSONHelpers::DeviceInfoJSON& deviceInfo, std::wstring_view tmpFilePath);
|
||||
std::optional<DeviceInfoJSON> ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath);
|
||||
std::optional<CustomZoneSetJSON> ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath);
|
||||
std::vector<std::wstring> ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "VirtualDesktopUtils.h"
|
||||
#include "lib/SecondaryMouseButtonsHook.h"
|
||||
#include "lib/GenericKeyHook.h"
|
||||
#include "lib/FancyZonesData.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
@@ -337,7 +338,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
||||
wil::unique_cotaskmem_string guidString;
|
||||
if (SUCCEEDED_LOG(StringFromCLSID(activeZoneSet->Id(), &guidString)))
|
||||
{
|
||||
JSONHelpers::FancyZonesDataInstance().RemoveAppLastZone(window, zoneWindowPtr->UniqueId(), guidString.get());
|
||||
FancyZonesDataInstance().RemoveAppLastZone(window, zoneWindowPtr->UniqueId(), guidString.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,17 @@
|
||||
#include "util.h"
|
||||
#include "lib/ZoneSet.h"
|
||||
#include "Settings.h"
|
||||
#include "FancyZonesData.h"
|
||||
#include "FancyZonesDataTypes.h"
|
||||
|
||||
#include <common/dpi_aware.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int C_MULTIPLIER = 10000;
|
||||
constexpr int MAX_ZONE_COUNT = 50;
|
||||
|
||||
/*
|
||||
struct GridLayoutInfo {
|
||||
@@ -20,81 +25,81 @@ namespace
|
||||
};
|
||||
*/
|
||||
|
||||
auto l = JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Minimal{ .rows = 1, .columns = 1 });
|
||||
auto l = FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = 1, .columns = 1 });
|
||||
// PriorityGrid layout is unique for zoneCount <= 11. For zoneCount > 11 PriorityGrid is same as Grid
|
||||
JSONHelpers::GridLayoutInfo predefinedPriorityGridLayouts[11] = {
|
||||
FancyZonesDataTypes::GridLayoutInfo predefinedPriorityGridLayouts[11] = {
|
||||
/* 1 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 1,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 10000 },
|
||||
.cellChildMap = { { 0 } } }),
|
||||
/* 2 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 2,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 6667, 3333 },
|
||||
.cellChildMap = { { 0, 1 } } }),
|
||||
/* 3 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 } } }),
|
||||
/* 4 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 } } }),
|
||||
/* 5 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 2,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 5000, 5000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 } } }),
|
||||
/* 6 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 0, 1, 3 }, { 4, 1, 5 } } }),
|
||||
/* 7 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 }, { 3, 1, 4 }, { 5, 1, 6 } } }),
|
||||
/* 8 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 2, 7 } } }),
|
||||
/* 9 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 2, 5 }, { 6, 1, 7, 8 } } }),
|
||||
/* 10 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
.columnsPercents = { 2500, 2500, 2500, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 1, 8, 9 } } }),
|
||||
/* 11 */
|
||||
JSONHelpers::GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{
|
||||
.rows = 3,
|
||||
.columns = 4,
|
||||
.rowsPercents = { 3333, 3334, 3333 },
|
||||
@@ -119,7 +124,7 @@ public:
|
||||
|
||||
IFACEMETHODIMP_(GUID)
|
||||
Id() noexcept { return m_config.Id; }
|
||||
IFACEMETHODIMP_(JSONHelpers::ZoneSetLayoutType)
|
||||
IFACEMETHODIMP_(FancyZonesDataTypes::ZoneSetLayoutType)
|
||||
LayoutType() noexcept { return m_config.LayoutType; }
|
||||
IFACEMETHODIMP AddZone(winrt::com_ptr<IZone> zone) noexcept;
|
||||
IFACEMETHODIMP_(std::vector<int>)
|
||||
@@ -143,11 +148,11 @@ public:
|
||||
|
||||
private:
|
||||
bool CalculateFocusLayout(Rect workArea, int zoneCount) noexcept;
|
||||
bool CalculateColumnsAndRowsLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateGridLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateColumnsAndRowsLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateGridLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateUniquePriorityGridLayout(Rect workArea, int zoneCount, int spacing) noexcept;
|
||||
bool CalculateCustomLayout(Rect workArea, int spacing) noexcept;
|
||||
bool CalculateGridZones(Rect workArea, JSONHelpers::GridLayoutInfo gridLayoutInfo, int spacing);
|
||||
bool CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing);
|
||||
void StampWindow(HWND window, size_t bitmask) noexcept;
|
||||
|
||||
std::vector<winrt::com_ptr<IZone>> m_zones;
|
||||
@@ -374,7 +379,7 @@ ZoneSet::CalculateZones(MONITORINFO monitorInfo, int zoneCount, int spacing) noe
|
||||
}
|
||||
|
||||
//invalid zoneCount, may cause division by zero
|
||||
if (zoneCount <= 0 && m_config.LayoutType != JSONHelpers::ZoneSetLayoutType::Custom)
|
||||
if (zoneCount <= 0 && m_config.LayoutType != FancyZonesDataTypes::ZoneSetLayoutType::Custom)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -382,18 +387,18 @@ ZoneSet::CalculateZones(MONITORINFO monitorInfo, int zoneCount, int spacing) noe
|
||||
bool success = true;
|
||||
switch (m_config.LayoutType)
|
||||
{
|
||||
case JSONHelpers::ZoneSetLayoutType::Focus:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Focus:
|
||||
success = CalculateFocusLayout(workArea, zoneCount);
|
||||
break;
|
||||
case JSONHelpers::ZoneSetLayoutType::Columns:
|
||||
case JSONHelpers::ZoneSetLayoutType::Rows:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Columns:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Rows:
|
||||
success = CalculateColumnsAndRowsLayout(workArea, m_config.LayoutType, zoneCount, spacing);
|
||||
break;
|
||||
case JSONHelpers::ZoneSetLayoutType::Grid:
|
||||
case JSONHelpers::ZoneSetLayoutType::PriorityGrid:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Grid:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid:
|
||||
success = CalculateGridLayout(workArea, m_config.LayoutType, zoneCount, spacing);
|
||||
break;
|
||||
case JSONHelpers::ZoneSetLayoutType::Custom:
|
||||
case FancyZonesDataTypes::ZoneSetLayoutType::Custom:
|
||||
success = CalculateCustomLayout(workArea, spacing);
|
||||
break;
|
||||
}
|
||||
@@ -445,14 +450,14 @@ bool ZoneSet::CalculateFocusLayout(Rect workArea, int zoneCount) noexcept
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
long totalWidth;
|
||||
long totalHeight;
|
||||
|
||||
if (type == JSONHelpers::ZoneSetLayoutType::Columns)
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
totalWidth = workArea.width() - (spacing * (zoneCount + 1));
|
||||
totalHeight = workArea.height() - (spacing * 2);
|
||||
@@ -472,7 +477,7 @@ bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, JSONHelpers::ZoneSetL
|
||||
// like this to make the sum of all zones' sizes exactly total{Width|Height}.
|
||||
for (int zone = 0; zone < zoneCount; zone++)
|
||||
{
|
||||
if (type == JSONHelpers::ZoneSetLayoutType::Columns)
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
right = left + (zone + 1) * totalWidth / zoneCount - zone * totalWidth / zoneCount;
|
||||
bottom = totalHeight + spacing;
|
||||
@@ -491,7 +496,7 @@ bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, JSONHelpers::ZoneSetL
|
||||
RECT focusZoneRect{ left, top, right, bottom };
|
||||
AddZone(MakeZone(focusZoneRect));
|
||||
|
||||
if (type == JSONHelpers::ZoneSetLayoutType::Columns)
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Columns)
|
||||
{
|
||||
left = right + spacing;
|
||||
}
|
||||
@@ -504,10 +509,10 @@ bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, JSONHelpers::ZoneSetL
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateGridLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
bool ZoneSet::CalculateGridLayout(Rect workArea, FancyZonesDataTypes::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept
|
||||
{
|
||||
const auto count = sizeof(predefinedPriorityGridLayouts) / sizeof(JSONHelpers::GridLayoutInfo);
|
||||
if (type == JSONHelpers::ZoneSetLayoutType::PriorityGrid && zoneCount < count)
|
||||
const auto count = sizeof(predefinedPriorityGridLayouts) / sizeof(FancyZonesDataTypes::GridLayoutInfo);
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::PriorityGrid && zoneCount < count)
|
||||
{
|
||||
return CalculateUniquePriorityGridLayout(workArea, zoneCount, spacing);
|
||||
}
|
||||
@@ -528,7 +533,7 @@ bool ZoneSet::CalculateGridLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType
|
||||
columns++;
|
||||
}
|
||||
|
||||
JSONHelpers::GridLayoutInfo gridLayoutInfo(JSONHelpers::GridLayoutInfo::Minimal{ .rows = rows, .columns = columns });
|
||||
FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = rows, .columns = columns });
|
||||
|
||||
// Note: The expressions below are NOT equal to C_MULTIPLIER / {rows|columns} and are done
|
||||
// like this to make the sum of all percents exactly C_MULTIPLIER
|
||||
@@ -578,7 +583,7 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
{
|
||||
const std::wstring guid = guidStr.get();
|
||||
|
||||
const auto zoneSetSearchResult = JSONHelpers::FancyZonesDataInstance().FindCustomZoneSet(guid);
|
||||
const auto zoneSetSearchResult = FancyZonesDataInstance().FindCustomZoneSet(guid);
|
||||
|
||||
if (!zoneSetSearchResult.has_value())
|
||||
{
|
||||
@@ -586,9 +591,9 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
}
|
||||
|
||||
const auto& zoneSet = *zoneSetSearchResult;
|
||||
if (zoneSet.type == JSONHelpers::CustomLayoutType::Canvas && std::holds_alternative<JSONHelpers::CanvasLayoutInfo>(zoneSet.info))
|
||||
if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Canvas && std::holds_alternative<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& zoneSetInfo = std::get<JSONHelpers::CanvasLayoutInfo>(zoneSet.info);
|
||||
const auto& zoneSetInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(zoneSet.info);
|
||||
for (const auto& zone : zoneSetInfo.zones)
|
||||
{
|
||||
int x = zone.x;
|
||||
@@ -609,9 +614,9 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (zoneSet.type == JSONHelpers::CustomLayoutType::Grid && std::holds_alternative<JSONHelpers::GridLayoutInfo>(zoneSet.info))
|
||||
else if (zoneSet.type == FancyZonesDataTypes::CustomLayoutType::Grid && std::holds_alternative<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info))
|
||||
{
|
||||
const auto& info = std::get<JSONHelpers::GridLayoutInfo>(zoneSet.info);
|
||||
const auto& info = std::get<FancyZonesDataTypes::GridLayoutInfo>(zoneSet.info);
|
||||
return CalculateGridZones(workArea, info, spacing);
|
||||
}
|
||||
}
|
||||
@@ -619,7 +624,7 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZoneSet::CalculateGridZones(Rect workArea, JSONHelpers::GridLayoutInfo gridLayoutInfo, int spacing)
|
||||
bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone.h"
|
||||
#include "JsonHelpers.h"
|
||||
|
||||
namespace FancyZonesDataTypes
|
||||
{
|
||||
enum class ZoneSetLayoutType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing single zone layout. ZoneSet is responsible for actual calculation of rectangle coordinates
|
||||
@@ -16,7 +20,7 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
||||
/**
|
||||
* @returns Type of the zone layout. Layout type can be focus, columns, rows, grid, priority grid or custom.
|
||||
*/
|
||||
IFACEMETHOD_(JSONHelpers::ZoneSetLayoutType, LayoutType)() = 0;
|
||||
IFACEMETHOD_(FancyZonesDataTypes::ZoneSetLayoutType, LayoutType)() = 0;
|
||||
/**
|
||||
* Add zone to the zone layout.
|
||||
*
|
||||
@@ -102,23 +106,11 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
||||
IFACEMETHOD_(bool, IsZoneEmpty)(int zoneIndex) = 0;
|
||||
};
|
||||
|
||||
#define VERSION_PERSISTEDDATA 0x0000F00D
|
||||
struct ZoneSetPersistedData
|
||||
{
|
||||
static constexpr inline size_t MAX_ZONES = 40;
|
||||
|
||||
DWORD Version{VERSION_PERSISTEDDATA};
|
||||
WORD LayoutId{};
|
||||
DWORD ZoneCount{};
|
||||
JSONHelpers::ZoneSetLayoutType Layout{};
|
||||
RECT Zones[MAX_ZONES]{};
|
||||
};
|
||||
|
||||
struct ZoneSetConfig
|
||||
{
|
||||
ZoneSetConfig(
|
||||
GUID id,
|
||||
JSONHelpers::ZoneSetLayoutType layoutType,
|
||||
FancyZonesDataTypes::ZoneSetLayoutType layoutType,
|
||||
HMONITOR monitor,
|
||||
PCWSTR resolutionKey) noexcept :
|
||||
Id(id),
|
||||
@@ -129,7 +121,7 @@ struct ZoneSetConfig
|
||||
}
|
||||
|
||||
GUID Id{};
|
||||
JSONHelpers::ZoneSetLayoutType LayoutType{};
|
||||
FancyZonesDataTypes::ZoneSetLayoutType LayoutType{};
|
||||
HMONITOR Monitor{};
|
||||
PCWSTR ResolutionKey{};
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <common/common.h>
|
||||
|
||||
#include "FancyZonesData.h"
|
||||
#include "FancyZonesDataTypes.h"
|
||||
#include "ZoneWindow.h"
|
||||
#include "trace.h"
|
||||
#include "util.h"
|
||||
@@ -14,48 +16,6 @@
|
||||
|
||||
namespace ZoneWindowUtils
|
||||
{
|
||||
const wchar_t ActiveZoneSetsTmpFileName[] = L"FancyZonesActiveZoneSets.json";
|
||||
const wchar_t AppliedZoneSetsTmpFileName[] = L"FancyZonesAppliedZoneSets.json";
|
||||
const wchar_t DeletedCustomZoneSetsTmpFileName[] = L"FancyZonesDeletedCustomZoneSets.json";
|
||||
|
||||
const std::wstring& GetTempDirPath()
|
||||
{
|
||||
static std::wstring tmpDirPath;
|
||||
static std::once_flag flag;
|
||||
|
||||
std::call_once(flag, []() {
|
||||
wchar_t buffer[MAX_PATH];
|
||||
|
||||
auto charsWritten = GetTempPath(MAX_PATH, buffer);
|
||||
if (charsWritten > MAX_PATH || (charsWritten == 0))
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
tmpDirPath = std::wstring{ buffer };
|
||||
});
|
||||
|
||||
return tmpDirPath;
|
||||
}
|
||||
|
||||
const std::wstring& GetActiveZoneSetTmpPath()
|
||||
{
|
||||
static std::wstring activeZoneSetTmpFileName = GetTempDirPath() + ActiveZoneSetsTmpFileName;
|
||||
return activeZoneSetTmpFileName;
|
||||
}
|
||||
|
||||
const std::wstring& GetAppliedZoneSetTmpPath()
|
||||
{
|
||||
static std::wstring appliedZoneSetTmpFileName = GetTempDirPath() + AppliedZoneSetsTmpFileName;
|
||||
return appliedZoneSetTmpFileName;
|
||||
}
|
||||
|
||||
const std::wstring& GetDeletedCustomZoneSetsTmpPath()
|
||||
{
|
||||
static std::wstring deletedCustomZoneSetsTmpFileName = GetTempDirPath() + DeletedCustomZoneSetsTmpFileName;
|
||||
return deletedCustomZoneSetsTmpFileName;
|
||||
}
|
||||
|
||||
std::wstring GenerateUniqueId(HMONITOR monitor, PCWSTR deviceId, PCWSTR virtualDesktopId)
|
||||
{
|
||||
wchar_t uniqueId[256]{}; // Parsed deviceId + resolution + virtualDesktopId
|
||||
@@ -546,7 +506,7 @@ ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
||||
OLECHAR* guidString;
|
||||
if (StringFromCLSID(m_activeZoneSet->Id(), &guidString) == S_OK)
|
||||
{
|
||||
JSONHelpers::FancyZonesDataInstance().SetAppLastZones(window, m_uniqueId, guidString, zoneIndexSet);
|
||||
FancyZonesDataInstance().SetAppLastZones(window, m_uniqueId, guidString, zoneIndexSet);
|
||||
}
|
||||
|
||||
CoTaskMemFree(guidString);
|
||||
@@ -619,17 +579,17 @@ ZoneWindow::ClearSelectedZones() noexcept
|
||||
void ZoneWindow::InitializeZoneSets(const std::wstring& parentUniqueId) noexcept
|
||||
{
|
||||
// If there is not defined zone layout for this work area, created default entry.
|
||||
JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId);
|
||||
FancyZonesDataInstance().AddDevice(m_uniqueId);
|
||||
if (!parentUniqueId.empty())
|
||||
{
|
||||
JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parentUniqueId, m_uniqueId);
|
||||
FancyZonesDataInstance().CloneDeviceInfo(parentUniqueId, m_uniqueId);
|
||||
}
|
||||
CalculateZoneSet();
|
||||
}
|
||||
|
||||
void ZoneWindow::CalculateZoneSet() noexcept
|
||||
{
|
||||
const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
const auto& fancyZonesData = FancyZonesDataInstance();
|
||||
const auto deviceInfoData = fancyZonesData.FindDeviceInfo(m_uniqueId);
|
||||
|
||||
if (!deviceInfoData.has_value())
|
||||
@@ -639,7 +599,7 @@ void ZoneWindow::CalculateZoneSet() noexcept
|
||||
|
||||
const auto& activeZoneSet = deviceInfoData->activeZoneSet;
|
||||
|
||||
if (activeZoneSet.uuid.empty() || activeZoneSet.type == JSONHelpers::ZoneSetLayoutType::Blank)
|
||||
if (activeZoneSet.uuid.empty() || activeZoneSet.type == FancyZonesDataTypes::ZoneSetLayoutType::Blank)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -674,11 +634,11 @@ void ZoneWindow::UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept
|
||||
wil::unique_cotaskmem_string zoneSetId;
|
||||
if (SUCCEEDED_LOG(StringFromCLSID(m_activeZoneSet->Id(), &zoneSetId)))
|
||||
{
|
||||
JSONHelpers::ZoneSetData data{
|
||||
FancyZonesDataTypes::ZoneSetData data{
|
||||
.uuid = zoneSetId.get(),
|
||||
.type = m_activeZoneSet->LayoutType()
|
||||
};
|
||||
JSONHelpers::FancyZonesDataInstance().SetActiveZoneSet(m_uniqueId, data);
|
||||
FancyZonesDataInstance().SetActiveZoneSet(m_uniqueId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
|
||||
namespace ZoneWindowUtils
|
||||
{
|
||||
const std::wstring& GetActiveZoneSetTmpPath();
|
||||
const std::wstring& GetAppliedZoneSetTmpPath();
|
||||
const std::wstring& GetDeletedCustomZoneSetsTmpPath();
|
||||
|
||||
std::wstring GenerateUniqueId(HMONITOR monitor, PCWSTR deviceId, PCWSTR virtualDesktopId);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <shared_mutex>
|
||||
#include <functional>
|
||||
#include <unordered_set>
|
||||
#include <ShObjIdl.h>
|
||||
|
||||
#pragma comment(lib, "windowsapp")
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#include "trace.h"
|
||||
#include "lib/ZoneSet.h"
|
||||
#include "lib/Settings.h"
|
||||
#include "lib/JsonHelpers.h"
|
||||
#include "lib/FancyZonesData.h"
|
||||
#include "lib/FancyZonesDataTypes.h"
|
||||
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_hProvider,
|
||||
@@ -71,7 +72,7 @@ void Trace::FancyZones::OnKeyDown(DWORD vkCode, bool win, bool control, bool inM
|
||||
|
||||
void Trace::FancyZones::DataChanged() noexcept
|
||||
{
|
||||
const JSONHelpers::FancyZonesData& data = JSONHelpers::FancyZonesDataInstance();
|
||||
const FancyZonesData& data = FancyZonesDataInstance();
|
||||
int appsHistorySize = static_cast<int>(data.GetAppZoneHistoryMap().size());
|
||||
const auto& customZones = data.GetCustomZoneSetsMap();
|
||||
const auto& devices = data.GetDeviceInfoMap();
|
||||
@@ -82,15 +83,15 @@ void Trace::FancyZones::DataChanged() noexcept
|
||||
return;
|
||||
}
|
||||
|
||||
auto getCustomZoneCount = [&data](const std::variant<JSONHelpers::CanvasLayoutInfo, JSONHelpers::GridLayoutInfo>& layoutInfo) -> int {
|
||||
if (std::holds_alternative<JSONHelpers::GridLayoutInfo>(layoutInfo))
|
||||
auto getCustomZoneCount = [&data](const std::variant<FancyZonesDataTypes::CanvasLayoutInfo, FancyZonesDataTypes::GridLayoutInfo>& layoutInfo) -> int {
|
||||
if (std::holds_alternative<FancyZonesDataTypes::GridLayoutInfo>(layoutInfo))
|
||||
{
|
||||
const auto& info = std::get<JSONHelpers::GridLayoutInfo>(layoutInfo);
|
||||
const auto& info = std::get<FancyZonesDataTypes::GridLayoutInfo>(layoutInfo);
|
||||
return (info.rows() * info.columns());
|
||||
}
|
||||
else if (std::holds_alternative<JSONHelpers::CanvasLayoutInfo>(layoutInfo))
|
||||
else if (std::holds_alternative<FancyZonesDataTypes::CanvasLayoutInfo>(layoutInfo))
|
||||
{
|
||||
const auto& info = std::get<JSONHelpers::CanvasLayoutInfo>(layoutInfo);
|
||||
const auto& info = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(layoutInfo);
|
||||
return static_cast<int>(info.zones.size());
|
||||
}
|
||||
return 0;
|
||||
@@ -108,15 +109,15 @@ void Trace::FancyZones::DataChanged() noexcept
|
||||
std::wstring activeZoneSetInfo;
|
||||
for (const auto& [id, device] : devices)
|
||||
{
|
||||
const JSONHelpers::ZoneSetLayoutType type = device.activeZoneSet.type;
|
||||
const FancyZonesDataTypes::ZoneSetLayoutType type = device.activeZoneSet.type;
|
||||
if (!activeZoneSetInfo.empty())
|
||||
{
|
||||
activeZoneSetInfo += L"; ";
|
||||
}
|
||||
activeZoneSetInfo += L"type: " + JSONHelpers::TypeToString(type);
|
||||
activeZoneSetInfo += L"type: " + FancyZonesDataTypes::TypeToString(type);
|
||||
|
||||
int zoneCount = -1;
|
||||
if (type == JSONHelpers::ZoneSetLayoutType::Custom)
|
||||
if (type == FancyZonesDataTypes::ZoneSetLayoutType::Custom)
|
||||
{
|
||||
const auto& activeCustomZone = customZones.find(device.activeZoneSet.uuid);
|
||||
if (activeCustomZone != customZones.end())
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <common/common.h>
|
||||
#include <common/dpi_aware.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t POWER_TOYS_APP_POWER_LAUCHER[] = L"POWERLAUNCHER.EXE";
|
||||
@@ -255,3 +257,81 @@ void RestoreWindowOrigin(HWND window) noexcept
|
||||
::RemoveProp(window, RESTORE_ORIGIN_STAMP);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidGuid(const std::wstring& str)
|
||||
{
|
||||
GUID id;
|
||||
return SUCCEEDED(CLSIDFromString(str.c_str(), &id));
|
||||
}
|
||||
|
||||
bool 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 ZoneWindowUtils::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::stoi(std::wstring(&c));
|
||||
}
|
||||
for (const auto& c : parts[2])
|
||||
{
|
||||
std::stoi(std::wstring(&c));
|
||||
}
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidGuid(parts[3]) || parts[0].empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,3 +124,6 @@ bool IsInterestingWindow(HWND window, const std::vector<std::wstring>& excludedA
|
||||
void SaveWindowSizeAndOrigin(HWND window) noexcept;
|
||||
void RestoreWindowSize(HWND window) noexcept;
|
||||
void RestoreWindowOrigin(HWND window) noexcept;
|
||||
|
||||
bool IsValidGuid(const std::wstring& str);
|
||||
bool IsValidDeviceId(const std::wstring& str);
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include <lib/FancyZones.h>
|
||||
#include <lib/FancyZonesData.h>
|
||||
#include <lib/Settings.h>
|
||||
#include <common/common.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
@@ -271,7 +271,7 @@ namespace FancyZonesUnitTests
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings = nullptr;
|
||||
winrt::com_ptr<IFancyZonesCallback> m_fzCallback = nullptr;
|
||||
|
||||
JSONHelpers::FancyZonesData& m_fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
FancyZonesData& m_fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
std::wstring serializedPowerToySettings(const Settings& settings)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/JsonHelpers.h"
|
||||
#include "lib/FancyZonesDataTypes.h"
|
||||
|
||||
namespace CustomAssert
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace CustomAssert
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(g1 == g2);
|
||||
}
|
||||
|
||||
static void AreEqual(JSONHelpers::ZoneSetLayoutType t1, JSONHelpers::ZoneSetLayoutType t2)
|
||||
static void AreEqual(FancyZonesDataTypes::ZoneSetLayoutType t1, FancyZonesDataTypes::ZoneSetLayoutType t2)
|
||||
{
|
||||
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(t1 == t2);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "lib\FancyZonesData.h"
|
||||
#include "lib\FancyZonesDataTypes.h"
|
||||
#include "lib\JsonHelpers.h"
|
||||
#include "lib\ZoneSet.h"
|
||||
|
||||
@@ -8,14 +10,14 @@
|
||||
#include <common/settings_helpers.h>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using TZoneSetLayoutType = JSONHelpers::ZoneSetLayoutType;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS (ZoneSetUnitTests)
|
||||
{
|
||||
GUID m_id;
|
||||
const TZoneSetLayoutType m_layoutType = TZoneSetLayoutType::Custom;
|
||||
const ZoneSetLayoutType m_layoutType = ZoneSetLayoutType::Custom;
|
||||
const PCWSTR m_resolutionKey = L"WorkAreaIn";
|
||||
|
||||
winrt::com_ptr<IZoneSet> m_set;
|
||||
@@ -490,7 +492,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
ZoneSetConfig config({}, TZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
ZoneSetConfig config({}, ZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
m_set = MakeZoneSet(config);
|
||||
|
||||
// Add a couple of zones.
|
||||
@@ -504,7 +506,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (EmptyZonesLeft)
|
||||
{
|
||||
ZoneSetConfig config({}, TZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
ZoneSetConfig config({}, ZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
auto set = MakeZoneSet(config);
|
||||
|
||||
set->MoveWindowIntoZoneByDirection(Mocks::Window(), Mocks::Window(), VK_LEFT, true);
|
||||
@@ -512,7 +514,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (EmptyZonesRight)
|
||||
{
|
||||
ZoneSetConfig config({}, TZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
ZoneSetConfig config({}, ZoneSetLayoutType::Custom, Mocks::Monitor(), L"WorkAreaIn");
|
||||
auto set = MakeZoneSet(config);
|
||||
|
||||
set->MoveWindowIntoZoneByDirection(Mocks::Window(), Mocks::Window(), VK_RIGHT, true);
|
||||
@@ -716,7 +718,7 @@ namespace FancyZonesUnitTests
|
||||
TEST_CLASS (ZoneSetCalculateZonesUnitTests)
|
||||
{
|
||||
GUID m_id;
|
||||
const TZoneSetLayoutType m_layoutType = TZoneSetLayoutType::Custom;
|
||||
const ZoneSetLayoutType m_layoutType = ZoneSetLayoutType::Custom;
|
||||
const PCWSTR m_resolutionKey = L"WorkAreaIn";
|
||||
winrt::com_ptr<IZoneSet> m_set;
|
||||
|
||||
@@ -783,9 +785,9 @@ namespace FancyZonesUnitTests
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
@@ -801,9 +803,9 @@ namespace FancyZonesUnitTests
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
MONITORINFO info{};
|
||||
@@ -817,9 +819,9 @@ namespace FancyZonesUnitTests
|
||||
const int spacing = 0;
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
@@ -836,15 +838,15 @@ namespace FancyZonesUnitTests
|
||||
const int spacing = -1;
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
auto result = set->CalculateZones(monitorInfo, zoneCount, spacing);
|
||||
if (type == static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus))
|
||||
if (type == static_cast<int>(ZoneSetLayoutType::Focus))
|
||||
{
|
||||
//Focus doesn't depends on spacing
|
||||
Assert::IsTrue(result);
|
||||
@@ -861,16 +863,16 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
const int spacing = monitorInfo.rcWork.right;
|
||||
auto result = set->CalculateZones(monitorInfo, zoneCount, spacing);
|
||||
if (type == static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus))
|
||||
if (type == static_cast<int>(ZoneSetLayoutType::Focus))
|
||||
{
|
||||
//Focus doesn't depends on spacing
|
||||
Assert::IsTrue(result);
|
||||
@@ -887,16 +889,16 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const int zoneCount = 10;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
const int spacing = monitorInfo.rcWork.bottom;
|
||||
auto result = set->CalculateZones(monitorInfo, zoneCount, spacing);
|
||||
if (type == static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus))
|
||||
if (type == static_cast<int>(ZoneSetLayoutType::Focus))
|
||||
{
|
||||
//Focus doesn't depends on spacing
|
||||
Assert::IsTrue(result);
|
||||
@@ -914,9 +916,9 @@ namespace FancyZonesUnitTests
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 0;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
@@ -931,12 +933,12 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const int spacing = 1;
|
||||
|
||||
for (int type = static_cast<int>(JSONHelpers::ZoneSetLayoutType::Focus); type < static_cast<int>(JSONHelpers::ZoneSetLayoutType::Custom); type++)
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 40; //editor limit
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<TZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, static_cast<ZoneSetLayoutType>(type), m_monitor, m_resolutionKey);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
@@ -959,7 +961,7 @@ namespace FancyZonesUnitTests
|
||||
std::filesystem::remove(m_path);
|
||||
}
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
@@ -977,7 +979,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsTrue(std::filesystem::create_directories(m_path));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
@@ -989,18 +991,16 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CustomZoneFromInvalidCanvasLayoutInfo)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const std::wstring uuid = L"uuid";
|
||||
const CanvasLayoutInfo info{ -1, 100, { CanvasLayoutInfo::Rect{ -10, -10, 100, 100 }, CanvasLayoutInfo::Rect{ 50, 50, 150, 150 } } };
|
||||
CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info } };
|
||||
json::to_file(m_path, CustomZoneSetJSON::ToJson(expected));
|
||||
JSONHelpers::CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info } };
|
||||
json::to_file(m_path, JSONHelpers::CustomZoneSetJSON::ToJson(expected));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
|
||||
const int spacing = 10;
|
||||
const int zoneCount = static_cast<int>(info.zones.size());
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
@@ -1012,23 +1012,21 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CustomZoneFromInvalidGridLayoutInfo)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const std::wstring uuid = L"uuid";
|
||||
const GridLayoutInfo grid(GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
const GridLayoutInfo grid(GridLayoutInfo(GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 3,
|
||||
.rowsPercents = { -100 }, //rows percents are negative
|
||||
.columnsPercents = { 2500, 2500 }, //column percents count is invalid
|
||||
.cellChildMap = { { 0, 1, 2 } } }));
|
||||
CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, CustomZoneSetJSON::ToJson(expected));
|
||||
JSONHelpers::CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, JSONHelpers::CustomZoneSetJSON::ToJson(expected));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
|
||||
const int spacing = 0;
|
||||
const int zoneCount = grid.rows() * grid.columns();
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
@@ -1040,14 +1038,12 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CustomZoneFromValidCanvasLayoutInfo)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
//prepare device data
|
||||
{
|
||||
const std::wstring zoneUuid = L"default_device_id";
|
||||
DeviceInfoJSON deviceInfo{ zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 } };
|
||||
const std::wstring deviceInfoPath = FancyZonesDataInstance().GetPersistFancyZonesJSONPath() + L".device_info_tmp";
|
||||
FancyZonesDataInstance().SerializeDeviceInfoToTmpFile(deviceInfo, deviceInfoPath);
|
||||
JSONHelpers::DeviceInfoJSON deviceInfo{ zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 } };
|
||||
const std::wstring deviceInfoPath = FancyZonesDataInstance().zonesSettingsFileName + L".device_info_tmp";
|
||||
JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfo, deviceInfoPath);
|
||||
|
||||
FancyZonesDataInstance().ParseDeviceInfoFromTmpFile(deviceInfoPath);
|
||||
std::filesystem::remove(deviceInfoPath);
|
||||
@@ -1057,15 +1053,15 @@ namespace FancyZonesUnitTests
|
||||
wil::unique_cotaskmem_string uuid;
|
||||
Assert::AreEqual(S_OK, StringFromCLSID(m_id, &uuid));
|
||||
const CanvasLayoutInfo info{ 123, 321, { CanvasLayoutInfo::Rect{ 0, 0, 100, 100 }, CanvasLayoutInfo::Rect{ 50, 50, 150, 150 } } };
|
||||
CustomZoneSetJSON expected{ uuid.get(), CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info } };
|
||||
json::to_file(m_path, CustomZoneSetJSON::ToJson(expected));
|
||||
JSONHelpers::CustomZoneSetJSON expected{ uuid.get(), CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info } };
|
||||
json::to_file(m_path, JSONHelpers::CustomZoneSetJSON::ToJson(expected));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
FancyZonesDataInstance().ParseCustomZoneSetFromTmpFile(m_path);
|
||||
|
||||
//test
|
||||
const int spacing = 10;
|
||||
const int zoneCount = static_cast<int>(info.zones.size());
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
auto set = MakeZoneSet(m_config);
|
||||
@@ -1077,14 +1073,12 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CustomZoneFromValidGridFullLayoutInfo)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
//prepare device data
|
||||
{
|
||||
const std::wstring zoneUuid = L"default_device_id";
|
||||
DeviceInfoJSON deviceInfo{ zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 } };
|
||||
const std::wstring deviceInfoPath = FancyZonesDataInstance().GetPersistFancyZonesJSONPath() + L".device_info_tmp";
|
||||
FancyZonesDataInstance().SerializeDeviceInfoToTmpFile(deviceInfo, deviceInfoPath);
|
||||
JSONHelpers::DeviceInfoJSON deviceInfo{ zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 } };
|
||||
const std::wstring deviceInfoPath = FancyZonesDataInstance().zonesSettingsFileName + L".device_info_tmp";
|
||||
JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfo, deviceInfoPath);
|
||||
|
||||
FancyZonesDataInstance().ParseDeviceInfoFromTmpFile(deviceInfoPath);
|
||||
std::filesystem::remove(deviceInfoPath);
|
||||
@@ -1093,21 +1087,21 @@ namespace FancyZonesUnitTests
|
||||
//prepare expected data
|
||||
wil::unique_cotaskmem_string uuid;
|
||||
Assert::AreEqual(S_OK, StringFromCLSID(m_id, &uuid));
|
||||
const GridLayoutInfo grid(GridLayoutInfo(JSONHelpers::GridLayoutInfo::Full{
|
||||
const GridLayoutInfo grid(GridLayoutInfo(GridLayoutInfo::Full{
|
||||
.rows = 1,
|
||||
.columns = 3,
|
||||
.rowsPercents = { 10000 },
|
||||
.columnsPercents = { 2500, 5000, 2500 },
|
||||
.cellChildMap = { { 0, 1, 2 } } }));
|
||||
CustomZoneSetJSON expected{ uuid.get(), CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, CustomZoneSetJSON::ToJson(expected));
|
||||
JSONHelpers::CustomZoneSetJSON expected{ uuid.get(), CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, JSONHelpers::CustomZoneSetJSON::ToJson(expected));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
FancyZonesDataInstance().ParseCustomZoneSetFromTmpFile(m_path);
|
||||
|
||||
const int spacing = 10;
|
||||
const int zoneCount = grid.rows() * grid.columns();
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
{
|
||||
@@ -1120,20 +1114,18 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CustomZoneFromValidGridMinimalLayoutInfo)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const std::wstring uuid = L"uuid";
|
||||
const GridLayoutInfo grid(GridLayoutInfo(JSONHelpers::GridLayoutInfo::Minimal{
|
||||
const GridLayoutInfo grid(GridLayoutInfo(GridLayoutInfo::Minimal{
|
||||
.rows = 1,
|
||||
.columns = 3 }));
|
||||
CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, CustomZoneSetJSON::ToJson(expected));
|
||||
JSONHelpers::CustomZoneSetJSON expected{ uuid, CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } };
|
||||
json::to_file(m_path, JSONHelpers::CustomZoneSetJSON::ToJson(expected));
|
||||
Assert::IsTrue(std::filesystem::exists(m_path));
|
||||
|
||||
const int spacing = 0;
|
||||
const int zoneCount = grid.rows() * grid.columns();
|
||||
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, TZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
ZoneSetConfig m_config = ZoneSetConfig(m_id, ZoneSetLayoutType::Custom, m_monitor, m_resolutionKey);
|
||||
auto set = MakeZoneSet(m_config);
|
||||
|
||||
for (const auto& monitorInfo : m_popularMonitors)
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include <lib/ZoneSet.h>
|
||||
#include <lib/ZoneWindow.h>
|
||||
#include <lib/FancyZones.h>
|
||||
#include <lib/FancyZonesData.h>
|
||||
#include <lib/FancyZonesDataTypes.h>
|
||||
#include <lib/JsonHelpers.h>
|
||||
#include "Util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
@@ -71,7 +74,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
winrt::com_ptr<IZoneWindow> m_zoneWindow;
|
||||
|
||||
JSONHelpers::FancyZonesData& m_fancyZonesData = JSONHelpers::FancyZonesDataInstance();
|
||||
FancyZonesData& m_fancyZonesData = FancyZonesDataInstance();
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
@@ -84,13 +87,13 @@ namespace FancyZonesUnitTests
|
||||
m_parentUniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{61FA9FC0-26A6-4B37-A834-491C148DFC57}";
|
||||
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
||||
|
||||
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
|
||||
Assert::IsFalse(ZoneWindowUtils::GetAppliedZoneSetTmpPath().empty());
|
||||
Assert::IsFalse(ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath().empty());
|
||||
Assert::IsFalse(m_fancyZonesData.activeZoneSetTmpFileName.empty());
|
||||
Assert::IsFalse(m_fancyZonesData.appliedZoneSetTmpFileName.empty());
|
||||
Assert::IsFalse(m_fancyZonesData.deletedCustomZoneSetsTmpFileName.empty());
|
||||
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetActiveZoneSetTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetAppliedZoneSetTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath()));
|
||||
Assert::IsFalse(std::filesystem::exists(m_fancyZonesData.activeZoneSetTmpFileName));
|
||||
Assert::IsFalse(std::filesystem::exists(m_fancyZonesData.appliedZoneSetTmpFileName));
|
||||
Assert::IsFalse(std::filesystem::exists(m_fancyZonesData.deletedCustomZoneSetsTmpFileName));
|
||||
|
||||
m_fancyZonesData.SetSettingsModulePath(L"FancyZonesUnitTests");
|
||||
m_fancyZonesData.clear_data();
|
||||
@@ -99,21 +102,21 @@ namespace FancyZonesUnitTests
|
||||
TEST_METHOD_CLEANUP(Cleanup)
|
||||
{
|
||||
//cleanup temp files if were created
|
||||
std::filesystem::remove(ZoneWindowUtils::GetActiveZoneSetTmpPath());
|
||||
std::filesystem::remove(ZoneWindowUtils::GetAppliedZoneSetTmpPath());
|
||||
std::filesystem::remove(ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath());
|
||||
std::filesystem::remove(m_fancyZonesData.activeZoneSetTmpFileName);
|
||||
std::filesystem::remove(m_fancyZonesData.appliedZoneSetTmpFileName);
|
||||
std::filesystem::remove(m_fancyZonesData.deletedCustomZoneSetsTmpFileName);
|
||||
|
||||
m_zoneWindow = nullptr;
|
||||
}
|
||||
|
||||
winrt::com_ptr<IZoneWindow> InitZoneWindowWithActiveZoneSet()
|
||||
{
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
Assert::IsFalse(std::filesystem::exists(activeZoneSetTempPath));
|
||||
|
||||
const auto type = JSONHelpers::ZoneSetLayoutType::Columns;
|
||||
const auto expectedZoneSet = JSONHelpers::ZoneSetData{ Helpers::CreateGuidString(), type };
|
||||
const auto data = JSONHelpers::DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto type = FancyZonesDataTypes::ZoneSetLayoutType::Columns;
|
||||
const auto expectedZoneSet = FancyZonesDataTypes::ZoneSetData{ Helpers::CreateGuidString(), type };
|
||||
const auto data = FancyZonesDataTypes::DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
@@ -203,16 +206,16 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveZoneTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
|
||||
for (int type = static_cast<int>(ZoneSetLayoutType::Focus); type < static_cast<int>(ZoneSetLayoutType::Custom); type++)
|
||||
{
|
||||
const auto expectedZoneSet = ZoneSetData{ Helpers::CreateGuidString(), static_cast<ZoneSetLayoutType>(type) };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
@@ -228,15 +231,15 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto expectedZoneSet = ZoneSetData{ Helpers::CreateGuidString(), type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
@@ -254,25 +257,25 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFile)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(CustomZoneSetJSON{ customSetGuid, customZoneData });
|
||||
auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData });
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
@@ -290,27 +293,27 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithDeletedCustomZones)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
const auto deletedZonesTempPath = ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName;
|
||||
const auto deletedZonesTempPath = m_fancyZonesData.deletedCustomZoneSetsTmpFileName;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
const auto customZoneSet = CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
const auto customZoneSet = JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
|
||||
//save same zone as deleted
|
||||
@@ -336,27 +339,27 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithUnusedDeletedCustomZones)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
//save required data
|
||||
const auto activeZoneSetTempPath = ZoneWindowUtils::GetActiveZoneSetTmpPath();
|
||||
const auto appliedZoneSetTempPath = ZoneWindowUtils::GetAppliedZoneSetTmpPath();
|
||||
const auto deletedZonesTempPath = ZoneWindowUtils::GetDeletedCustomZoneSetsTmpPath();
|
||||
const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName;
|
||||
const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName;
|
||||
const auto deletedZonesTempPath = m_fancyZonesData.deletedCustomZoneSetsTmpFileName;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::Custom;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto expectedZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 };
|
||||
const auto deviceInfo = DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = DeviceInfoJSON::ToJson(deviceInfo);
|
||||
const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data };
|
||||
const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo);
|
||||
json::to_file(activeZoneSetTempPath, json);
|
||||
|
||||
const auto info = CanvasLayoutInfo{
|
||||
100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } }
|
||||
};
|
||||
const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info };
|
||||
const auto customZoneSet = CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
const auto customZoneSet = JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData };
|
||||
auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(customZoneSet);
|
||||
json::to_file(appliedZoneSetTempPath, customZoneJson);
|
||||
|
||||
//save different zone as deleted
|
||||
@@ -383,7 +386,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CreateZoneWindowClonedFromParent)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||
const int spacing = 10;
|
||||
@@ -412,7 +415,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNotClonedFromParent)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||
const int spacing = 10;
|
||||
|
||||
Reference in New Issue
Block a user