mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 20:57:22 +02:00
[FancyZones] Split zones-settings: layout hotkeys (#15514)
This commit is contained in:
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@@ -1951,6 +1951,7 @@ textblock
|
|||||||
TEXTINCLUDE
|
TEXTINCLUDE
|
||||||
THICKFRAME
|
THICKFRAME
|
||||||
THISCOMPONENT
|
THISCOMPONENT
|
||||||
|
THotkey
|
||||||
thre
|
thre
|
||||||
TILEDWINDOW
|
TILEDWINDOW
|
||||||
timedate
|
timedate
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#include <common/utils/resources.h>
|
#include <common/utils/resources.h>
|
||||||
|
|
||||||
#include <FancyZonesLib/FancyZones.h>
|
#include <FancyZonesLib/FancyZones.h>
|
||||||
#include <FancyZonesLib/FancyZonesData.h>
|
|
||||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
|
#include <FancyZonesLib/ModuleConstants.h>
|
||||||
|
|
||||||
#include <FancyZonesApp.h>
|
#include <FancyZonesApp.h>
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
Trace::RegisterProvider();
|
Trace::RegisterProvider();
|
||||||
|
|
||||||
FancyZonesApp app(GET_RESOURCE_STRING(IDS_FANCYZONES), NonLocalizable::FancyZonesStr);
|
FancyZonesApp app(GET_RESOURCE_STRING(IDS_FANCYZONES), NonLocalizable::ModuleKey);
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
||||||
run_message_loop();
|
run_message_loop();
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <common/SettingsAPI/FileWatcher.h>
|
#include <common/SettingsAPI/FileWatcher.h>
|
||||||
|
|
||||||
#include <FancyZonesLib/FancyZonesData.h>
|
#include <FancyZonesLib/FancyZonesData.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
#include <FancyZonesLib/MonitorUtils.h>
|
#include <FancyZonesLib/MonitorUtils.h>
|
||||||
@@ -68,6 +69,9 @@ public:
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
this->disableModuleCallback = std::move(disableModuleCallback);
|
this->disableModuleCallback = std::move(disableModuleCallback);
|
||||||
|
|
||||||
|
FancyZonesDataInstance().ReplaceZoneSettingsFileFromOlderVersions();
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFancyZones
|
// IFancyZones
|
||||||
@@ -486,8 +490,8 @@ FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept
|
|||||||
|
|
||||||
if (changeLayoutWhileNotDragging || changeLayoutWhileDragging)
|
if (changeLayoutWhileNotDragging || changeLayoutWhileDragging)
|
||||||
{
|
{
|
||||||
auto quickKeysMap = FancyZonesDataInstance().GetLayoutQuickKeys();
|
auto layoutId = LayoutHotkeys::instance().GetLayoutId(digitPressed);
|
||||||
if (std::any_of(quickKeysMap.begin(), quickKeysMap.end(), [=](auto item) { return item.second == digitPressed; }))
|
if (layoutId.has_value())
|
||||||
{
|
{
|
||||||
PostMessageW(m_window, WM_PRIV_QUICK_LAYOUT_KEY, 0, static_cast<LPARAM>(digitPressed));
|
PostMessageW(m_window, WM_PRIV_QUICK_LAYOUT_KEY, 0, static_cast<LPARAM>(digitPressed));
|
||||||
Trace::FancyZones::QuickLayoutSwitched(changeLayoutWhileNotDragging);
|
Trace::FancyZones::QuickLayoutSwitched(changeLayoutWhileNotDragging);
|
||||||
@@ -767,6 +771,10 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
|||||||
FancyZonesDataInstance().LoadFancyZonesData();
|
FancyZonesDataInstance().LoadFancyZonesData();
|
||||||
UpdateZoneSets();
|
UpdateZoneSets();
|
||||||
}
|
}
|
||||||
|
else if (message == WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE)
|
||||||
|
{
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
}
|
||||||
else if (message == WM_PRIV_QUICK_LAYOUT_KEY)
|
else if (message == WM_PRIV_QUICK_LAYOUT_KEY)
|
||||||
{
|
{
|
||||||
ApplyQuickLayout(static_cast<int>(lparam));
|
ApplyQuickLayout(static_cast<int>(lparam));
|
||||||
@@ -1293,13 +1301,16 @@ bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
|||||||
|
|
||||||
void FancyZones::ApplyQuickLayout(int key) noexcept
|
void FancyZones::ApplyQuickLayout(int key) noexcept
|
||||||
{
|
{
|
||||||
std::wstring uuid;
|
auto layoutId = LayoutHotkeys::instance().GetLayoutId(key);
|
||||||
for (auto [layoutUuid, hotkey] : FancyZonesDataInstance().GetLayoutQuickKeys())
|
if (!layoutId)
|
||||||
{
|
{
|
||||||
if (hotkey == key)
|
return;
|
||||||
{
|
}
|
||||||
uuid = layoutUuid;
|
|
||||||
}
|
auto uuidStr = FancyZonesUtils::GuidToString(layoutId.value());
|
||||||
|
if (!uuidStr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(m_currentDesktopId);
|
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(m_currentDesktopId);
|
||||||
@@ -1307,12 +1318,12 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
|
|||||||
// Find a custom zone set with this uuid and apply it
|
// Find a custom zone set with this uuid and apply it
|
||||||
auto customZoneSets = FancyZonesDataInstance().GetCustomZoneSetsMap();
|
auto customZoneSets = FancyZonesDataInstance().GetCustomZoneSetsMap();
|
||||||
|
|
||||||
if (!customZoneSets.contains(uuid))
|
if (!customZoneSets.contains(uuidStr.value()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyZonesDataTypes::ZoneSetData data{ .uuid = uuid, .type = FancyZonesDataTypes::ZoneSetLayoutType::Custom };
|
FancyZonesDataTypes::ZoneSetData data{ .uuid = uuidStr.value(), .type = FancyZonesDataTypes::ZoneSetLayoutType::Custom };
|
||||||
FancyZonesDataInstance().SetActiveZoneSet(workArea->UniqueId(), data);
|
FancyZonesDataInstance().SetActiveZoneSet(workArea->UniqueId(), data);
|
||||||
FancyZonesDataInstance().SaveZoneSettings();
|
FancyZonesDataInstance().SaveZoneSettings();
|
||||||
UpdateZoneSets();
|
UpdateZoneSets();
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
#include <common/utils/process_path.h>
|
#include <common/utils/process_path.h>
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||||
|
#include <FancyZonesLib/ModuleConstants.h>
|
||||||
|
|
||||||
// Non-localizable strings
|
// Non-localizable strings
|
||||||
namespace NonLocalizable
|
namespace NonLocalizable
|
||||||
{
|
{
|
||||||
@@ -149,7 +152,7 @@ FancyZonesData& FancyZonesDataInstance()
|
|||||||
|
|
||||||
FancyZonesData::FancyZonesData()
|
FancyZonesData::FancyZonesData()
|
||||||
{
|
{
|
||||||
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::FancyZonesStr);
|
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::ModuleKey);
|
||||||
|
|
||||||
settingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesSettingsFile);
|
settingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesSettingsFile);
|
||||||
zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile);
|
zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile);
|
||||||
@@ -157,6 +160,26 @@ FancyZonesData::FancyZonesData()
|
|||||||
editorParametersFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesEditorParametersFile);
|
editorParametersFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesEditorParametersFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FancyZonesData::ReplaceZoneSettingsFileFromOlderVersions()
|
||||||
|
{
|
||||||
|
if (std::filesystem::exists(zonesSettingsFileName))
|
||||||
|
{
|
||||||
|
json::JsonObject fancyZonesDataJSON = GetPersistFancyZonesJSON();
|
||||||
|
|
||||||
|
//appZoneHistoryMap = JSONHelpers::ParseAppZoneHistory(fancyZonesDataJSON);
|
||||||
|
//deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON);
|
||||||
|
//customZoneSetsMap = JSONHelpers::ParseCustomZoneSets(fancyZonesDataJSON);
|
||||||
|
|
||||||
|
auto quickKeysMap = JSONHelpers::ParseQuickKeys(fancyZonesDataJSON);
|
||||||
|
if (quickKeysMap)
|
||||||
|
{
|
||||||
|
JSONHelpers::SaveLayoutHotkeys(quickKeysMap.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: remove zone-settings.json after getting all info from it
|
||||||
|
}
|
||||||
|
|
||||||
void FancyZonesData::SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback)
|
void FancyZonesData::SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback)
|
||||||
{
|
{
|
||||||
m_virtualDesktopCheckCallback = callback;
|
m_virtualDesktopCheckCallback = callback;
|
||||||
@@ -616,8 +639,7 @@ void FancyZonesData::LoadFancyZonesData()
|
|||||||
|
|
||||||
appZoneHistoryMap = JSONHelpers::ParseAppZoneHistory(fancyZonesDataJSON);
|
appZoneHistoryMap = JSONHelpers::ParseAppZoneHistory(fancyZonesDataJSON);
|
||||||
deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON);
|
deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON);
|
||||||
customZoneSetsMap = JSONHelpers::ParseCustomZoneSets(fancyZonesDataJSON);
|
customZoneSetsMap = JSONHelpers::ParseCustomZoneSets(fancyZonesDataJSON);
|
||||||
quickKeysMap = JSONHelpers::ParseQuickKeys(fancyZonesDataJSON);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,11 +673,11 @@ void FancyZonesData::SaveZoneSettings() const
|
|||||||
|
|
||||||
if (dirtyFlag)
|
if (dirtyFlag)
|
||||||
{
|
{
|
||||||
JSONHelpers::SaveZoneSettings(zonesSettingsFileName, updatedDeviceInfoMap, customZoneSetsMap, quickKeysMap);
|
JSONHelpers::SaveZoneSettings(zonesSettingsFileName, updatedDeviceInfoMap, customZoneSetsMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JSONHelpers::SaveZoneSettings(zonesSettingsFileName, deviceInfoMap, customZoneSetsMap, quickKeysMap);
|
JSONHelpers::SaveZoneSettings(zonesSettingsFileName, deviceInfoMap, customZoneSetsMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,6 @@
|
|||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
#include <FancyZonesLib/JsonHelpers.h>
|
#include <FancyZonesLib/JsonHelpers.h>
|
||||||
|
|
||||||
// Non-localizable strings
|
|
||||||
namespace NonLocalizable
|
|
||||||
{
|
|
||||||
const wchar_t FancyZonesStr[] = L"FancyZones";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace FancyZonesDataTypes
|
namespace FancyZonesDataTypes
|
||||||
{
|
{
|
||||||
struct ZoneSetData;
|
struct ZoneSetData;
|
||||||
@@ -36,6 +30,7 @@ namespace FancyZonesUnitTests
|
|||||||
class ZoneSetCalculateZonesUnitTests;
|
class ZoneSetCalculateZonesUnitTests;
|
||||||
class WorkAreaUnitTests;
|
class WorkAreaUnitTests;
|
||||||
class WorkAreaCreationUnitTests;
|
class WorkAreaCreationUnitTests;
|
||||||
|
class LayoutHotkeysUnitTests;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -44,6 +39,8 @@ class FancyZonesData
|
|||||||
public:
|
public:
|
||||||
FancyZonesData();
|
FancyZonesData();
|
||||||
|
|
||||||
|
void ReplaceZoneSettingsFileFromOlderVersions();
|
||||||
|
|
||||||
void SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback);
|
void SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback);
|
||||||
|
|
||||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& id) const;
|
std::optional<FancyZonesDataTypes::DeviceInfoData> FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& id) const;
|
||||||
@@ -53,12 +50,6 @@ public:
|
|||||||
const JSONHelpers::TCustomZoneSetsMap& GetCustomZoneSetsMap() const;
|
const JSONHelpers::TCustomZoneSetsMap& GetCustomZoneSetsMap() const;
|
||||||
const std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>>& GetAppZoneHistoryMap() const;
|
const std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>>& GetAppZoneHistoryMap() const;
|
||||||
|
|
||||||
inline const JSONHelpers::TLayoutQuickKeysMap& GetLayoutQuickKeys() const
|
|
||||||
{
|
|
||||||
std::scoped_lock lock{ dataLock };
|
|
||||||
return quickKeysMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::wstring& GetZonesSettingsFileName() const
|
inline const std::wstring& GetZonesSettingsFileName() const
|
||||||
{
|
{
|
||||||
return zonesSettingsFileName;
|
return zonesSettingsFileName;
|
||||||
@@ -98,6 +89,7 @@ private:
|
|||||||
friend class FancyZonesUnitTests::WorkAreaUnitTests;
|
friend class FancyZonesUnitTests::WorkAreaUnitTests;
|
||||||
friend class FancyZonesUnitTests::WorkAreaCreationUnitTests;
|
friend class FancyZonesUnitTests::WorkAreaCreationUnitTests;
|
||||||
friend class FancyZonesUnitTests::ZoneSetCalculateZonesUnitTests;
|
friend class FancyZonesUnitTests::ZoneSetCalculateZonesUnitTests;
|
||||||
|
friend class FancyZonesUnitTests::LayoutHotkeysUnitTests;
|
||||||
|
|
||||||
inline void SetDeviceInfo(const FancyZonesDataTypes::DeviceIdData& deviceId, FancyZonesDataTypes::DeviceInfoData data)
|
inline void SetDeviceInfo(const FancyZonesDataTypes::DeviceIdData& deviceId, FancyZonesDataTypes::DeviceInfoData data)
|
||||||
{
|
{
|
||||||
@@ -128,6 +120,12 @@ private:
|
|||||||
zonesSettingsFileName = result + L"\\" + std::wstring(L"zones-settings.json");
|
zonesSettingsFileName = result + L"\\" + std::wstring(L"zones-settings.json");
|
||||||
appZoneHistoryFileName = result + L"\\" + std::wstring(L"app-zone-history.json");
|
appZoneHistoryFileName = result + L"\\" + std::wstring(L"app-zone-history.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::wstring GetZoneSettingsPath(std::wstring_view moduleName)
|
||||||
|
{
|
||||||
|
std::wstring result = PTSettingsHelper::get_module_save_folder_location(moduleName);
|
||||||
|
return result + L"\\" + std::wstring(L"zones-settings.json");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
void RemoveDesktopAppZoneHistory(GUID desktopId);
|
void RemoveDesktopAppZoneHistory(GUID desktopId);
|
||||||
|
|
||||||
@@ -137,8 +135,6 @@ private:
|
|||||||
JSONHelpers::TDeviceInfoMap deviceInfoMap{};
|
JSONHelpers::TDeviceInfoMap deviceInfoMap{};
|
||||||
// Maps custom zoneset UUID to it's data
|
// Maps custom zoneset UUID to it's data
|
||||||
JSONHelpers::TCustomZoneSetsMap customZoneSetsMap{};
|
JSONHelpers::TCustomZoneSetsMap customZoneSetsMap{};
|
||||||
// Maps zoneset UUID with quick access keys
|
|
||||||
JSONHelpers::TLayoutQuickKeysMap quickKeysMap{};
|
|
||||||
|
|
||||||
std::wstring settingsFileName;
|
std::wstring settingsFileName;
|
||||||
std::wstring zonesSettingsFileName;
|
std::wstring zonesSettingsFileName;
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "LayoutHotkeys.h"
|
||||||
|
|
||||||
|
#include <common/logger/logger.h>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
|
#include <FancyZonesLib/JsonHelpers.h>
|
||||||
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
|
namespace JsonUtils
|
||||||
|
{
|
||||||
|
struct LayoutHotkeysJSON
|
||||||
|
{
|
||||||
|
GUID uuid;
|
||||||
|
int key;
|
||||||
|
|
||||||
|
static std::optional<LayoutHotkeysJSON> FromJson(const json::JsonObject& json)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LayoutHotkeysJSON result;
|
||||||
|
|
||||||
|
std::wstring uuidStr = json.GetNamedString(NonLocalizable::LayoutHotkeysIds::LayoutUuidID).c_str();
|
||||||
|
auto uuidOpt = FancyZonesUtils::GuidFromString(uuidStr);
|
||||||
|
if (!uuidOpt)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.uuid = uuidOpt.value();
|
||||||
|
result.key = static_cast<int>(json.GetNamedNumber(NonLocalizable::LayoutHotkeysIds::KeyID));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error&)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LayoutHotkeys::THotkeyMap ParseJson(const json::JsonObject& json)
|
||||||
|
{
|
||||||
|
LayoutHotkeys::THotkeyMap map{};
|
||||||
|
auto layoutHotkeys = json.GetNamedArray(NonLocalizable::LayoutHotkeysIds::LayoutHotkeysArrayID);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < layoutHotkeys.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (auto obj = LayoutHotkeysJSON::FromJson(layoutHotkeys.GetObjectAt(i)); obj.has_value())
|
||||||
|
{
|
||||||
|
map[obj->key] = obj->uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LayoutHotkeys::LayoutHotkeys()
|
||||||
|
{
|
||||||
|
const std::wstring& settingsFileName = LayoutHotkeysFileName();
|
||||||
|
m_fileWatcher = std::make_unique<FileWatcher>(settingsFileName, [&]() {
|
||||||
|
PostMessageW(HWND_BROADCAST, WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE, NULL, NULL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutHotkeys& LayoutHotkeys::instance()
|
||||||
|
{
|
||||||
|
static LayoutHotkeys self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutHotkeys::LoadData()
|
||||||
|
{
|
||||||
|
auto data = json::from_file(LayoutHotkeysFileName());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
m_hotkeyMap = JsonUtils::ParseJson(data.value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hotkeyMap.clear();
|
||||||
|
Logger::info(L"layout-hotkeys.json file is missing or malformed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const winrt::hresult_error& e)
|
||||||
|
{
|
||||||
|
Logger::error(L"Parsing layout-hotkeys error: {}", e.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<GUID> LayoutHotkeys::GetLayoutId(int key) const noexcept
|
||||||
|
{
|
||||||
|
auto iter = m_hotkeyMap.find(key);
|
||||||
|
if (iter != m_hotkeyMap.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t LayoutHotkeys::GetHotkeysCount() const noexcept
|
||||||
|
{
|
||||||
|
return m_hotkeyMap.size();
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <guiddef.h>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/ModuleConstants.h>
|
||||||
|
|
||||||
|
#include <common/SettingsAPI/FileWatcher.h>
|
||||||
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
|
|
||||||
|
namespace NonLocalizable
|
||||||
|
{
|
||||||
|
namespace LayoutHotkeysIds
|
||||||
|
{
|
||||||
|
const static wchar_t* LayoutHotkeysArrayID = L"layout-hotkeys";
|
||||||
|
const static wchar_t* LayoutUuidID = L"layout-id";
|
||||||
|
const static wchar_t* KeyID = L"key";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LayoutHotkeys
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using THotkeyMap = std::map<int, GUID>;
|
||||||
|
|
||||||
|
static LayoutHotkeys& instance();
|
||||||
|
|
||||||
|
inline static std::wstring LayoutHotkeysFileName()
|
||||||
|
{
|
||||||
|
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::ModuleKey);
|
||||||
|
#if defined(UNIT_TESTS)
|
||||||
|
return saveFolderPath + L"\\test-layout-hotkeys.json";
|
||||||
|
#endif
|
||||||
|
return saveFolderPath + L"\\layout-hotkeys.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadData();
|
||||||
|
|
||||||
|
std::optional<GUID> GetLayoutId(int key) const noexcept;
|
||||||
|
size_t GetHotkeysCount() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayoutHotkeys();
|
||||||
|
~LayoutHotkeys() = default;
|
||||||
|
|
||||||
|
THotkeyMap m_hotkeyMap;
|
||||||
|
std::unique_ptr<FileWatcher> m_fileWatcher;
|
||||||
|
};
|
||||||
@@ -45,6 +45,8 @@
|
|||||||
<ClInclude Include="GuidUtils.h" />
|
<ClInclude Include="GuidUtils.h" />
|
||||||
<ClInclude Include="JsonHelpers.h" />
|
<ClInclude Include="JsonHelpers.h" />
|
||||||
<ClInclude Include="KeyState.h" />
|
<ClInclude Include="KeyState.h" />
|
||||||
|
<ClInclude Include="FancyZonesData\LayoutHotkeys.h" />
|
||||||
|
<ClInclude Include="ModuleConstants.h" />
|
||||||
<ClInclude Include="MonitorUtils.h" />
|
<ClInclude Include="MonitorUtils.h" />
|
||||||
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
@@ -69,6 +71,7 @@
|
|||||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
|
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
|
||||||
<ClCompile Include="FancyZonesData.cpp" />
|
<ClCompile Include="FancyZonesData.cpp" />
|
||||||
<ClCompile Include="JsonHelpers.cpp" />
|
<ClCompile Include="JsonHelpers.cpp" />
|
||||||
|
<ClCompile Include="FancyZonesData\LayoutHotkeys.cpp" />
|
||||||
<ClCompile Include="MonitorUtils.cpp" />
|
<ClCompile Include="MonitorUtils.cpp" />
|
||||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||||
<ClCompile Include="OnThreadExecutor.cpp" />
|
<ClCompile Include="OnThreadExecutor.cpp" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
<Filter Include="Source Files">
|
||||||
@@ -90,6 +90,12 @@
|
|||||||
<ClInclude Include="GuidUtils.h">
|
<ClInclude Include="GuidUtils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FancyZonesData\LayoutHotkeys.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ModuleConstants.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
@@ -149,6 +155,9 @@
|
|||||||
<ClCompile Include="MonitorUtils.cpp">
|
<ClCompile Include="MonitorUtils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FancyZonesData\LayoutHotkeys.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ UINT WM_PRIV_VD_SWITCH;
|
|||||||
UINT WM_PRIV_VD_UPDATE;
|
UINT WM_PRIV_VD_UPDATE;
|
||||||
UINT WM_PRIV_EDITOR;
|
UINT WM_PRIV_EDITOR;
|
||||||
UINT WM_PRIV_FILE_UPDATE;
|
UINT WM_PRIV_FILE_UPDATE;
|
||||||
|
UINT WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE;
|
||||||
UINT WM_PRIV_SNAP_HOTKEY;
|
UINT WM_PRIV_SNAP_HOTKEY;
|
||||||
UINT WM_PRIV_QUICK_LAYOUT_KEY;
|
UINT WM_PRIV_QUICK_LAYOUT_KEY;
|
||||||
UINT WM_PRIV_SETTINGS_CHANGED;
|
UINT WM_PRIV_SETTINGS_CHANGED;
|
||||||
@@ -31,6 +32,7 @@ void InitializeWinhookEventIds()
|
|||||||
WM_PRIV_VD_UPDATE = RegisterWindowMessage(L"{b8b72b46-f42f-4c26-9e20-29336cf2f22e}");
|
WM_PRIV_VD_UPDATE = RegisterWindowMessage(L"{b8b72b46-f42f-4c26-9e20-29336cf2f22e}");
|
||||||
WM_PRIV_EDITOR = RegisterWindowMessage(L"{87543824-7080-4e91-9d9c-0404642fc7b6}");
|
WM_PRIV_EDITOR = RegisterWindowMessage(L"{87543824-7080-4e91-9d9c-0404642fc7b6}");
|
||||||
WM_PRIV_FILE_UPDATE = RegisterWindowMessage(L"{632f17a9-55a7-45f1-a4db-162e39271d92}");
|
WM_PRIV_FILE_UPDATE = RegisterWindowMessage(L"{632f17a9-55a7-45f1-a4db-162e39271d92}");
|
||||||
|
WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE = RegisterWindowMessage(L"{07229b7e-4f22-4357-b136-33c289be2295}");
|
||||||
WM_PRIV_SNAP_HOTKEY = RegisterWindowMessage(L"{72f4fd8e-23f1-43ab-bbbc-029363df9a84}");
|
WM_PRIV_SNAP_HOTKEY = RegisterWindowMessage(L"{72f4fd8e-23f1-43ab-bbbc-029363df9a84}");
|
||||||
WM_PRIV_QUICK_LAYOUT_KEY = RegisterWindowMessage(L"{15baab3d-c67b-4a15-aFF0-13610e05e947}");
|
WM_PRIV_QUICK_LAYOUT_KEY = RegisterWindowMessage(L"{15baab3d-c67b-4a15-aFF0-13610e05e947}");
|
||||||
WM_PRIV_SETTINGS_CHANGED = RegisterWindowMessage(L"{89ca3Daa-bf2d-4e73-9f3f-c60716364e27}");
|
WM_PRIV_SETTINGS_CHANGED = RegisterWindowMessage(L"{89ca3Daa-bf2d-4e73-9f3f-c60716364e27}");
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ extern UINT WM_PRIV_VD_INIT; // Scheduled when FancyZones is initialized
|
|||||||
extern UINT WM_PRIV_VD_SWITCH; // Scheduled when virtual desktop switch occurs
|
extern UINT WM_PRIV_VD_SWITCH; // Scheduled when virtual desktop switch occurs
|
||||||
extern UINT WM_PRIV_VD_UPDATE; // Scheduled on virtual desktops update (creation/deletion)
|
extern UINT WM_PRIV_VD_UPDATE; // Scheduled on virtual desktops update (creation/deletion)
|
||||||
extern UINT WM_PRIV_EDITOR; // Scheduled when the editor exits
|
extern UINT WM_PRIV_EDITOR; // Scheduled when the editor exits
|
||||||
extern UINT WM_PRIV_FILE_UPDATE; // Scheduled when the a watched zone-settings file is updated
|
extern UINT WM_PRIV_FILE_UPDATE; // Scheduled when the watched zone-settings file is updated
|
||||||
|
extern UINT WM_PRIV_LAYOUT_HOTKEYS_FILE_UPDATE; // Scheduled when the watched layout-hotkeys.json file is updated
|
||||||
extern UINT WM_PRIV_SNAP_HOTKEY; // Scheduled when we receive a snap hotkey key down press
|
extern UINT WM_PRIV_SNAP_HOTKEY; // Scheduled when we receive a snap hotkey key down press
|
||||||
extern UINT WM_PRIV_QUICK_LAYOUT_KEY; // Scheduled when we receive a key down press to quickly apply a layout
|
extern UINT WM_PRIV_QUICK_LAYOUT_KEY; // Scheduled when we receive a key down press to quickly apply a layout
|
||||||
extern UINT WM_PRIV_SETTINGS_CHANGED; // Scheduled when the a watched settings file is updated
|
extern UINT WM_PRIV_SETTINGS_CHANGED; // Scheduled when the a watched settings file is updated
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||||
|
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -576,7 +578,7 @@ namespace JSONHelpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveZoneSettings(const std::wstring& zonesSettingsFileName, const TDeviceInfoMap& deviceInfoMap, const TCustomZoneSetsMap& customZoneSetsMap, const TLayoutQuickKeysMap& quickKeysMap)
|
void SaveZoneSettings(const std::wstring& zonesSettingsFileName, const TDeviceInfoMap& deviceInfoMap, const TCustomZoneSetsMap& customZoneSetsMap)
|
||||||
{
|
{
|
||||||
auto before = json::from_file(zonesSettingsFileName);
|
auto before = json::from_file(zonesSettingsFileName);
|
||||||
|
|
||||||
@@ -598,7 +600,6 @@ namespace JSONHelpers
|
|||||||
root.SetNamedValue(NonLocalizable::DevicesStr, JSONHelpers::SerializeDeviceInfos(deviceInfoMap));
|
root.SetNamedValue(NonLocalizable::DevicesStr, JSONHelpers::SerializeDeviceInfos(deviceInfoMap));
|
||||||
root.SetNamedValue(NonLocalizable::CustomZoneSetsStr, JSONHelpers::SerializeCustomZoneSets(customZoneSetsMap));
|
root.SetNamedValue(NonLocalizable::CustomZoneSetsStr, JSONHelpers::SerializeCustomZoneSets(customZoneSetsMap));
|
||||||
root.SetNamedValue(NonLocalizable::Templates, templates);
|
root.SetNamedValue(NonLocalizable::Templates, templates);
|
||||||
root.SetNamedValue(NonLocalizable::QuickLayoutKeys, JSONHelpers::SerializeQuickKeys(quickKeysMap));
|
|
||||||
|
|
||||||
if (!before.has_value() || before.value().Stringify() != root.Stringify())
|
if (!before.has_value() || before.value().Stringify() != root.Stringify())
|
||||||
{
|
{
|
||||||
@@ -726,7 +727,7 @@ namespace JSONHelpers
|
|||||||
return customZoneSetsJSON;
|
return customZoneSetsJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
TLayoutQuickKeysMap ParseQuickKeys(const json::JsonObject& fancyZonesDataJSON)
|
std::optional<TLayoutQuickKeysMap> ParseQuickKeys(const json::JsonObject& fancyZonesDataJSON)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -746,19 +747,26 @@ namespace JSONHelpers
|
|||||||
catch (const winrt::hresult_error& e)
|
catch (const winrt::hresult_error& e)
|
||||||
{
|
{
|
||||||
Logger::error(L"Parsing quick keys error: {}", e.message());
|
Logger::error(L"Parsing quick keys error: {}", e.message());
|
||||||
return {};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
json::JsonArray SerializeQuickKeys(const TLayoutQuickKeysMap& quickKeysMap)
|
void SaveLayoutHotkeys(const TLayoutQuickKeysMap& quickKeysMap)
|
||||||
{
|
{
|
||||||
json::JsonArray quickKeysJSON{};
|
json::JsonObject root{};
|
||||||
|
json::JsonArray keysArray{};
|
||||||
|
|
||||||
for (const auto& [uuid, key] : quickKeysMap)
|
for (const auto& [uuid, key] : quickKeysMap)
|
||||||
{
|
{
|
||||||
quickKeysJSON.Append(LayoutQuickKeyJSON::ToJson(LayoutQuickKeyJSON{ uuid, key }));
|
json::JsonObject keyJson{};
|
||||||
|
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutUuidID, json::value(uuid));
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::KeyID, json::value(key));
|
||||||
|
|
||||||
|
keysArray.Append(keyJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return quickKeysJSON;
|
root.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutHotkeysArrayID, keysArray);
|
||||||
|
json::to_file(LayoutHotkeys::LayoutHotkeysFileName(), root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ namespace JSONHelpers
|
|||||||
|
|
||||||
json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName);
|
json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName);
|
||||||
|
|
||||||
void SaveZoneSettings(const std::wstring& zonesSettingsFileName, const TDeviceInfoMap& deviceInfoMap, const TCustomZoneSetsMap& customZoneSetsMap, const TLayoutQuickKeysMap& quickKeysMap);
|
void SaveZoneSettings(const std::wstring& zonesSettingsFileName, const TDeviceInfoMap& deviceInfoMap, const TCustomZoneSetsMap& customZoneSetsMap);
|
||||||
void SaveAppZoneHistory(const std::wstring& appZoneHistoryFileName, const TAppZoneHistoryMap& appZoneHistoryMap);
|
void SaveAppZoneHistory(const std::wstring& appZoneHistoryFileName, const TAppZoneHistoryMap& appZoneHistoryMap);
|
||||||
|
|
||||||
TAppZoneHistoryMap ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON);
|
TAppZoneHistoryMap ParseAppZoneHistory(const json::JsonObject& fancyZonesDataJSON);
|
||||||
@@ -105,6 +105,7 @@ namespace JSONHelpers
|
|||||||
TCustomZoneSetsMap ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON);
|
TCustomZoneSetsMap ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON);
|
||||||
json::JsonArray SerializeCustomZoneSets(const TCustomZoneSetsMap& customZoneSetsMap);
|
json::JsonArray SerializeCustomZoneSets(const TCustomZoneSetsMap& customZoneSetsMap);
|
||||||
|
|
||||||
TLayoutQuickKeysMap ParseQuickKeys(const json::JsonObject& fancyZonesDataJSON);
|
// replace zone-settings: layout hotkeys
|
||||||
json::JsonArray SerializeQuickKeys(const TLayoutQuickKeysMap& quickKeysMap);
|
std::optional<TLayoutQuickKeysMap> ParseQuickKeys(const json::JsonObject& fancyZonesDataJSON);
|
||||||
|
void SaveLayoutHotkeys(const TLayoutQuickKeysMap& quickKeysMap);
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/modules/fancyzones/FancyZonesLib/ModuleConstants.h
Normal file
6
src/modules/fancyzones/FancyZonesLib/ModuleConstants.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace NonLocalizable
|
||||||
|
{
|
||||||
|
const inline wchar_t ModuleKey[] = L"FancyZones";
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "FancyZonesLib/ZoneSet.h"
|
#include "FancyZonesLib/ZoneSet.h"
|
||||||
#include "FancyZonesLib/Settings.h"
|
#include "FancyZonesLib/Settings.h"
|
||||||
#include "FancyZonesLib/FancyZonesData.h"
|
#include "FancyZonesLib/FancyZonesData.h"
|
||||||
|
#include "FancyZonesLib/FancyZonesData/LayoutHotkeys.h"
|
||||||
#include "FancyZonesLib/FancyZonesDataTypes.h"
|
#include "FancyZonesLib/FancyZonesDataTypes.h"
|
||||||
|
|
||||||
// Telemetry strings should not be localized.
|
// Telemetry strings should not be localized.
|
||||||
@@ -145,7 +146,7 @@ void Trace::FancyZones::DataChanged() noexcept
|
|||||||
int appsHistorySize = static_cast<int>(data.GetAppZoneHistoryMap().size());
|
int appsHistorySize = static_cast<int>(data.GetAppZoneHistoryMap().size());
|
||||||
const auto& customZones = data.GetCustomZoneSetsMap();
|
const auto& customZones = data.GetCustomZoneSetsMap();
|
||||||
const auto& devices = data.GetDeviceInfoMap();
|
const auto& devices = data.GetDeviceInfoMap();
|
||||||
const auto& quickKeys = data.GetLayoutQuickKeys();
|
auto quickKeysCount = LayoutHotkeys::instance().GetHotkeysCount();
|
||||||
|
|
||||||
std::unique_ptr<INT32[]> customZonesArray(new (std::nothrow) INT32[customZones.size()]);
|
std::unique_ptr<INT32[]> customZonesArray(new (std::nothrow) INT32[customZones.size()]);
|
||||||
if (!customZonesArray)
|
if (!customZonesArray)
|
||||||
@@ -220,7 +221,7 @@ void Trace::FancyZones::DataChanged() noexcept
|
|||||||
TraceLoggingInt32Array(customZonesArray.get(), static_cast<int>(customZones.size()), NumberOfZonesForEachCustomZoneSetKey),
|
TraceLoggingInt32Array(customZonesArray.get(), static_cast<int>(customZones.size()), NumberOfZonesForEachCustomZoneSetKey),
|
||||||
TraceLoggingInt32(static_cast<int>(devices.size()), ActiveZoneSetsCountKey),
|
TraceLoggingInt32(static_cast<int>(devices.size()), ActiveZoneSetsCountKey),
|
||||||
TraceLoggingWideString(activeZoneSetInfo.c_str(), ActiveZoneSetsListKey),
|
TraceLoggingWideString(activeZoneSetInfo.c_str(), ActiveZoneSetsListKey),
|
||||||
TraceLoggingInt32(static_cast<int>(quickKeys.size()), LayoutUsingQuickKeyCountKey));
|
TraceLoggingInt32(static_cast<int>(quickKeysCount), LayoutUsingQuickKeyCountKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::FancyZones::EditorLaunched(int value) noexcept
|
void Trace::FancyZones::EditorLaunched(int value) noexcept
|
||||||
|
|||||||
@@ -550,6 +550,17 @@ namespace FancyZonesUtils
|
|||||||
return SUCCEEDED(CLSIDFromString(str.c_str(), &id));
|
return SUCCEEDED(CLSIDFromString(str.c_str(), &id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<GUID> GuidFromString(const std::wstring& str) noexcept
|
||||||
|
{
|
||||||
|
GUID id;
|
||||||
|
if (SUCCEEDED(CLSIDFromString(str.c_str(), &id)))
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::wstring> GuidToString(const GUID& guid) noexcept
|
std::optional<std::wstring> GuidToString(const GUID& guid) noexcept
|
||||||
{
|
{
|
||||||
wil::unique_cotaskmem_string guidString;
|
wil::unique_cotaskmem_string guidString;
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace FancyZonesUtils
|
|||||||
void RestoreWindowOrigin(HWND window) noexcept;
|
void RestoreWindowOrigin(HWND window) noexcept;
|
||||||
|
|
||||||
bool IsValidGuid(const std::wstring& str);
|
bool IsValidGuid(const std::wstring& str);
|
||||||
|
std::optional<GUID> GuidFromString(const std::wstring& str) noexcept;
|
||||||
std::optional<std::wstring> GuidToString(const GUID& guid) noexcept;
|
std::optional<std::wstring> GuidToString(const GUID& guid) noexcept;
|
||||||
|
|
||||||
std::wstring GenerateUniqueId(HMONITOR monitor, const std::wstring& devideId, const std::wstring& virtualDesktopId);
|
std::wstring GenerateUniqueId(HMONITOR monitor, const std::wstring& devideId, const std::wstring& virtualDesktopId);
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
#include <common/utils/winapi_error.h>
|
#include <common/utils/winapi_error.h>
|
||||||
|
|
||||||
#include <FancyZonesLib/Generated Files/resource.h>
|
#include <FancyZonesLib/Generated Files/resource.h>
|
||||||
#include <FancyZonesLib/FancyZonesData.h>
|
|
||||||
#include <FancyZonesLib/trace.h>
|
#include <FancyZonesLib/trace.h>
|
||||||
#include <FancyZonesLib/Settings.h>
|
#include <FancyZonesLib/Settings.h>
|
||||||
|
#include <FancyZonesLib/ModuleConstants.h>
|
||||||
|
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
FancyZonesModuleInterface()
|
FancyZonesModuleInterface()
|
||||||
{
|
{
|
||||||
app_name = GET_RESOURCE_STRING(IDS_FANCYZONES);
|
app_name = GET_RESOURCE_STRING(IDS_FANCYZONES);
|
||||||
app_key = NonLocalizable::FancyZonesStr;
|
app_key = NonLocalizable::ModuleKey;
|
||||||
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), FancyZonesModuleInterface::get_name(), FancyZonesModuleInterface::get_key());
|
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), FancyZonesModuleInterface::get_name(), FancyZonesModuleInterface::get_key());
|
||||||
|
|
||||||
m_toggleEditorEvent = CreateDefaultEvent(CommonSharedConstants::FANCY_ZONES_EDITOR_TOGGLE_EVENT);
|
m_toggleEditorEvent = CreateDefaultEvent(CommonSharedConstants::FANCY_ZONES_EDITOR_TOGGLE_EVENT);
|
||||||
|
|||||||
@@ -1556,73 +1556,6 @@ namespace FancyZonesUnitTests
|
|||||||
auto actual = SerializeCustomZoneSets(customZoneSetsMap);
|
auto actual = SerializeCustomZoneSets(customZoneSetsMap);
|
||||||
compareJsonArrays(expected, actual);
|
compareJsonArrays(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(QuickLayoutKeysParse)
|
|
||||||
{
|
|
||||||
const std::wstring zoneUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}";
|
|
||||||
LayoutQuickKeyJSON expected{ zoneUuid, 2 };
|
|
||||||
json::JsonArray array;
|
|
||||||
array.Append(LayoutQuickKeyJSON::ToJson(expected));
|
|
||||||
|
|
||||||
json::JsonObject json;
|
|
||||||
json.SetNamedValue(L"quick-layout-keys", json::JsonValue::Parse(array.Stringify()));
|
|
||||||
|
|
||||||
const auto& quickKeysMap = ParseQuickKeys(json);
|
|
||||||
|
|
||||||
Assert::AreEqual((size_t)array.Size(), quickKeysMap.size());
|
|
||||||
|
|
||||||
Assert::IsTrue(quickKeysMap.find(zoneUuid) != quickKeysMap.end());
|
|
||||||
int actualKey = quickKeysMap.find(zoneUuid)->second;
|
|
||||||
Assert::AreEqual((int)expected.key, actualKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (QuickLayoutKeysParseEmpty)
|
|
||||||
{
|
|
||||||
json::JsonArray array;
|
|
||||||
json::JsonObject json;
|
|
||||||
json.SetNamedValue(L"quick-layout-keys", json::JsonValue::Parse(array.Stringify()));
|
|
||||||
|
|
||||||
const auto& quickKeysMap = ParseQuickKeys(json);
|
|
||||||
|
|
||||||
Assert::IsTrue(quickKeysMap.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (QuickLayoutKeysParseInvalid)
|
|
||||||
{
|
|
||||||
const std::wstring invalidZoneUuid = L"{33A2B101-06E0-437B-}";
|
|
||||||
LayoutQuickKeyJSON expected{ invalidZoneUuid, 2 };
|
|
||||||
json::JsonArray array;
|
|
||||||
array.Append(LayoutQuickKeyJSON::ToJson(expected));
|
|
||||||
|
|
||||||
json::JsonObject json;
|
|
||||||
json.SetNamedValue(L"quick-layout-keys", json::JsonValue::Parse(array.Stringify()));
|
|
||||||
|
|
||||||
const auto& quickKeysMap = ParseQuickKeys(json);
|
|
||||||
|
|
||||||
Assert::IsTrue(quickKeysMap.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (QuickLayoutKeysParseMissed)
|
|
||||||
{
|
|
||||||
json::JsonObject json;
|
|
||||||
|
|
||||||
const auto& quickKeysMap = ParseQuickKeys(json);
|
|
||||||
|
|
||||||
Assert::IsTrue(quickKeysMap.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (QuickLayoutKeysSerialize)
|
|
||||||
{
|
|
||||||
json::JsonArray expected;
|
|
||||||
expected.Append(LayoutQuickKeyJSON::ToJson(LayoutQuickKeyJSON{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", 3}));
|
|
||||||
json::JsonObject json;
|
|
||||||
json.SetNamedValue(L"quick-layout-keys", json::JsonValue::Parse(expected.Stringify()));
|
|
||||||
|
|
||||||
const auto& quickKeysMap = ParseQuickKeys(json);
|
|
||||||
|
|
||||||
auto actual = SerializeQuickKeys(quickKeysMap);
|
|
||||||
compareJsonArrays(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (SetActiveZoneSet)
|
TEST_METHOD (SetActiveZoneSet)
|
||||||
{
|
{
|
||||||
@@ -1754,7 +1687,6 @@ namespace FancyZonesUnitTests
|
|||||||
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
||||||
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
||||||
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
Assert::IsFalse(fancyZonesData.GetCustomZoneSetsMap().empty());
|
||||||
Assert::IsFalse(fancyZonesData.GetLayoutQuickKeys().empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (LoadFancyZonesDataFromCroppedJson)
|
TEST_METHOD (LoadFancyZonesDataFromCroppedJson)
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||||
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace FancyZonesUnitTests
|
||||||
|
{
|
||||||
|
TEST_CLASS (LayoutHotkeysUnitTests)
|
||||||
|
{
|
||||||
|
FancyZonesData& m_fzData = FancyZonesDataInstance();
|
||||||
|
std::wstring m_testFolder = L"FancyZonesUnitTests";
|
||||||
|
|
||||||
|
TEST_METHOD_INITIALIZE(Init)
|
||||||
|
{
|
||||||
|
m_fzData.clear_data();
|
||||||
|
m_fzData.SetSettingsModulePath(L"FancyZonesUnitTests");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD_CLEANUP(CleanUp)
|
||||||
|
{
|
||||||
|
std::filesystem::remove_all(LayoutHotkeys::LayoutHotkeysFileName());
|
||||||
|
std::filesystem::remove_all(PTSettingsHelper::get_module_save_folder_location(m_testFolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (LayoutHotkeysParse)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray keysArray{};
|
||||||
|
|
||||||
|
{
|
||||||
|
json::JsonObject keyJson{};
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutUuidID, json::value(L"{33A2B101-06E0-437B-A61E-CDBECF502906}"));
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::KeyID, json::value(1));
|
||||||
|
|
||||||
|
keysArray.Append(keyJson);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
json::JsonObject keyJson{};
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutUuidID, json::value(L"{33A2B101-06E0-437B-A61E-CDBECF502907}"));
|
||||||
|
keyJson.SetNamedValue(NonLocalizable::LayoutHotkeysIds::KeyID, json::value(2));
|
||||||
|
|
||||||
|
keysArray.Append(keyJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
root.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutHotkeysArrayID, keysArray);
|
||||||
|
json::to_file(LayoutHotkeys::LayoutHotkeysFileName(), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)2, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
Assert::AreEqual(L"{33A2B101-06E0-437B-A61E-CDBECF502906}", FancyZonesUtils::GuidToString(LayoutHotkeys::instance().GetLayoutId(1).value()).value().c_str());
|
||||||
|
Assert::AreEqual(L"{33A2B101-06E0-437B-A61E-CDBECF502907}", FancyZonesUtils::GuidToString(LayoutHotkeys::instance().GetLayoutId(2).value()).value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (LayoutHotkeysParseEmpty)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray keysArray{};
|
||||||
|
root.SetNamedValue(NonLocalizable::LayoutHotkeysIds::LayoutHotkeysArrayID, keysArray);
|
||||||
|
json::to_file(LayoutHotkeys::LayoutHotkeysFileName(), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)0, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (LayoutHotkeysNoFile)
|
||||||
|
{
|
||||||
|
// test
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)0, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (MoveLayoutHotkeysFromZonesSettings)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray devicesArray{}, customLayoutsArray{}, templateLayoutsArray{}, quickLayoutKeysArray{};
|
||||||
|
root.SetNamedValue(L"devices", devicesArray);
|
||||||
|
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||||
|
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||||
|
json::JsonObject layoutKeyObj{};
|
||||||
|
layoutKeyObj.SetNamedValue(L"uuid", json::value(L"{BF7DD882-AB90-4AB8-88A0-96CCFCEC538C}"));
|
||||||
|
layoutKeyObj.SetNamedValue(L"key", json::value(1));
|
||||||
|
quickLayoutKeysArray.Append(layoutKeyObj);
|
||||||
|
root.SetNamedValue(L"quick-layout-keys", quickLayoutKeysArray);
|
||||||
|
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)1, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
Assert::AreEqual(L"{BF7DD882-AB90-4AB8-88A0-96CCFCEC538C}", FancyZonesUtils::GuidToString(LayoutHotkeys::instance().GetLayoutId(1).value()).value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (MoveLayoutHotkeysFromZonesSettingsNoQuickLayoutKeys)
|
||||||
|
{
|
||||||
|
// prepare
|
||||||
|
json::JsonObject root{};
|
||||||
|
json::JsonArray devicesArray{}, customLayoutsArray{}, templateLayoutsArray{};
|
||||||
|
root.SetNamedValue(L"devices", devicesArray);
|
||||||
|
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||||
|
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||||
|
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||||
|
|
||||||
|
// test
|
||||||
|
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)0, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (MoveLayoutHotkeysFromZonesSettingsNoFile)
|
||||||
|
{
|
||||||
|
// test
|
||||||
|
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||||
|
LayoutHotkeys::instance().LoadData();
|
||||||
|
Assert::AreEqual((size_t)0, LayoutHotkeys::instance().GetHotkeysCount());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
<ClCompile Include="FancyZones.Spec.cpp" />
|
<ClCompile Include="FancyZones.Spec.cpp" />
|
||||||
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
|
||||||
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
<ClCompile Include="JsonHelpers.Tests.cpp" />
|
||||||
|
<ClCompile Include="LayoutHotkeysTests.Spec.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -42,6 +42,9 @@
|
|||||||
<ClCompile Include="WorkArea.Spec.cpp">
|
<ClCompile Include="WorkArea.Spec.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="LayoutHotkeysTests.Spec.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pch.h">
|
<ClInclude Include="pch.h">
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using System.Runtime.CompilerServices;
|
|||||||
|
|
||||||
namespace FancyZonesEditor.Models
|
namespace FancyZonesEditor.Models
|
||||||
{
|
{
|
||||||
public class QuickKeysModel : INotifyPropertyChanged
|
public class LayoutHotkeysModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
public SortedDictionary<string, string> SelectedKeys { get; } = new SortedDictionary<string, string>()
|
public SortedDictionary<string, string> SelectedKeys { get; } = new SortedDictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@ namespace FancyZonesEditor.Models
|
|||||||
{ "9", string.Empty },
|
{ "9", string.Empty },
|
||||||
};
|
};
|
||||||
|
|
||||||
public QuickKeysModel()
|
public LayoutHotkeysModel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ namespace FancyZonesEditor.Models
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
List<string> result = new List<string>();
|
List<string> result = new List<string>();
|
||||||
foreach (var pair in MainWindowSettingsModel.QuickKeys.SelectedKeys)
|
foreach (var pair in MainWindowSettingsModel.LayoutHotkeys.SelectedKeys)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(pair.Value) || pair.Value == Uuid)
|
if (string.IsNullOrEmpty(pair.Value) || pair.Value == Uuid)
|
||||||
{
|
{
|
||||||
@@ -195,11 +195,11 @@ namespace FancyZonesEditor.Models
|
|||||||
|
|
||||||
if (intValue != -1)
|
if (intValue != -1)
|
||||||
{
|
{
|
||||||
MainWindowSettingsModel.QuickKeys.SelectKey(value, Uuid);
|
MainWindowSettingsModel.LayoutHotkeys.SelectKey(value, Uuid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainWindowSettingsModel.QuickKeys.FreeKey(prev);
|
MainWindowSettingsModel.LayoutHotkeys.FreeKey(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
FirePropertyChanged(nameof(QuickKey));
|
FirePropertyChanged(nameof(QuickKey));
|
||||||
@@ -253,7 +253,7 @@ namespace FancyZonesEditor.Models
|
|||||||
{
|
{
|
||||||
if (_quickKey != -1)
|
if (_quickKey != -1)
|
||||||
{
|
{
|
||||||
MainWindowSettingsModel.QuickKeys.FreeKey(QuickKey);
|
MainWindowSettingsModel.LayoutHotkeys.FreeKey(QuickKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
var customModels = MainWindowSettingsModel.CustomModels;
|
var customModels = MainWindowSettingsModel.CustomModels;
|
||||||
@@ -298,9 +298,9 @@ namespace FancyZonesEditor.Models
|
|||||||
PersistData();
|
PersistData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QuickSwitchKeys_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
public void LayoutHotkeys_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
foreach (var pair in MainWindowSettingsModel.QuickKeys.SelectedKeys)
|
foreach (var pair in MainWindowSettingsModel.LayoutHotkeys.SelectedKeys)
|
||||||
{
|
{
|
||||||
if (pair.Value == Uuid)
|
if (pair.Value == Uuid)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace FancyZonesEditor
|
|||||||
{
|
{
|
||||||
foreach (LayoutModel model in _customModels)
|
foreach (LayoutModel model in _customModels)
|
||||||
{
|
{
|
||||||
QuickKeys.PropertyChanged -= model.QuickSwitchKeys_PropertyChanged;
|
LayoutHotkeys.PropertyChanged -= model.LayoutHotkeys_PropertyChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
_customModels.Clear();
|
_customModels.Clear();
|
||||||
@@ -151,7 +151,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
foreach (LayoutModel model in _customModels)
|
foreach (LayoutModel model in _customModels)
|
||||||
{
|
{
|
||||||
QuickKeys.PropertyChanged += model.QuickSwitchKeys_PropertyChanged;
|
LayoutHotkeys.PropertyChanged += model.LayoutHotkeys_PropertyChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ namespace FancyZonesEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QuickKeysModel QuickKeys { get; } = new QuickKeysModel();
|
public static LayoutHotkeysModel LayoutHotkeys { get; } = new LayoutHotkeysModel();
|
||||||
|
|
||||||
public LayoutModel SelectedModel
|
public LayoutModel SelectedModel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -384,6 +384,15 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to An error occurred while parsing layout hotkeys..
|
||||||
|
/// </summary>
|
||||||
|
public static string Error_Parsing_Layout_Hotkeys_Message {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Error_Parsing_Layout_Hotkeys_Message", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to A layout that contained invalid data has been removed..
|
/// Looks up a localized string similar to A layout that contained invalid data has been removed..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -394,7 +403,7 @@ namespace FancyZonesEditor.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Editor settings parsing error..
|
/// Looks up a localized string similar to Editor data parsing error..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string Error_Parsing_Zones_Settings_Title {
|
public static string Error_Parsing_Zones_Settings_Title {
|
||||||
get {
|
get {
|
||||||
|
|||||||
@@ -305,7 +305,7 @@
|
|||||||
<comment>A tooltip on a button that allows the user to delete a zone</comment>
|
<comment>A tooltip on a button that allows the user to delete a zone</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error_Parsing_Zones_Settings_Title" xml:space="preserve">
|
<data name="Error_Parsing_Zones_Settings_Title" xml:space="preserve">
|
||||||
<value>Editor settings parsing error.</value>
|
<value>Editor data parsing error.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error_Parsing_Zones_Settings_Message" xml:space="preserve">
|
<data name="Error_Parsing_Zones_Settings_Message" xml:space="preserve">
|
||||||
<value>A layout that contained invalid data has been removed.</value>
|
<value>A layout that contained invalid data has been removed.</value>
|
||||||
@@ -383,4 +383,7 @@
|
|||||||
<data name="OpenSettings" xml:space="preserve">
|
<data name="OpenSettings" xml:space="preserve">
|
||||||
<value>Open settings</value>
|
<value>Open settings</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error_Parsing_Layout_Hotkeys_Message" xml:space="preserve">
|
||||||
|
<value>An error occurred while parsing layout hotkeys.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -29,6 +29,7 @@ namespace FancyZonesEditor.Utils
|
|||||||
|
|
||||||
// Non-localizable strings: Files
|
// Non-localizable strings: Files
|
||||||
private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json";
|
private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json";
|
||||||
|
private const string LayoutHotkeysFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-hotkeys.json";
|
||||||
private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
|
private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
|
||||||
|
|
||||||
// Non-localizable string: Multi-monitor id
|
// Non-localizable string: Multi-monitor id
|
||||||
@@ -49,6 +50,8 @@ namespace FancyZonesEditor.Utils
|
|||||||
|
|
||||||
public string FancyZonesSettingsFile { get; private set; }
|
public string FancyZonesSettingsFile { get; private set; }
|
||||||
|
|
||||||
|
public string FancyZonesLayoutHotkeysFile { get; private set; }
|
||||||
|
|
||||||
public string FancyZonesEditorParamsFile { get; private set; }
|
public string FancyZonesEditorParamsFile { get; private set; }
|
||||||
|
|
||||||
private enum CmdArgs
|
private enum CmdArgs
|
||||||
@@ -193,12 +196,18 @@ namespace FancyZonesEditor.Utils
|
|||||||
public int SensitivityRadius { get; set; }
|
public int SensitivityRadius { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// zones-settings: quick-layout-keys-wrapper
|
// layout-hotkeys: layout-hotkeys-wrapper
|
||||||
private struct QuickLayoutKeysWrapper
|
private struct LayoutHotkeyWrapper
|
||||||
{
|
{
|
||||||
public int Key { get; set; }
|
public int Key { get; set; }
|
||||||
|
|
||||||
public string Uuid { get; set; }
|
public string LayoutId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// layout-hotkeys: layout-hotkeys-wrapper
|
||||||
|
private struct LayoutHotkeysWrapper
|
||||||
|
{
|
||||||
|
public List<LayoutHotkeyWrapper> LayoutHotkeys { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// zones-settings
|
// zones-settings
|
||||||
@@ -209,8 +218,6 @@ namespace FancyZonesEditor.Utils
|
|||||||
public List<CustomLayoutWrapper> CustomZoneSets { get; set; }
|
public List<CustomLayoutWrapper> CustomZoneSets { get; set; }
|
||||||
|
|
||||||
public List<TemplateLayoutWrapper> Templates { get; set; }
|
public List<TemplateLayoutWrapper> Templates { get; set; }
|
||||||
|
|
||||||
public List<QuickLayoutKeysWrapper> QuickLayoutKeys { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct EditorParams
|
private struct EditorParams
|
||||||
@@ -242,6 +249,7 @@ namespace FancyZonesEditor.Utils
|
|||||||
{
|
{
|
||||||
var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
FancyZonesSettingsFile = localAppDataDir + ZonesSettingsFile;
|
FancyZonesSettingsFile = localAppDataDir + ZonesSettingsFile;
|
||||||
|
FancyZonesLayoutHotkeysFile = localAppDataDir + LayoutHotkeysFile;
|
||||||
FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
|
FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +524,6 @@ namespace FancyZonesEditor.Utils
|
|||||||
bool devicesParsingResult = SetDevices(zoneSettings.Devices);
|
bool devicesParsingResult = SetDevices(zoneSettings.Devices);
|
||||||
bool customZonesParsingResult = SetCustomLayouts(zoneSettings.CustomZoneSets);
|
bool customZonesParsingResult = SetCustomLayouts(zoneSettings.CustomZoneSets);
|
||||||
bool templatesParsingResult = SetTemplateLayouts(zoneSettings.Templates);
|
bool templatesParsingResult = SetTemplateLayouts(zoneSettings.Templates);
|
||||||
bool quickLayoutSwitchKeysParsingResult = SetQuickLayoutSwitchKeys(zoneSettings.QuickLayoutKeys);
|
|
||||||
|
|
||||||
if (!devicesParsingResult || !customZonesParsingResult)
|
if (!devicesParsingResult || !customZonesParsingResult)
|
||||||
{
|
{
|
||||||
@@ -530,6 +537,51 @@ namespace FancyZonesEditor.Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parsingHotkeysResult = ParseLayoutHotkeys();
|
||||||
|
if (!parsingHotkeysResult.Result)
|
||||||
|
{
|
||||||
|
return parsingHotkeysResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ParsingResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsingResult ParseLayoutHotkeys()
|
||||||
|
{
|
||||||
|
Logger.LogTrace();
|
||||||
|
|
||||||
|
if (_fileSystem.File.Exists(FancyZonesLayoutHotkeysFile))
|
||||||
|
{
|
||||||
|
LayoutHotkeysWrapper layoutHotkeys;
|
||||||
|
string dataString = string.Empty;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dataString = ReadFile(FancyZonesLayoutHotkeysFile);
|
||||||
|
layoutHotkeys = JsonSerializer.Deserialize<LayoutHotkeysWrapper>(dataString, _options);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Layout hotkeys parsing error", ex);
|
||||||
|
return new ParsingResult(false, ex.Message, dataString);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool layoutHotkeysParsingResult = SetLayoutHotkeys(layoutHotkeys);
|
||||||
|
|
||||||
|
if (!layoutHotkeysParsingResult)
|
||||||
|
{
|
||||||
|
return new ParsingResult(false, FancyZonesEditor.Properties.Resources.Error_Parsing_Layout_Hotkeys_Message, dataString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Layout hotkeys parsing error", ex);
|
||||||
|
return new ParsingResult(false, ex.Message, dataString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new ParsingResult(true);
|
return new ParsingResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +593,6 @@ namespace FancyZonesEditor.Utils
|
|||||||
zoneSettings.Devices = new List<DeviceWrapper>();
|
zoneSettings.Devices = new List<DeviceWrapper>();
|
||||||
zoneSettings.CustomZoneSets = new List<CustomLayoutWrapper>();
|
zoneSettings.CustomZoneSets = new List<CustomLayoutWrapper>();
|
||||||
zoneSettings.Templates = new List<TemplateLayoutWrapper>();
|
zoneSettings.Templates = new List<TemplateLayoutWrapper>();
|
||||||
zoneSettings.QuickLayoutKeys = new List<QuickLayoutKeysWrapper>();
|
|
||||||
|
|
||||||
// Serialize used devices
|
// Serialize used devices
|
||||||
foreach (var monitor in App.Overlay.Monitors)
|
foreach (var monitor in App.Overlay.Monitors)
|
||||||
@@ -678,20 +729,38 @@ namespace FancyZonesEditor.Utils
|
|||||||
zoneSettings.Templates.Add(wrapper);
|
zoneSettings.Templates.Add(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize quick layout switch keys
|
try
|
||||||
foreach (var pair in MainWindowSettingsModel.QuickKeys.SelectedKeys)
|
{
|
||||||
|
string jsonString = JsonSerializer.Serialize(zoneSettings, _options);
|
||||||
|
_fileSystem.File.WriteAllText(FancyZonesSettingsFile, jsonString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("Serialize zone settings error", ex);
|
||||||
|
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeLayoutHotkeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeLayoutHotkeys()
|
||||||
|
{
|
||||||
|
LayoutHotkeysWrapper hotkeys = new LayoutHotkeysWrapper { };
|
||||||
|
hotkeys.LayoutHotkeys = new List<LayoutHotkeyWrapper>();
|
||||||
|
|
||||||
|
foreach (var pair in MainWindowSettingsModel.LayoutHotkeys.SelectedKeys)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(pair.Value))
|
if (!string.IsNullOrEmpty(pair.Value))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QuickLayoutKeysWrapper wrapper = new QuickLayoutKeysWrapper
|
LayoutHotkeyWrapper wrapper = new LayoutHotkeyWrapper
|
||||||
{
|
{
|
||||||
Key = int.Parse(pair.Key),
|
Key = int.Parse(pair.Key),
|
||||||
Uuid = pair.Value,
|
LayoutId = pair.Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
zoneSettings.QuickLayoutKeys.Add(wrapper);
|
hotkeys.LayoutHotkeys.Add(wrapper);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -702,12 +771,12 @@ namespace FancyZonesEditor.Utils
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string jsonString = JsonSerializer.Serialize(zoneSettings, _options);
|
string jsonString = JsonSerializer.Serialize(hotkeys, _options);
|
||||||
_fileSystem.File.WriteAllText(FancyZonesSettingsFile, jsonString);
|
_fileSystem.File.WriteAllText(FancyZonesLayoutHotkeysFile, jsonString);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.LogError("Serialize zone settings error", ex);
|
Logger.LogError("Serialize layout hotkeys error", ex);
|
||||||
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,19 +931,14 @@ namespace FancyZonesEditor.Utils
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SetQuickLayoutSwitchKeys(List<QuickLayoutKeysWrapper> quickSwitchKeys)
|
private bool SetLayoutHotkeys(LayoutHotkeysWrapper layoutHotkeys)
|
||||||
{
|
{
|
||||||
Logger.LogTrace();
|
Logger.LogTrace();
|
||||||
|
|
||||||
if (quickSwitchKeys == null)
|
MainWindowSettingsModel.LayoutHotkeys.CleanUp();
|
||||||
|
foreach (var wrapper in layoutHotkeys.LayoutHotkeys)
|
||||||
{
|
{
|
||||||
return false;
|
MainWindowSettingsModel.LayoutHotkeys.SelectKey(wrapper.Key.ToString(), wrapper.LayoutId);
|
||||||
}
|
|
||||||
|
|
||||||
MainWindowSettingsModel.QuickKeys.CleanUp();
|
|
||||||
foreach (var wrapper in quickSwitchKeys)
|
|
||||||
{
|
|
||||||
MainWindowSettingsModel.QuickKeys.SelectKey(wrapper.Key.ToString(), wrapper.Uuid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user