mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[FancyZones]Fix for the scenario of layout reset when opening the FZEditor (#28556)
* rename * moved applied layouts tests * changed work area id comparison * changed save * changed apply * changed clone * sync applied layouts * save last used vd * replace parent work area ids * proper time for sync * sync layouts considering last used virtual desktop * use ids from work areas on editor opening * update applied layouts tests * sync app zone history vd * fix test * release build fix * app zone history comparison * pass last used vd to sync * clean up unused * dpi unaware values * update GUID_NULL * use registry values only * added more tests * fix failing scenario * added replace condition to zone history * sync time * log * spellcheck * fix pch in project * fixed cloning layout
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <FancyZonesLib/on_thread_executor.h>
|
||||
#include <FancyZonesLib/Settings.h>
|
||||
#include <FancyZonesLib/VirtualDesktop.h>
|
||||
#include <FancyZonesLib/WorkArea.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
#include <common/Display/dpi_aware.h>
|
||||
@@ -36,6 +37,31 @@ namespace JsonUtils
|
||||
int monitorHeight{};
|
||||
bool isSelected = false;
|
||||
|
||||
bool FillFromWorkArea(const WorkArea* const workArea)
|
||||
{
|
||||
const auto virtualDesktopIdStr = FancyZonesUtils::GuidToString(workArea->UniqueId().virtualDesktopId);
|
||||
if (!virtualDesktopIdStr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& monitorId = workArea->UniqueId().monitorId;
|
||||
monitorName = monitorId.deviceId.id;
|
||||
monitorInstanceId = monitorId.deviceId.instanceId;
|
||||
monitorNumber = monitorId.deviceId.number;
|
||||
monitorSerialNumber = monitorId.serialNumber;
|
||||
|
||||
const auto& rect = workArea->GetWorkAreaRect();
|
||||
top = rect.top();
|
||||
left = rect.left();
|
||||
workAreaWidth = rect.width();
|
||||
workAreaHeight = rect.height();
|
||||
|
||||
virtualDesktop = virtualDesktopIdStr.value();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static json::JsonObject ToJson(const MonitorInfo& monitor)
|
||||
{
|
||||
json::JsonObject result{};
|
||||
@@ -84,21 +110,8 @@ namespace JsonUtils
|
||||
};
|
||||
}
|
||||
|
||||
bool EditorParameters::Save() noexcept
|
||||
bool EditorParameters::Save(const WorkAreaConfiguration& configuration, OnThreadExecutor& dpiUnawareThread) noexcept
|
||||
{
|
||||
const auto virtualDesktopIdStr = FancyZonesUtils::GuidToString(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||
if (!virtualDesktopIdStr)
|
||||
{
|
||||
Logger::error(L"Save editor params: invalid virtual desktop id");
|
||||
return false;
|
||||
}
|
||||
|
||||
OnThreadExecutor dpiUnawareThread;
|
||||
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [] {
|
||||
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
||||
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
||||
} }).wait();
|
||||
|
||||
const bool spanZonesAcrossMonitors = FancyZonesSettings::settings().spanZonesAcrossMonitors;
|
||||
|
||||
JsonUtils::EditorArgs argsJson;
|
||||
@@ -107,23 +120,31 @@ bool EditorParameters::Save() noexcept
|
||||
|
||||
if (spanZonesAcrossMonitors)
|
||||
{
|
||||
RECT combinedWorkArea;
|
||||
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [&]() {
|
||||
combinedWorkArea = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFOEX::rcWork>();
|
||||
|
||||
} }).wait();
|
||||
|
||||
RECT combinedMonitorArea = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFOEX::rcMonitor>();
|
||||
const auto& workArea = configuration.GetWorkArea(nullptr);
|
||||
if (!workArea)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonUtils::MonitorInfo monitorJson;
|
||||
monitorJson.monitorName = ZonedWindowProperties::MultiMonitorName;
|
||||
monitorJson.monitorInstanceId = ZonedWindowProperties::MultiMonitorInstance;
|
||||
monitorJson.monitorNumber = 0;
|
||||
monitorJson.virtualDesktop = virtualDesktopIdStr.value();
|
||||
if (!monitorJson.FillFromWorkArea(workArea))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RECT combinedWorkArea;
|
||||
dpiUnawareThread.submit(OnThreadExecutor::task_t{
|
||||
[&]() {
|
||||
combinedWorkArea = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFOEX::rcWork>();
|
||||
} }).wait();
|
||||
RECT combinedMonitorArea = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFOEX::rcMonitor>();
|
||||
|
||||
// use dpi-unaware values
|
||||
monitorJson.top = combinedWorkArea.top;
|
||||
monitorJson.left = combinedWorkArea.left;
|
||||
monitorJson.workAreaWidth = combinedWorkArea.right - combinedWorkArea.left;
|
||||
monitorJson.workAreaHeight = combinedWorkArea.bottom - combinedWorkArea.top;
|
||||
|
||||
monitorJson.monitorWidth = combinedMonitorArea.right - combinedMonitorArea.left;
|
||||
monitorJson.monitorHeight = combinedMonitorArea.bottom - combinedMonitorArea.top;
|
||||
monitorJson.isSelected = true;
|
||||
@@ -133,8 +154,6 @@ bool EditorParameters::Save() noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
auto monitors = MonitorUtils::IdentifyMonitors();
|
||||
|
||||
HMONITOR targetMonitor{};
|
||||
if (FancyZonesSettings::settings().use_cursorpos_editor_startupscreen)
|
||||
{
|
||||
@@ -153,9 +172,24 @@ bool EditorParameters::Save() noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& monitorData : monitors)
|
||||
const auto& config = configuration.GetAllWorkAreas();
|
||||
for (auto& [monitor, workArea] : config)
|
||||
{
|
||||
HMONITOR monitor = monitorData.monitor;
|
||||
JsonUtils::MonitorInfo monitorJson;
|
||||
if (!monitorJson.FillFromWorkArea(workArea.get()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
monitorJson.isSelected = monitor == targetMonitor; /* Is monitor selected for the main editor window opening */
|
||||
|
||||
UINT dpi = 0;
|
||||
if (DPIAware::GetScreenDPIForMonitor(monitor, dpi) != S_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
monitorJson.dpi = dpi;
|
||||
|
||||
MONITORINFOEX monitorInfo{};
|
||||
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [&] {
|
||||
@@ -166,31 +200,6 @@ bool EditorParameters::Save() noexcept
|
||||
}
|
||||
} }).wait();
|
||||
|
||||
JsonUtils::MonitorInfo monitorJson;
|
||||
|
||||
if (monitor == targetMonitor)
|
||||
{
|
||||
monitorJson.isSelected = true; /* Is monitor selected for the main editor window opening */
|
||||
}
|
||||
|
||||
monitorJson.monitorName = monitorData.deviceId.id;
|
||||
monitorJson.monitorInstanceId = monitorData.deviceId.instanceId;
|
||||
monitorJson.monitorNumber = monitorData.deviceId.number;
|
||||
monitorJson.monitorSerialNumber = monitorData.serialNumber;
|
||||
monitorJson.virtualDesktop = virtualDesktopIdStr.value();
|
||||
|
||||
UINT dpi = 0;
|
||||
if (DPIAware::GetScreenDPIForMonitor(monitor, dpi) != S_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
monitorJson.dpi = dpi;
|
||||
monitorJson.top = monitorInfo.rcWork.top;
|
||||
monitorJson.left = monitorInfo.rcWork.left;
|
||||
monitorJson.workAreaWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
|
||||
monitorJson.workAreaHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
|
||||
|
||||
float width = static_cast<float>(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left);
|
||||
float height = static_cast<float>(monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
|
||||
DPIAware::Convert(monitor, width, height);
|
||||
@@ -198,6 +207,12 @@ bool EditorParameters::Save() noexcept
|
||||
monitorJson.monitorWidth = static_cast<int>(std::roundf(width));
|
||||
monitorJson.monitorHeight = static_cast<int>(std::roundf(height));
|
||||
|
||||
// use dpi-unaware values
|
||||
monitorJson.top = monitorInfo.rcWork.top;
|
||||
monitorJson.left = monitorInfo.rcWork.left;
|
||||
monitorJson.workAreaWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
|
||||
monitorJson.workAreaHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
|
||||
|
||||
argsJson.monitors.emplace_back(std::move(monitorJson));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <FancyZonesLib/on_thread_executor.h>
|
||||
#include <FancyZonesLib/WorkAreaConfiguration.h>
|
||||
|
||||
namespace NonLocalizable
|
||||
{
|
||||
namespace EditorParametersIds
|
||||
@@ -26,5 +29,5 @@ namespace NonLocalizable
|
||||
class EditorParameters
|
||||
{
|
||||
public:
|
||||
static bool Save() noexcept;
|
||||
static bool Save(const WorkAreaConfiguration& configuration, OnThreadExecutor& dpiUnawareThread) noexcept;
|
||||
};
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
||||
#include <FancyZonesLib/FancyZonesData/CustomLayouts.h>
|
||||
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||
#include <FancyZonesLib/FancyZonesData/LastUsedVirtualDesktop.h>
|
||||
#include <FancyZonesLib/FancyZonesData/LayoutHotkeys.h>
|
||||
#include <FancyZonesLib/FancyZonesData/LayoutTemplates.h>
|
||||
#include <FancyZonesLib/FancyZonesWindowProcessing.h>
|
||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||
#include <FancyZonesLib/MonitorUtils.h>
|
||||
#include <FancyZonesLib/MonitorWorkAreaMap.h>
|
||||
#include <FancyZonesLib/on_thread_executor.h>
|
||||
#include <FancyZonesLib/Settings.h>
|
||||
#include <FancyZonesLib/SettingsObserver.h>
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <FancyZonesLib/WindowKeyboardSnap.h>
|
||||
#include <FancyZonesLib/WindowMouseSnap.h>
|
||||
#include <FancyZonesLib/WorkArea.h>
|
||||
#include <FancyZonesLib/WorkAreaConfiguration.h>
|
||||
|
||||
enum class DisplayChangeType
|
||||
{
|
||||
@@ -88,6 +89,7 @@ public:
|
||||
AppliedLayouts::instance().LoadData();
|
||||
AppZoneHistory::instance().LoadData();
|
||||
DefaultLayouts::instance().LoadData();
|
||||
LastUsedVirtualDesktop::instance().LoadData();
|
||||
}
|
||||
|
||||
// IFancyZones
|
||||
@@ -170,7 +172,7 @@ private:
|
||||
HWND m_window{};
|
||||
std::unique_ptr<WindowMouseSnap> m_windowMouseSnapper{};
|
||||
WindowKeyboardSnap m_windowKeyboardSnapper{};
|
||||
MonitorWorkAreaMap m_workAreaHandler;
|
||||
WorkAreaConfiguration m_workAreaConfiguration;
|
||||
DraggingState m_draggingState;
|
||||
|
||||
wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on
|
||||
@@ -254,6 +256,7 @@ FancyZones::Run() noexcept
|
||||
}
|
||||
});
|
||||
|
||||
VirtualDesktop::instance().UpdateVirtualDesktopId();
|
||||
SyncVirtualDesktops();
|
||||
|
||||
// id format of applied-layouts and app-zone-history was changed in 0.60
|
||||
@@ -268,7 +271,7 @@ FancyZones::Run() noexcept
|
||||
IFACEMETHODIMP_(void)
|
||||
FancyZones::Destroy() noexcept
|
||||
{
|
||||
m_workAreaHandler.Clear();
|
||||
m_workAreaConfiguration.Clear();
|
||||
BufferedPaintUnInit();
|
||||
if (m_window)
|
||||
{
|
||||
@@ -290,7 +293,7 @@ FancyZones::VirtualDesktopChanged() noexcept
|
||||
|
||||
void FancyZones::MoveSizeStart(HWND window, HMONITOR monitor)
|
||||
{
|
||||
m_windowMouseSnapper = WindowMouseSnap::Create(window, m_workAreaHandler.GetAllWorkAreas());
|
||||
m_windowMouseSnapper = WindowMouseSnap::Create(window, m_workAreaConfiguration.GetAllWorkAreas());
|
||||
if (m_windowMouseSnapper)
|
||||
{
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||
@@ -330,7 +333,7 @@ void FancyZones::MoveSizeEnd()
|
||||
|
||||
bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR monitor) noexcept
|
||||
{
|
||||
const auto& workAreas = m_workAreaHandler.GetAllWorkAreas();
|
||||
const auto& workAreas = m_workAreaConfiguration.GetAllWorkAreas();
|
||||
WorkArea* workArea{ nullptr };
|
||||
ZoneIndexSet indexes{};
|
||||
|
||||
@@ -518,7 +521,7 @@ void FancyZones::ToggleEditor() noexcept
|
||||
|
||||
m_terminateEditorEvent.reset(CreateEvent(nullptr, true, false, nullptr));
|
||||
|
||||
if (!EditorParameters::Save())
|
||||
if (!EditorParameters::Save(m_workAreaConfiguration, m_dpiUnawareThread))
|
||||
{
|
||||
Logger::error(L"Failed to save editor startup parameters");
|
||||
return;
|
||||
@@ -618,11 +621,11 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
||||
// Check whether Alt is used in the shortcut key combination
|
||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
||||
{
|
||||
m_windowKeyboardSnapper.Extend(foregroundWindow, windowRect, monitor, static_cast<DWORD>(lparam), m_workAreaHandler.GetAllWorkAreas());
|
||||
m_windowKeyboardSnapper.Extend(foregroundWindow, windowRect, monitor, static_cast<DWORD>(lparam), m_workAreaConfiguration.GetAllWorkAreas());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_windowKeyboardSnapper.Snap(foregroundWindow, windowRect, monitor, static_cast<DWORD>(lparam), m_workAreaHandler.GetAllWorkAreas(), monitors);
|
||||
m_windowKeyboardSnapper.Snap(foregroundWindow, windowRect, monitor, static_cast<DWORD>(lparam), m_workAreaConfiguration.GetAllWorkAreas(), monitors);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -632,7 +635,7 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
||||
}
|
||||
else
|
||||
{
|
||||
m_windowKeyboardSnapper.Snap(foregroundWindow, monitor, static_cast<DWORD>(lparam), m_workAreaHandler.GetAllWorkAreas(), FancyZonesUtils::GetMonitorsOrdered());
|
||||
m_windowKeyboardSnapper.Snap(foregroundWindow, monitor, static_cast<DWORD>(lparam), m_workAreaConfiguration.GetAllWorkAreas(), FancyZonesUtils::GetMonitorsOrdered());
|
||||
}
|
||||
}
|
||||
else if (message == WM_PRIV_INIT)
|
||||
@@ -727,6 +730,7 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
||||
updateWindowsPositions = FancyZonesSettings::settings().displayChange_moveWindows;
|
||||
break;
|
||||
case DisplayChangeType::VirtualDesktop: // Switched virtual desktop
|
||||
SyncVirtualDesktops();
|
||||
break;
|
||||
case DisplayChangeType::Initialization: // Initialization
|
||||
updateWindowsPositions = FancyZonesSettings::settings().zoneSetChange_moveWindows;
|
||||
@@ -756,14 +760,17 @@ bool FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAr
|
||||
rect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
||||
}
|
||||
|
||||
auto workArea = WorkArea::Create(m_hinstance, id, m_workAreaHandler.GetParent(monitor), rect);
|
||||
auto parentWorkAreaId = id;
|
||||
parentWorkAreaId.virtualDesktopId = LastUsedVirtualDesktop::instance().GetId();
|
||||
|
||||
auto workArea = WorkArea::Create(m_hinstance, id, parentWorkAreaId, rect);
|
||||
if (!workArea)
|
||||
{
|
||||
Logger::error(L"Failed to create work area {}", id.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_workAreaHandler.AddWorkArea(monitor, std::move(workArea));
|
||||
m_workAreaConfiguration.AddWorkArea(monitor, std::move(workArea));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -785,8 +792,7 @@ void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||
{
|
||||
Logger::debug(L"Update work areas, update windows positions: {}", updateWindowPositions);
|
||||
|
||||
m_workAreaHandler.SaveParentIds();
|
||||
m_workAreaHandler.Clear();
|
||||
m_workAreaConfiguration.Clear();
|
||||
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||
{
|
||||
@@ -824,7 +830,7 @@ void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors) // one work area across monitors
|
||||
{
|
||||
const auto workArea = m_workAreaHandler.GetWorkArea(nullptr);
|
||||
const auto workArea = m_workAreaConfiguration.GetWorkArea(nullptr);
|
||||
if (workArea)
|
||||
{
|
||||
for (const auto& [window, zones] : windowsToSnap)
|
||||
@@ -841,7 +847,7 @@ void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||
const auto window = iter->first;
|
||||
const auto zones = iter->second;
|
||||
const auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||
const auto workAreaForMonitor = m_workAreaHandler.GetWorkArea(monitor);
|
||||
const auto workAreaForMonitor = m_workAreaConfiguration.GetWorkArea(monitor);
|
||||
if (workAreaForMonitor && AppZoneHistory::instance().GetAppLastZoneIndexSet(window, workAreaForMonitor->UniqueId(), workAreaForMonitor->GetLayoutId()) == zones)
|
||||
{
|
||||
workAreaForMonitor->Snap(window, zones, false);
|
||||
@@ -856,7 +862,7 @@ void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||
// snap rest of the windows to other work areas (in case they were moved after the monitor unplug)
|
||||
for (const auto& [window, zones] : windowsToSnap)
|
||||
{
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (const auto& [_, workArea] : m_workAreaConfiguration.GetAllWorkAreas())
|
||||
{
|
||||
const auto savedIndexes = AppZoneHistory::instance().GetAppLastZoneIndexSet(window, workArea->UniqueId(), workArea->GetLayoutId());
|
||||
if (savedIndexes == zones)
|
||||
@@ -869,7 +875,7 @@ void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept
|
||||
|
||||
if (updateWindowPositions)
|
||||
{
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (const auto& [_, workArea] : m_workAreaConfiguration.GetAllWorkAreas())
|
||||
{
|
||||
if (workArea)
|
||||
{
|
||||
@@ -884,7 +890,7 @@ void FancyZones::CycleWindows(bool reverse) noexcept
|
||||
auto window = GetForegroundWindow();
|
||||
HMONITOR current = WorkAreaKeyFromWindow(window);
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(current);
|
||||
auto workArea = m_workAreaConfiguration.GetWorkArea(current);
|
||||
if (workArea)
|
||||
{
|
||||
workArea->CycleWindows(window, reverse);
|
||||
@@ -893,15 +899,23 @@ void FancyZones::CycleWindows(bool reverse) noexcept
|
||||
|
||||
void FancyZones::SyncVirtualDesktops() noexcept
|
||||
{
|
||||
// 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).
|
||||
|
||||
auto lastUsed = LastUsedVirtualDesktop::instance().GetId();
|
||||
auto current = VirtualDesktop::instance().GetCurrentVirtualDesktopId();
|
||||
auto guids = VirtualDesktop::instance().GetVirtualDesktopIdsFromRegistry();
|
||||
if (guids.has_value())
|
||||
|
||||
if (current != lastUsed)
|
||||
{
|
||||
AppZoneHistory::instance().RemoveDeletedVirtualDesktops(*guids);
|
||||
AppliedLayouts::instance().RemoveDeletedVirtualDesktops(*guids);
|
||||
LastUsedVirtualDesktop::instance().SetId(current);
|
||||
LastUsedVirtualDesktop::instance().SaveData();
|
||||
}
|
||||
|
||||
AppZoneHistory::instance().SyncVirtualDesktops();
|
||||
AppliedLayouts::instance().SyncVirtualDesktops();
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(current, lastUsed, guids);
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(current, lastUsed, guids);
|
||||
}
|
||||
|
||||
void FancyZones::UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept
|
||||
@@ -955,7 +969,7 @@ void FancyZones::SettingsUpdate(SettingId id)
|
||||
break;
|
||||
case SettingId::SpanZonesAcrossMonitors:
|
||||
{
|
||||
m_workAreaHandler.Clear();
|
||||
m_workAreaConfiguration.Clear();
|
||||
PostMessageW(m_window, WM_PRIV_INIT, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
@@ -966,7 +980,7 @@ void FancyZones::SettingsUpdate(SettingId id)
|
||||
|
||||
void FancyZones::RefreshLayouts() noexcept
|
||||
{
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (const auto& [_, workArea] : m_workAreaConfiguration.GetAllWorkAreas())
|
||||
{
|
||||
if (workArea)
|
||||
{
|
||||
@@ -993,7 +1007,7 @@ bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
||||
{
|
||||
HMONITOR monitor = WorkAreaKeyFromWindow(window);
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(monitor);
|
||||
auto workArea = m_workAreaConfiguration.GetWorkArea(monitor);
|
||||
if (!workArea)
|
||||
{
|
||||
Logger::error(L"No work area for processing snap hotkey");
|
||||
@@ -1038,13 +1052,15 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
|
||||
return;
|
||||
}
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor();
|
||||
auto workArea = m_workAreaConfiguration.GetWorkAreaFromCursor();
|
||||
if (workArea)
|
||||
{
|
||||
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
||||
AppliedLayouts::instance().SaveData();
|
||||
RefreshLayouts();
|
||||
FlashZones();
|
||||
if (AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value()))
|
||||
{
|
||||
RefreshLayouts();
|
||||
FlashZones();
|
||||
AppliedLayouts::instance().SaveData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,7 +1068,7 @@ void FancyZones::FlashZones() noexcept
|
||||
{
|
||||
if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_draggingState.IsDragging())
|
||||
{
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (const auto& [_, workArea] : m_workAreaConfiguration.GetAllWorkAreas())
|
||||
{
|
||||
if (workArea)
|
||||
{
|
||||
|
||||
@@ -26,13 +26,7 @@ public:
|
||||
return settingsFileName;
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(UNIT_TESTS)
|
||||
friend class FancyZonesUnitTests::LayoutHotkeysUnitTests;
|
||||
friend class FancyZonesUnitTests::LayoutTemplatesUnitTests;
|
||||
friend class FancyZonesUnitTests::CustomLayoutsUnitTests;
|
||||
friend class FancyZonesUnitTests::AppliedLayoutsUnitTests;
|
||||
|
||||
inline void SetSettingsModulePath(std::wstring_view moduleName)
|
||||
{
|
||||
std::wstring result = PTSettingsHelper::get_module_save_folder_location(moduleName);
|
||||
@@ -46,6 +40,8 @@ private:
|
||||
return result + L"\\" + std::wstring(L"zones-settings.json");
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::wstring settingsFileName;
|
||||
std::wstring zonesSettingsFileName;
|
||||
std::wstring appZoneHistoryFileName;
|
||||
|
||||
@@ -591,67 +591,43 @@ ZoneIndexSet AppZoneHistory::GetAppLastZoneIndexSet(HWND window, const FancyZone
|
||||
return {};
|
||||
}
|
||||
|
||||
void AppZoneHistory::SyncVirtualDesktops()
|
||||
void AppZoneHistory::SyncVirtualDesktops(const GUID& currentVirtualDesktop, const GUID& lastUsedVirtualDesktop, std::optional<std::vector<GUID>> desktops)
|
||||
{
|
||||
// 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).
|
||||
TAppZoneHistoryMap history;
|
||||
|
||||
auto savedInRegistryVirtualDesktopID = VirtualDesktop::instance().GetCurrentVirtualDesktopIdFromRegistry();
|
||||
if (!savedInRegistryVirtualDesktopID.has_value() || savedInRegistryVirtualDesktopID.value() == GUID_NULL)
|
||||
std::unordered_set<GUID> activeDesktops{};
|
||||
if (desktops.has_value())
|
||||
{
|
||||
return;
|
||||
activeDesktops = std::unordered_set<GUID>(std::begin(desktops.value()), std::end(desktops.value()));
|
||||
}
|
||||
|
||||
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(savedInRegistryVirtualDesktopID.value());
|
||||
if (!currentVirtualDesktopStr.has_value())
|
||||
auto findCurrentVirtualDesktopInSavedHistory = [&](const std::pair<std::wstring, std::vector<FancyZonesDataTypes::AppZoneHistoryData>>& val) -> bool
|
||||
{
|
||||
Logger::error(L"Failed to convert virtual desktop GUID to string");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::info(L"AppZoneHistory Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
||||
|
||||
bool dirtyFlag = false;
|
||||
|
||||
for (auto& [path, perDesktopData] : m_history)
|
||||
{
|
||||
for (auto& data : perDesktopData)
|
||||
for (auto& data : val.second)
|
||||
{
|
||||
if (data.workAreaId.virtualDesktopId == GUID_NULL)
|
||||
if (data.workAreaId.virtualDesktopId == currentVirtualDesktop)
|
||||
{
|
||||
data.workAreaId.virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||
dirtyFlag = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
bool replaceLastUsedWithCurrent = !desktops.has_value() || currentVirtualDesktop == GUID_NULL || lastUsedVirtualDesktop == GUID_NULL || std::find_if(m_history.begin(), m_history.end(), findCurrentVirtualDesktopInSavedHistory) == m_history.end();
|
||||
|
||||
if (dirtyFlag)
|
||||
{
|
||||
Logger::info(L"Update Virtual Desktop id to {}", currentVirtualDesktopStr.value());
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
void AppZoneHistory::RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops)
|
||||
{
|
||||
std::unordered_set<GUID> active(std::begin(activeDesktops), std::end(activeDesktops));
|
||||
bool dirtyFlag = false;
|
||||
|
||||
for (auto it = std::begin(m_history); it != std::end(m_history);)
|
||||
{
|
||||
auto& perDesktopData = it->second;
|
||||
for (auto desktopIt = std::begin(perDesktopData); desktopIt != std::end(perDesktopData);)
|
||||
{
|
||||
if (desktopIt->workAreaId.virtualDesktopId != GUID_NULL && !active.contains(desktopIt->workAreaId.virtualDesktopId))
|
||||
if (replaceLastUsedWithCurrent && desktopIt->workAreaId.virtualDesktopId == lastUsedVirtualDesktop)
|
||||
{
|
||||
auto virtualDesktopIdStr = FancyZonesUtils::GuidToString(desktopIt->workAreaId.virtualDesktopId);
|
||||
if (virtualDesktopIdStr)
|
||||
{
|
||||
Logger::info(L"Remove Virtual Desktop id {} from app-zone-history", virtualDesktopIdStr.value());
|
||||
}
|
||||
desktopIt->workAreaId.virtualDesktopId = currentVirtualDesktop;
|
||||
dirtyFlag = true;
|
||||
}
|
||||
|
||||
if (desktopIt->workAreaId.virtualDesktopId != currentVirtualDesktop && !activeDesktops.contains(desktopIt->workAreaId.virtualDesktopId))
|
||||
{
|
||||
desktopIt = perDesktopData.erase(desktopIt);
|
||||
dirtyFlag = true;
|
||||
}
|
||||
@@ -664,6 +640,7 @@ void AppZoneHistory::RemoveDeletedVirtualDesktops(const std::vector<GUID>& activ
|
||||
if (perDesktopData.empty())
|
||||
{
|
||||
it = m_history.erase(it);
|
||||
dirtyFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -41,6 +41,13 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
inline void SetAppZoneHistory(const TAppZoneHistoryMap& history)
|
||||
{
|
||||
m_history = history;
|
||||
}
|
||||
#endif
|
||||
|
||||
void LoadData();
|
||||
void SaveData();
|
||||
void AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids);
|
||||
@@ -56,8 +63,7 @@ public:
|
||||
bool IsAnotherWindowOfApplicationInstanceZoned(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId) const noexcept;
|
||||
ZoneIndexSet GetAppLastZoneIndexSet(HWND window, const FancyZonesDataTypes::WorkAreaId& workAreaId, const GUID& layoutId) const;
|
||||
|
||||
void SyncVirtualDesktops();
|
||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||
void SyncVirtualDesktops(const GUID& currentVirtualDesktop, const GUID& lastUsedVirtualDesktop, std::optional<std::vector<GUID>> desktops);
|
||||
|
||||
private:
|
||||
AppZoneHistory();
|
||||
|
||||
@@ -279,29 +279,7 @@ void AppliedLayouts::LoadData()
|
||||
|
||||
void AppliedLayouts::SaveData()
|
||||
{
|
||||
bool dirtyFlag = false;
|
||||
TAppliedLayoutsMap updatedMap;
|
||||
|
||||
for (const auto& [id, data] : m_layouts)
|
||||
{
|
||||
auto updatedId = id;
|
||||
if (!VirtualDesktop::instance().IsVirtualDesktopIdSavedInRegistry(id.virtualDesktopId))
|
||||
{
|
||||
updatedId.virtualDesktopId = GUID_NULL;
|
||||
dirtyFlag = true;
|
||||
}
|
||||
|
||||
updatedMap.insert({ updatedId, data });
|
||||
}
|
||||
|
||||
if (dirtyFlag)
|
||||
{
|
||||
json::to_file(AppliedLayoutsFileName(), JsonUtils::SerializeJson(updatedMap));
|
||||
}
|
||||
else
|
||||
{
|
||||
json::to_file(AppliedLayoutsFileName(), JsonUtils::SerializeJson(m_layouts));
|
||||
}
|
||||
json::to_file(AppliedLayoutsFileName(), JsonUtils::SerializeJson(m_layouts));
|
||||
}
|
||||
|
||||
void AppliedLayouts::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids)
|
||||
@@ -344,86 +322,75 @@ void AppliedLayouts::AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::Mo
|
||||
}
|
||||
}
|
||||
|
||||
void AppliedLayouts::SyncVirtualDesktops()
|
||||
void AppliedLayouts::SyncVirtualDesktops(const GUID& currentVirtualDesktop, const GUID& lastUsedVirtualDesktop, std::optional<std::vector<GUID>> desktops)
|
||||
{
|
||||
// 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).
|
||||
TAppliedLayoutsMap layouts;
|
||||
|
||||
auto savedInRegistryVirtualDesktopID = VirtualDesktop::instance().GetCurrentVirtualDesktopIdFromRegistry();
|
||||
if (!savedInRegistryVirtualDesktopID.has_value() || savedInRegistryVirtualDesktopID.value() == GUID_NULL)
|
||||
auto findCurrentVirtualDesktopInSavedLayouts = [&](const std::pair<FancyZonesDataTypes::WorkAreaId, LayoutData>& val) -> bool { return val.first.virtualDesktopId == currentVirtualDesktop; };
|
||||
bool replaceLastUsedWithCurrent = !desktops.has_value() || currentVirtualDesktop == GUID_NULL ||
|
||||
std::find_if(m_layouts.begin(), m_layouts.end(), findCurrentVirtualDesktopInSavedLayouts) == m_layouts.end();
|
||||
bool copyToOtherVirtualDesktops = lastUsedVirtualDesktop == GUID_NULL && currentVirtualDesktop != GUID_NULL && desktops.has_value();
|
||||
|
||||
for (const auto& [workAreaId, layout] : m_layouts)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto currentVirtualDesktopStr = FancyZonesUtils::GuidToString(savedInRegistryVirtualDesktopID.value());
|
||||
if (!currentVirtualDesktopStr.has_value())
|
||||
{
|
||||
Logger::error(L"Failed to convert virtual desktop GUID to string");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::info(L"AppliedLayouts Sync virtual desktops: current {}", currentVirtualDesktopStr.value());
|
||||
|
||||
bool dirtyFlag = false;
|
||||
|
||||
std::vector<FancyZonesDataTypes::WorkAreaId> replaceWithCurrentId{};
|
||||
|
||||
for (const auto& [id, data] : m_layouts)
|
||||
{
|
||||
if (id.virtualDesktopId == GUID_NULL)
|
||||
if (replaceLastUsedWithCurrent && workAreaId.virtualDesktopId == lastUsedVirtualDesktop)
|
||||
{
|
||||
replaceWithCurrentId.push_back(id);
|
||||
dirtyFlag = true;
|
||||
}
|
||||
}
|
||||
// replace "lastUsedVirtualDesktop" with "currentVirtualDesktop"
|
||||
auto updatedWorkAreaId = workAreaId;
|
||||
updatedWorkAreaId.virtualDesktopId = currentVirtualDesktop;
|
||||
layouts.insert({ updatedWorkAreaId, layout });
|
||||
|
||||
for (const auto& id : replaceWithCurrentId)
|
||||
{
|
||||
auto mapEntry = m_layouts.extract(id);
|
||||
mapEntry.key().virtualDesktopId = savedInRegistryVirtualDesktopID.value();
|
||||
m_layouts.insert(std::move(mapEntry));
|
||||
}
|
||||
|
||||
if (dirtyFlag)
|
||||
{
|
||||
Logger::info(L"Update Virtual Desktop id to {}", currentVirtualDesktopStr.value());
|
||||
SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
void AppliedLayouts::RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops)
|
||||
{
|
||||
std::unordered_set<GUID> active(std::begin(activeDesktops), std::end(activeDesktops));
|
||||
bool dirtyFlag = false;
|
||||
|
||||
for (auto it = std::begin(m_layouts); it != std::end(m_layouts);)
|
||||
{
|
||||
GUID desktopId = it->first.virtualDesktopId;
|
||||
|
||||
if (desktopId != GUID_NULL)
|
||||
{
|
||||
auto foundId = active.find(desktopId);
|
||||
if (foundId == std::end(active))
|
||||
if (copyToOtherVirtualDesktops)
|
||||
{
|
||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
||||
if (SUCCEEDED(StringFromCLSID(desktopId, &virtualDesktopIdStr)))
|
||||
// Copy to other virtual desktops on the 1st VD creation.
|
||||
// If we just replace the id, we'll lose the layout on the other desktops.
|
||||
// Usage scenario:
|
||||
// apply the layout to the single virtual desktop with id = GUID_NULL,
|
||||
// create the 2nd virtual desktop and switch to it,
|
||||
// so virtual desktop id changes from GUID_NULL to a valid value of the 2nd VD.
|
||||
// Then change the layout on the 2nd VD and switch back to the 1st VD.
|
||||
// Layout on the initial VD will be changed too without initializing it beforehand.
|
||||
for (const auto& id : desktops.value())
|
||||
{
|
||||
Logger::info(L"Remove Virtual Desktop id {}", virtualDesktopIdStr.get());
|
||||
if (id != currentVirtualDesktop)
|
||||
{
|
||||
auto copyWorkAreaId = workAreaId;
|
||||
copyWorkAreaId.virtualDesktopId = id;
|
||||
layouts.insert({ copyWorkAreaId, layout });
|
||||
}
|
||||
}
|
||||
|
||||
it = m_layouts.erase(it);
|
||||
dirtyFlag = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
|
||||
if (workAreaId.virtualDesktopId == currentVirtualDesktop || (desktops.has_value() &&
|
||||
std::find(desktops.value().begin(), desktops.value().end(), workAreaId.virtualDesktopId) != desktops.value().end()))
|
||||
{
|
||||
// keep only actual virtual desktop values
|
||||
layouts.insert({ workAreaId, layout });
|
||||
}
|
||||
}
|
||||
|
||||
if (dirtyFlag)
|
||||
if (layouts != m_layouts)
|
||||
{
|
||||
m_layouts = layouts;
|
||||
SaveData();
|
||||
|
||||
std::wstring currentStr = FancyZonesUtils::GuidToString(currentVirtualDesktop).value_or(L"incorrect guid");
|
||||
std::wstring lastUsedStr = FancyZonesUtils::GuidToString(lastUsedVirtualDesktop).value_or(L"incorrect guid");
|
||||
std::wstring registryStr{};
|
||||
if (desktops.has_value())
|
||||
{
|
||||
for (const auto& id : desktops.value())
|
||||
{
|
||||
registryStr += FancyZonesUtils::GuidToString(id).value_or(L"incorrect guid") + L" ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
registryStr = L"empty";
|
||||
}
|
||||
|
||||
Logger::info(L"Synced virtual desktops. Current: {}, last used: {}, registry: {}", currentStr, lastUsedStr, registryStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,9 +416,9 @@ bool AppliedLayouts::IsLayoutApplied(const FancyZonesDataTypes::WorkAreaId& id)
|
||||
return iter != m_layouts.end();
|
||||
}
|
||||
|
||||
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::WorkAreaId& deviceId, LayoutData layout)
|
||||
bool AppliedLayouts::ApplyLayout(const FancyZonesDataTypes::WorkAreaId& workAreaId, LayoutData layout)
|
||||
{
|
||||
m_layouts[deviceId] = std::move(layout);
|
||||
m_layouts[workAreaId] = layout;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -496,9 +463,5 @@ bool AppliedLayouts::CloneLayout(const FancyZonesDataTypes::WorkAreaId& srcId, c
|
||||
}
|
||||
|
||||
Logger::info(L"Clone layout from {} to {}", dstId.toString(), srcId.toString());
|
||||
m_layouts[dstId] = m_layouts[srcId];
|
||||
|
||||
SaveData();
|
||||
|
||||
return true;
|
||||
return ApplyLayout(dstId, m_layouts[srcId]);
|
||||
}
|
||||
|
||||
@@ -49,12 +49,18 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
inline void SetAppliedLayouts(TAppliedLayoutsMap layouts)
|
||||
{
|
||||
m_layouts = layouts;
|
||||
}
|
||||
#endif
|
||||
|
||||
void LoadData();
|
||||
void SaveData();
|
||||
void AdjustWorkAreaIds(const std::vector<FancyZonesDataTypes::MonitorId>& ids);
|
||||
|
||||
void SyncVirtualDesktops();
|
||||
void RemoveDeletedVirtualDesktops(const std::vector<GUID>& activeDesktops);
|
||||
void SyncVirtualDesktops(const GUID& currentVirtualDesktop, const GUID& lastUsedVirtualDesktop, std::optional<std::vector<GUID>> desktops);
|
||||
|
||||
std::optional<LayoutData> GetDeviceLayout(const FancyZonesDataTypes::WorkAreaId& id) const noexcept;
|
||||
const TAppliedLayoutsMap& GetAppliedLayoutMap() const noexcept;
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "../pch.h"
|
||||
#include "LastUsedVirtualDesktop.h"
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
namespace JsonUtils
|
||||
{
|
||||
GUID ParseJson(const json::JsonObject& json)
|
||||
{
|
||||
auto idStr = json.GetNamedString(NonLocalizable::LastUsedVirtualDesktop::LastUsedVirtualDesktopID);
|
||||
auto idOpt = FancyZonesUtils::GuidFromString(idStr.c_str());
|
||||
|
||||
if (!idOpt.has_value())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return idOpt.value();
|
||||
}
|
||||
|
||||
json::JsonObject SerializeJson(const GUID& id)
|
||||
{
|
||||
json::JsonObject result{};
|
||||
|
||||
auto virtualDesktopStr = FancyZonesUtils::GuidToString(id);
|
||||
if (virtualDesktopStr)
|
||||
{
|
||||
result.SetNamedValue(NonLocalizable::LastUsedVirtualDesktop::LastUsedVirtualDesktopID, json::value(virtualDesktopStr.value()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LastUsedVirtualDesktop& LastUsedVirtualDesktop::instance()
|
||||
{
|
||||
static LastUsedVirtualDesktop self;
|
||||
return self;
|
||||
}
|
||||
|
||||
void LastUsedVirtualDesktop::LoadData()
|
||||
{
|
||||
auto data = json::from_file(LastUsedVirtualDesktopFileName());
|
||||
|
||||
try
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
m_id = JsonUtils::ParseJson(data.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_id = GUID_NULL;
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error& e)
|
||||
{
|
||||
Logger::error(L"Parsing last-used-virtual-desktop error: {}", e.message());
|
||||
}
|
||||
}
|
||||
|
||||
void LastUsedVirtualDesktop::SaveData() const
|
||||
{
|
||||
json::to_file(LastUsedVirtualDesktopFileName(), JsonUtils::SerializeJson(m_id));
|
||||
}
|
||||
|
||||
GUID LastUsedVirtualDesktop::GetId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void LastUsedVirtualDesktop::SetId(GUID id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
|
||||
#include <FancyZonesLib/ModuleConstants.h>
|
||||
|
||||
namespace NonLocalizable
|
||||
{
|
||||
namespace LastUsedVirtualDesktop
|
||||
{
|
||||
const static wchar_t* LastUsedVirtualDesktopID = L"last-used-virtual-desktop";
|
||||
}
|
||||
}
|
||||
|
||||
class LastUsedVirtualDesktop
|
||||
{
|
||||
public:
|
||||
static LastUsedVirtualDesktop& instance();
|
||||
|
||||
inline static std::wstring LastUsedVirtualDesktopFileName()
|
||||
{
|
||||
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::ModuleKey);
|
||||
#if defined(UNIT_TESTS)
|
||||
return saveFolderPath + L"\\test-last-used-virtual-desktop.json";
|
||||
#else
|
||||
return saveFolderPath + L"\\last-used-virtual-desktop.json";
|
||||
#endif
|
||||
}
|
||||
|
||||
void LoadData();
|
||||
void SaveData() const;
|
||||
|
||||
GUID GetId() const;
|
||||
void SetId(GUID id);
|
||||
|
||||
private:
|
||||
LastUsedVirtualDesktop() = default;
|
||||
~LastUsedVirtualDesktop() = default;
|
||||
|
||||
GUID m_id{};
|
||||
};
|
||||
@@ -209,14 +209,12 @@ namespace FancyZonesDataTypes
|
||||
|
||||
inline bool operator==(const WorkAreaId& lhs, const WorkAreaId& rhs)
|
||||
{
|
||||
bool vdEqual = (lhs.virtualDesktopId == rhs.virtualDesktopId || lhs.virtualDesktopId == GUID_NULL || rhs.virtualDesktopId == GUID_NULL);
|
||||
return vdEqual && lhs.monitorId == rhs.monitorId;
|
||||
return lhs.virtualDesktopId == rhs.virtualDesktopId && lhs.monitorId == rhs.monitorId;
|
||||
}
|
||||
|
||||
inline bool operator!=(const WorkAreaId& lhs, const WorkAreaId& rhs)
|
||||
{
|
||||
bool vdEqual = (lhs.virtualDesktopId == rhs.virtualDesktopId || lhs.virtualDesktopId == GUID_NULL || rhs.virtualDesktopId == GUID_NULL);
|
||||
return !vdEqual || lhs.monitorId != rhs.monitorId;
|
||||
return lhs.virtualDesktopId != rhs.virtualDesktopId || lhs.monitorId != rhs.monitorId;
|
||||
}
|
||||
|
||||
inline bool operator<(const WorkAreaId& lhs, const WorkAreaId& rhs)
|
||||
@@ -240,6 +238,11 @@ namespace FancyZonesDataTypes
|
||||
|
||||
return lhs.monitorId.deviceId < rhs.monitorId.deviceId;
|
||||
}
|
||||
|
||||
inline bool operator==(const AppZoneHistoryData& lhs, const AppZoneHistoryData& rhs)
|
||||
{
|
||||
return lhs.layoutId == rhs.layoutId && lhs.workAreaId == rhs.workAreaId && lhs.zoneIndexSet == rhs.zoneIndexSet && lhs.processIdToHandleMap == rhs.processIdToHandleMap;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<ClInclude Include="FancyZones.h" />
|
||||
<ClInclude Include="FancyZonesDataTypes.h" />
|
||||
<ClInclude Include="FancyZonesData\DefaultLayouts.h" />
|
||||
<ClInclude Include="FancyZonesData\LastUsedVirtualDesktop.h" />
|
||||
<ClInclude Include="FancyZonesData\LayoutData.h" />
|
||||
<ClInclude Include="FancyZonesData\LayoutDefaults.h" />
|
||||
<ClInclude Include="FancyZonesData\LayoutTemplates.h" />
|
||||
@@ -59,7 +60,7 @@
|
||||
<ClInclude Include="LayoutAssignedWindows.h" />
|
||||
<ClInclude Include="ModuleConstants.h" />
|
||||
<ClInclude Include="MonitorUtils.h" />
|
||||
<ClInclude Include="MonitorWorkAreaMap.h" />
|
||||
<ClInclude Include="WorkAreaConfiguration.h" />
|
||||
<ClInclude Include="NotificationUtil.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Generated Files/resource.h" />
|
||||
@@ -100,6 +101,9 @@
|
||||
<ClCompile Include="FancyZonesData\DefaultLayouts.cpp">
|
||||
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData\LastUsedVirtualDesktop.cpp">
|
||||
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData\LayoutTemplates.cpp">
|
||||
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
@@ -115,7 +119,7 @@
|
||||
<ClCompile Include="LayoutConfigurator.cpp" />
|
||||
<ClCompile Include="LayoutAssignedWindows.cpp" />
|
||||
<ClCompile Include="MonitorUtils.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaMap.cpp" />
|
||||
<ClCompile Include="WorkAreaConfiguration.cpp" />
|
||||
<ClCompile Include="OnThreadExecutor.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<ClInclude Include="MouseButtonsHook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MonitorWorkAreaMap.h">
|
||||
<ClInclude Include="WorkAreaConfiguration.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GenericKeyHook.h">
|
||||
@@ -168,6 +168,9 @@
|
||||
<ClInclude Include="WindowKeyboardSnap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FancyZonesData\LastUsedVirtualDesktop.h">
|
||||
<Filter>Header Files\FancyZonesData</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
@@ -200,7 +203,7 @@
|
||||
<ClCompile Include="MouseButtonsHook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MonitorWorkAreaMap.cpp">
|
||||
<ClCompile Include="WorkAreaConfiguration.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData.cpp">
|
||||
@@ -272,6 +275,9 @@
|
||||
<ClCompile Include="WindowKeyboardSnap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData\LastUsedVirtualDesktop.cpp">
|
||||
<Filter>Source Files\FancyZonesData</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesWindowProcessing.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -270,30 +270,16 @@ GUID VirtualDesktop::GetCurrentVirtualDesktopId() const noexcept
|
||||
return m_currentVirtualDesktopId;
|
||||
}
|
||||
|
||||
GUID VirtualDesktop::GetPreviousVirtualDesktopId() const noexcept
|
||||
{
|
||||
return m_previousDesktopId;
|
||||
}
|
||||
|
||||
void VirtualDesktop::UpdateVirtualDesktopId() noexcept
|
||||
{
|
||||
m_previousDesktopId = m_currentVirtualDesktopId;
|
||||
|
||||
auto currentVirtualDesktopId = GetCurrentVirtualDesktopIdFromRegistry();
|
||||
if (!currentVirtualDesktopId.has_value())
|
||||
{
|
||||
Logger::info("No Virtual Desktop Id found in registry");
|
||||
currentVirtualDesktopId = VirtualDesktop::instance().GetDesktopIdByTopLevelWindows();
|
||||
}
|
||||
|
||||
if (currentVirtualDesktopId.has_value())
|
||||
{
|
||||
m_currentVirtualDesktopId = *currentVirtualDesktopId;
|
||||
|
||||
if (m_currentVirtualDesktopId == GUID_NULL)
|
||||
{
|
||||
Logger::warn("Couldn't retrieve virtual desktop id");
|
||||
}
|
||||
m_currentVirtualDesktopId = currentVirtualDesktopId.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentVirtualDesktopId = GUID_NULL;
|
||||
}
|
||||
|
||||
Trace::VirtualDesktopChanged();
|
||||
|
||||
@@ -7,7 +7,6 @@ public:
|
||||
|
||||
// saved values
|
||||
GUID GetCurrentVirtualDesktopId() const noexcept;
|
||||
GUID GetPreviousVirtualDesktopId() const noexcept;
|
||||
void UpdateVirtualDesktopId() noexcept;
|
||||
|
||||
// IVirtualDesktopManager
|
||||
@@ -29,7 +28,6 @@ private:
|
||||
IVirtualDesktopManager* m_vdManager{nullptr};
|
||||
|
||||
GUID m_currentVirtualDesktopId{};
|
||||
GUID m_previousDesktopId{};
|
||||
|
||||
std::optional<std::vector<GUID>> GetVirtualDesktopIdsFromRegistry(HKEY hKey) const;
|
||||
};
|
||||
|
||||
@@ -244,14 +244,12 @@ void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId)
|
||||
const bool isLayoutAlreadyApplied = AppliedLayouts::instance().IsLayoutApplied(m_uniqueId);
|
||||
if (!isLayoutAlreadyApplied)
|
||||
{
|
||||
if (parentUniqueId.virtualDesktopId != GUID_NULL)
|
||||
{
|
||||
AppliedLayouts::instance().CloneLayout(parentUniqueId, m_uniqueId);
|
||||
}
|
||||
else
|
||||
if (!AppliedLayouts::instance().CloneLayout(parentUniqueId, m_uniqueId))
|
||||
{
|
||||
AppliedLayouts::instance().ApplyDefaultLayout(m_uniqueId);
|
||||
}
|
||||
|
||||
AppliedLayouts::instance().SaveData();
|
||||
}
|
||||
|
||||
CalculateZoneSet();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "pch.h"
|
||||
#include "MonitorWorkAreaMap.h"
|
||||
#include "WorkAreaConfiguration.h"
|
||||
|
||||
#include <FancyZonesLib/WorkArea.h>
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkArea(HMONITOR monitor) const
|
||||
WorkArea* const WorkAreaConfiguration::GetWorkArea(HMONITOR monitor) const
|
||||
{
|
||||
auto iter = m_workAreaMap.find(monitor);
|
||||
if (iter != m_workAreaMap.end())
|
||||
@@ -14,7 +14,7 @@ WorkArea* const MonitorWorkAreaMap::GetWorkArea(HMONITOR monitor) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromCursor() const
|
||||
WorkArea* const WorkAreaConfiguration::GetWorkAreaFromCursor() const
|
||||
{
|
||||
const auto allMonitorsWorkArea = GetWorkArea(nullptr);
|
||||
if (allMonitorsWorkArea)
|
||||
@@ -35,7 +35,7 @@ WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromCursor() const
|
||||
}
|
||||
}
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromWindow(HWND window) const
|
||||
WorkArea* const WorkAreaConfiguration::GetWorkAreaFromWindow(HWND window) const
|
||||
{
|
||||
const auto allMonitorsWorkArea = GetWorkArea(nullptr);
|
||||
if (allMonitorsWorkArea)
|
||||
@@ -51,39 +51,17 @@ WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromWindow(HWND window) const
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& MonitorWorkAreaMap::GetAllWorkAreas() const noexcept
|
||||
const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& WorkAreaConfiguration::GetAllWorkAreas() const noexcept
|
||||
{
|
||||
return m_workAreaMap;
|
||||
}
|
||||
|
||||
void MonitorWorkAreaMap::AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea)
|
||||
void WorkAreaConfiguration::AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea)
|
||||
{
|
||||
m_workAreaMap.insert({ monitor, std::move(workArea) });
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId MonitorWorkAreaMap::GetParent(HMONITOR monitor) const
|
||||
{
|
||||
if (m_workAreaParents.contains(monitor))
|
||||
{
|
||||
return m_workAreaParents.at(monitor);
|
||||
}
|
||||
|
||||
return FancyZonesDataTypes::WorkAreaId{};
|
||||
}
|
||||
|
||||
void MonitorWorkAreaMap::SaveParentIds()
|
||||
{
|
||||
m_workAreaParents.clear();
|
||||
for (const auto& [monitor, workArea] : m_workAreaMap)
|
||||
{
|
||||
if (workArea)
|
||||
{
|
||||
m_workAreaParents.insert({ monitor, workArea->UniqueId() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorWorkAreaMap::Clear() noexcept
|
||||
void WorkAreaConfiguration::Clear() noexcept
|
||||
{
|
||||
m_workAreaMap.clear();
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuidUtils.h"
|
||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||
|
||||
class WorkArea;
|
||||
|
||||
class MonitorWorkAreaMap
|
||||
class WorkAreaConfiguration
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Get work area based on virtual desktop id and monitor handle.
|
||||
* Get work area based on monitor handle.
|
||||
*
|
||||
* @param[in] monitor Monitor handle.
|
||||
*
|
||||
@@ -19,7 +18,7 @@ public:
|
||||
WorkArea* const GetWorkArea(HMONITOR monitor) const;
|
||||
|
||||
/**
|
||||
* Get work area based on virtual desktop id and the current cursor position.
|
||||
* Get work area based on the current cursor position.
|
||||
*
|
||||
* @returns Object representing single work area, interface to all actions available on work area
|
||||
* (e.g. moving windows through zone layout specified for that work area).
|
||||
@@ -49,13 +48,6 @@ public:
|
||||
*/
|
||||
void AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea);
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId GetParent(HMONITOR monitor) const;
|
||||
|
||||
/**
|
||||
* Saving current work area IDs as parents for later use.
|
||||
*/
|
||||
void SaveParentIds();
|
||||
|
||||
/**
|
||||
* Clear all persisted work area related data.
|
||||
*/
|
||||
@@ -63,5 +55,4 @@ public:
|
||||
|
||||
private:
|
||||
std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>> m_workAreaMap;
|
||||
std::unordered_map<HMONITOR, FancyZonesDataTypes::WorkAreaId> m_workAreaParents{};
|
||||
};
|
||||
@@ -339,4 +339,159 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsFalse(AppZoneHistory::instance().RemoveAppLastZone(nullptr, workAreaId, layoutId));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (AppZoneHistorySyncVirtualDesktops)
|
||||
{
|
||||
const GUID virtualDesktop1 = FancyZonesUtils::GuidFromString(L"{30387C86-BB15-476D-8683-AF93F6D73E99}").value();
|
||||
const GUID virtualDesktop2 = FancyZonesUtils::GuidFromString(L"{65F6343A-868F-47EE-838E-55A178A7FB7A}").value();
|
||||
const GUID deletedVirtualDesktop = FancyZonesUtils::GuidFromString(L"{2D9F3E2D-F61D-4618-B35D-85C9B8DFDFD8}").value();
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId GetWorkAreaID(GUID virtualDesktop)
|
||||
{
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = {
|
||||
.deviceId = { .id = L"id", .instanceId = L"id", .number = 1 },
|
||||
.serialNumber = L"serial-number"
|
||||
},
|
||||
.virtualDesktopId = virtualDesktop
|
||||
};
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::AppZoneHistoryData GetAppZoneHistoryData(GUID virtualDesktop, const std::wstring& layoutId, const ZoneIndexSet& zones)
|
||||
{
|
||||
return FancyZonesDataTypes::AppZoneHistoryData{
|
||||
.layoutId = FancyZonesUtils::GuidFromString(layoutId).value(),
|
||||
.workAreaId = GetWorkAreaID(virtualDesktop),
|
||||
.zoneIndexSet = zones
|
||||
};
|
||||
};
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
AppZoneHistory::instance().LoadData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
std::filesystem::remove(AppZoneHistory::AppZoneHistoryFileName());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_SwitchVirtualDesktop)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(virtualDesktop1, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
GetAppZoneHistoryData(virtualDesktop2, L"{EAC1BB3B-13D6-4839-BBF7-58C3E8AB7229}", { 1 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = virtualDesktop2;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(history.at(app)[0] == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop1)).value());
|
||||
Assert::IsTrue(history.at(app)[1] == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop2)).value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_CurrentVirtualDesktopDeleted)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(virtualDesktop1, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
GetAppZoneHistoryData(deletedVirtualDesktop, L"{EAC1BB3B-13D6-4839-BBF7-58C3E8AB7229}", { 1 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1 } };
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(history.at(app)[0] == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop1)).value());
|
||||
Assert::IsFalse(AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_NotCurrentVirtualDesktopDeleted)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(virtualDesktop1, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
GetAppZoneHistoryData(deletedVirtualDesktop, L"{EAC1BB3B-13D6-4839-BBF7-58C3E8AB7229}", { 1 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = virtualDesktop1;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1 } };
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(history.at(app)[0] == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop1)).value());
|
||||
Assert::IsFalse(AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_AllIdsFromRegistryAreNew)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(deletedVirtualDesktop, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
auto expected = history.at(app)[0];
|
||||
expected.workAreaId.virtualDesktopId = currentVirtualDesktop;
|
||||
Assert::IsTrue(expected == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop1)).value());
|
||||
Assert::IsFalse(AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(virtualDesktop2)).has_value());
|
||||
Assert::IsFalse(AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktop_NoDesktopsInRegistry)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(deletedVirtualDesktop, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = GUID_NULL;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = std::nullopt;
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
auto expected = history.at(app)[0];
|
||||
expected.workAreaId.virtualDesktopId = currentVirtualDesktop;
|
||||
Assert::IsTrue(expected == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(currentVirtualDesktop)).value());
|
||||
Assert::IsFalse(AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktop_SwithVirtualDesktopFirstTime)
|
||||
{
|
||||
AppZoneHistory::TAppZoneHistoryMap history{};
|
||||
const std::wstring app = L"app";
|
||||
history.insert({ app, std::vector<FancyZonesDataTypes::AppZoneHistoryData>{
|
||||
GetAppZoneHistoryData(GUID_NULL, L"{147243D0-1111-4225-BCD3-31029FE384FC}", { 0 }),
|
||||
} });
|
||||
AppZoneHistory::instance().SetAppZoneHistory(history);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = GUID_NULL;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppZoneHistory::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
auto expected = history.at(app)[0];
|
||||
expected.workAreaId.virtualDesktopId = currentVirtualDesktop;
|
||||
Assert::IsTrue(expected == AppZoneHistory::instance().GetZoneHistory(app, GetWorkAreaID(currentVirtualDesktop)).value());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,24 +14,14 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
TEST_CLASS (AppliedLayoutsUnitTests)
|
||||
{
|
||||
FancyZonesData& m_fzData = FancyZonesDataInstance();
|
||||
std::wstring m_testFolder = L"FancyZonesUnitTests";
|
||||
std::wstring m_testFolderPath = PTSettingsHelper::get_module_save_folder_location(m_testFolder);
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_fzData.SetSettingsModulePath(L"FancyZonesUnitTests");
|
||||
AppliedLayouts::instance().LoadData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
// Move...FromZonesSettings creates all of these files, clean up
|
||||
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
||||
std::filesystem::remove(CustomLayouts::CustomLayoutsFileName());
|
||||
std::filesystem::remove(LayoutHotkeys::LayoutHotkeysFileName());
|
||||
std::filesystem::remove(LayoutTemplates::LayoutTemplatesFileName());
|
||||
std::filesystem::remove_all(m_testFolderPath);
|
||||
AppliedLayouts::instance().LoadData(); // clean data
|
||||
}
|
||||
|
||||
TEST_METHOD (AppliedLayoutsParse)
|
||||
@@ -75,7 +65,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsTrue(AppliedLayouts::instance().IsLayoutApplied(id));
|
||||
}
|
||||
|
||||
TEST_METHOD(AppliedLayoutsParseDataWithResolution)
|
||||
TEST_METHOD (AppliedLayoutsParseDataWithResolution)
|
||||
{
|
||||
// prepare
|
||||
json::JsonObject root{};
|
||||
@@ -242,143 +232,94 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettings)
|
||||
TEST_METHOD (Save)
|
||||
{
|
||||
// prepare
|
||||
json::JsonObject root{};
|
||||
json::JsonArray devicesArray{}, customLayoutsArray{}, templateLayoutsArray{}, quickLayoutKeysArray{};
|
||||
|
||||
{
|
||||
json::JsonObject activeZoneset{};
|
||||
activeZoneset.SetNamedValue(L"uuid", json::value(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}"));
|
||||
activeZoneset.SetNamedValue(L"type", json::value(FancyZonesDataTypes::TypeToString(FancyZonesDataTypes::ZoneSetLayoutType::Rows)));
|
||||
|
||||
json::JsonObject obj{};
|
||||
obj.SetNamedValue(L"device-id", json::value(L"VSC9636#5&37ac4db&0&UID160005_3840_2160_{00000000-0000-0000-0000-000000000000}"));
|
||||
obj.SetNamedValue(L"active-zoneset", activeZoneset);;
|
||||
obj.SetNamedValue(L"editor-show-spacing", json::value(true));
|
||||
obj.SetNamedValue(L"editor-spacing", json::value(3));
|
||||
obj.SetNamedValue(L"editor-zone-count", json::value(4));
|
||||
obj.SetNamedValue(L"editor-sensitivity-radius", json::value(22));
|
||||
|
||||
devicesArray.Append(obj);
|
||||
}
|
||||
|
||||
root.SetNamedValue(L"devices", devicesArray);
|
||||
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||
root.SetNamedValue(L"quick-layout-keys", quickLayoutKeysArray);
|
||||
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::AreEqual((size_t)1, AppliedLayouts::instance().GetAppliedLayoutMap().size());
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId id{
|
||||
.monitorId = { .deviceId = { .id = L"VSC9636", .instanceId = L"5&37ac4db&0&UID160005" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId1{
|
||||
.monitorId = {
|
||||
.deviceId = { .id = L"id-1", .instanceId = L"id-1", .number = 1 },
|
||||
.serialNumber = L"serial-number-1"
|
||||
},
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{30387C86-BB15-476D-8683-AF93F6D73E99}").value()
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId2{
|
||||
.monitorId = {
|
||||
.deviceId = { .id = L"id-2", .instanceId = L"id-2", .number = 2 },
|
||||
.serialNumber = L"serial-number-2" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{30387C86-BB15-476D-8683-AF93F6D73E99}").value()
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId3{
|
||||
.monitorId = {
|
||||
.deviceId = { .id = L"id-1", .instanceId = L"id-1", .number = 1 },
|
||||
.serialNumber = L"serial-number-1" },
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId4{
|
||||
.monitorId = {
|
||||
.deviceId = { .id = L"id-2", .instanceId = L"id-2", .number = 2 },
|
||||
.serialNumber = L"serial-number-2" },
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(id).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettingsNoAppliedLayoutsData)
|
||||
{
|
||||
// prepare
|
||||
json::JsonObject root{};
|
||||
json::JsonArray customLayoutsArray{}, templateLayoutsArray{}, quickLayoutKeysArray{};
|
||||
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||
root.SetNamedValue(L"quick-layout-keys", quickLayoutKeysArray);
|
||||
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||
LayoutData layout1{ .uuid = FancyZonesUtils::GuidFromString(L"{D7DBECFA-23FC-4F45-9B56-51CFA9F6ABA2}").value() };
|
||||
LayoutData layout2{ .uuid = FancyZonesUtils::GuidFromString(L"{B9EDB48C-EC48-4E82-993F-A15DC1FF09D3}").value() };
|
||||
LayoutData layout3{ .uuid = FancyZonesUtils::GuidFromString(L"{94CF0000-7814-4D72-9624-794060FA269C}").value() };
|
||||
LayoutData layout4{ .uuid = FancyZonesUtils::GuidFromString(L"{13FA7ADF-1B6C-4FB6-8142-254B77C128E2}").value() };
|
||||
|
||||
AppliedLayouts::TAppliedLayoutsMap expected{};
|
||||
expected.insert({ workAreaId1, layout1 });
|
||||
expected.insert({ workAreaId2, layout2 });
|
||||
expected.insert({ workAreaId3, layout3 });
|
||||
expected.insert({ workAreaId4, layout4 });
|
||||
|
||||
AppliedLayouts::instance().SetAppliedLayouts(expected);
|
||||
AppliedLayouts::instance().SaveData();
|
||||
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettingsNoFile)
|
||||
{
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
auto actual = AppliedLayouts::instance().GetAppliedLayoutMap();
|
||||
Assert::AreEqual(expected.size(), actual.size());
|
||||
Assert::IsTrue(expected.at(workAreaId1) == actual.at(workAreaId1));
|
||||
Assert::IsTrue(expected.at(workAreaId2) == actual.at(workAreaId2));
|
||||
Assert::IsTrue(expected.at(workAreaId3) == actual.at(workAreaId3));
|
||||
Assert::IsTrue(expected.at(workAreaId4) == actual.at(workAreaId4));
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfo)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId deviceSrc{
|
||||
.monitorId = { .deviceId = { .id = L"Device1", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{EA6B6934-D55F-49F5-A9A5-CFADE21FFFB8}").value()
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId deviceDst{
|
||||
.monitorId = { .deviceId = { .id = L"Device2", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{EF1A8099-7D1E-4738-805A-571B31B02674}").value()
|
||||
};
|
||||
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceSrc));
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceDst));
|
||||
LayoutData layout { .uuid = FancyZonesUtils::GuidFromString(L"{361F96DD-FD10-4D01-ABAC-CC1C857294DD}").value() };
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyLayout(deviceSrc, layout));
|
||||
|
||||
AppliedLayouts::instance().CloneLayout(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = AppliedLayouts::instance().GetAppliedLayoutMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = AppliedLayouts::instance().GetDeviceLayout(deviceSrc);
|
||||
auto actual = AppliedLayouts::instance().GetDeviceLayout(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value().uuid == actual.value().uuid);
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfoIntoUnknownDevice)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId deviceSrc{
|
||||
.monitorId = { .deviceId = { .id = L"Device1", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId deviceDst{
|
||||
.monitorId = { .deviceId = { .id = L"Device2", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
};
|
||||
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceSrc));
|
||||
|
||||
AppliedLayouts::instance().CloneLayout(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = AppliedLayouts::instance().GetAppliedLayoutMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = AppliedLayouts::instance().GetDeviceLayout(deviceSrc);
|
||||
auto actual = AppliedLayouts::instance().GetDeviceLayout(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value().uuid == actual.value().uuid);
|
||||
Assert::IsTrue(layout == AppliedLayouts::instance().GetDeviceLayout(deviceSrc));
|
||||
Assert::IsTrue(layout == AppliedLayouts::instance().GetDeviceLayout(deviceDst));
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfoFromUnknownDevice)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId deviceSrc{
|
||||
.monitorId = { .deviceId = { .id = L"Device1", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{EA6B6934-D55F-49F5-A9A5-CFADE21FFFB8}").value()
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId deviceDst{
|
||||
.monitorId = { .deviceId = { .id = L"Device2", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{EF1A8099-7D1E-4738-805A-571B31B02674}").value()
|
||||
};
|
||||
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceDst));
|
||||
|
||||
Assert::IsFalse(AppliedLayouts::instance().CloneLayout(deviceSrc, deviceDst));
|
||||
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(deviceSrc).has_value());
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(deviceDst).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(deviceDst).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfoNullVirtualDesktopId)
|
||||
@@ -389,35 +330,25 @@ namespace FancyZonesUnitTests
|
||||
};
|
||||
FancyZonesDataTypes::WorkAreaId deviceDst{
|
||||
.monitorId = { .deviceId = { .id = L"Device2", .instanceId = L"" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{EF1A8099-7D1E-4738-805A-571B31B02674}").value()
|
||||
};
|
||||
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceSrc));
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyDefaultLayout(deviceDst));
|
||||
LayoutData layout{ .uuid = FancyZonesUtils::GuidFromString(L"{361F96DD-FD10-4D01-ABAC-CC1C857294DD}").value() };
|
||||
Assert::IsTrue(AppliedLayouts::instance().ApplyLayout(deviceSrc, layout));
|
||||
|
||||
AppliedLayouts::instance().CloneLayout(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = AppliedLayouts::instance().GetAppliedLayoutMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = AppliedLayouts::instance().GetDeviceLayout(deviceSrc);
|
||||
auto actual = AppliedLayouts::instance().GetDeviceLayout(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value().uuid == actual.value().uuid);
|
||||
Assert::IsTrue(layout == AppliedLayouts::instance().GetDeviceLayout(deviceSrc));
|
||||
Assert::IsTrue(layout == AppliedLayouts::instance().GetDeviceLayout(deviceDst));
|
||||
}
|
||||
|
||||
TEST_METHOD (ApplyLayout)
|
||||
{
|
||||
// prepare
|
||||
FancyZonesDataTypes::WorkAreaId deviceId {
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId {
|
||||
.monitorId = { .deviceId = { .id = L"DELA026", .instanceId = L"5&10a58c63&0&UID16777488" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{61FA9FC0-26A6-4B37-A834-491C148DFC57}").value()
|
||||
};
|
||||
|
||||
// test
|
||||
LayoutData expectedLayout {
|
||||
.uuid = FancyZonesUtils::GuidFromString(L"{33A2B101-06E0-437B-A61E-CDBECF502906}").value(),
|
||||
.type = FancyZonesDataTypes::ZoneSetLayoutType::Focus,
|
||||
@@ -427,47 +358,30 @@ namespace FancyZonesUnitTests
|
||||
.sensitivityRadius = 30
|
||||
};
|
||||
|
||||
AppliedLayouts::instance().ApplyLayout(deviceId, expectedLayout);
|
||||
AppliedLayouts::instance().ApplyLayout(workAreaId, expectedLayout);
|
||||
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(deviceId).has_value());
|
||||
|
||||
auto actual = AppliedLayouts::instance().GetAppliedLayoutMap().find(deviceId)->second;
|
||||
Assert::IsTrue(expectedLayout.type == actual.type);
|
||||
Assert::AreEqual(expectedLayout.showSpacing, actual.showSpacing);
|
||||
Assert::AreEqual(expectedLayout.spacing, actual.spacing);
|
||||
Assert::AreEqual(expectedLayout.zoneCount, actual.zoneCount);
|
||||
Assert::AreEqual(expectedLayout.sensitivityRadius, actual.sensitivityRadius);
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(workAreaId).has_value());
|
||||
Assert::IsTrue(expectedLayout == AppliedLayouts::instance().GetAppliedLayoutMap().find(workAreaId)->second);
|
||||
}
|
||||
|
||||
TEST_METHOD (ApplyLayoutReplace)
|
||||
{
|
||||
// prepare
|
||||
FancyZonesDataTypes::WorkAreaId deviceId{
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId{
|
||||
.monitorId = { .deviceId = { .id = L"DELA026", .instanceId = L"5&10a58c63&0&UID16777488" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{61FA9FC0-26A6-4B37-A834-491C148DFC57}").value()
|
||||
};
|
||||
|
||||
json::JsonObject root{};
|
||||
json::JsonArray layoutsArray{};
|
||||
{
|
||||
json::JsonObject layout{};
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::UuidID, json::value(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}"));
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::TypeID, json::value(FancyZonesDataTypes::TypeToString(FancyZonesDataTypes::ZoneSetLayoutType::Rows)));
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::ShowSpacingID, json::value(true));
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::SpacingID, json::value(3));
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::ZoneCountID, json::value(4));
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::SensitivityRadiusID, json::value(22));
|
||||
LayoutData layout{
|
||||
.uuid = FancyZonesUtils::GuidFromString(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}").value(),
|
||||
.type = FancyZonesDataTypes::ZoneSetLayoutType::Rows,
|
||||
.showSpacing = true,
|
||||
.spacing = 3,
|
||||
.zoneCount = 4,
|
||||
.sensitivityRadius = 22
|
||||
};
|
||||
|
||||
json::JsonObject obj{};
|
||||
obj.SetNamedValue(NonLocalizable::AppliedLayoutsIds::DeviceIdID, json::value(L"DELA026#5&10a58c63&0&UID16777488_2194_1234_{61FA9FC0-26A6-4B37-A834-491C148DFC57}"));
|
||||
obj.SetNamedValue(NonLocalizable::AppliedLayoutsIds::AppliedLayoutID, layout);
|
||||
|
||||
layoutsArray.Append(obj);
|
||||
}
|
||||
root.SetNamedValue(NonLocalizable::AppliedLayoutsIds::AppliedLayoutsArrayID, layoutsArray);
|
||||
json::to_file(AppliedLayouts::AppliedLayoutsFileName(), root);
|
||||
AppliedLayouts::instance().LoadData();
|
||||
AppliedLayouts::instance().SetAppliedLayouts({ {workAreaId, layout} });
|
||||
|
||||
// test
|
||||
LayoutData expectedLayout{
|
||||
@@ -479,18 +393,8 @@ namespace FancyZonesUnitTests
|
||||
.sensitivityRadius = 30
|
||||
};
|
||||
|
||||
AppliedLayouts::instance().ApplyLayout(deviceId, expectedLayout);
|
||||
|
||||
Assert::AreEqual((size_t)1, AppliedLayouts::instance().GetAppliedLayoutMap().size());
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(deviceId).has_value());
|
||||
|
||||
auto actual = AppliedLayouts::instance().GetAppliedLayoutMap().find(deviceId)->second;
|
||||
Assert::AreEqual(FancyZonesUtils::GuidToString(expectedLayout.uuid).value().c_str(), FancyZonesUtils::GuidToString(actual.uuid).value().c_str());
|
||||
Assert::IsTrue(expectedLayout.type == actual.type);
|
||||
Assert::AreEqual(expectedLayout.showSpacing, actual.showSpacing);
|
||||
Assert::AreEqual(expectedLayout.spacing, actual.spacing);
|
||||
Assert::AreEqual(expectedLayout.zoneCount, actual.zoneCount);
|
||||
Assert::AreEqual(expectedLayout.sensitivityRadius, actual.sensitivityRadius);
|
||||
AppliedLayouts::instance().ApplyLayout(workAreaId, expectedLayout);
|
||||
Assert::IsTrue(expectedLayout == AppliedLayouts::instance().GetDeviceLayout(workAreaId));
|
||||
}
|
||||
|
||||
TEST_METHOD (ApplyDefaultLayout)
|
||||
@@ -553,4 +457,245 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsFalse(AppliedLayouts::instance().IsLayoutApplied(id2));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (AppliedLayoutsSyncVirtualDesktops)
|
||||
{
|
||||
const GUID virtualDesktop1 = FancyZonesUtils::GuidFromString(L"{30387C86-BB15-476D-8683-AF93F6D73E99}").value();
|
||||
const GUID virtualDesktop2 = FancyZonesUtils::GuidFromString(L"{65F6343A-868F-47EE-838E-55A178A7FB7A}").value();
|
||||
const GUID deletedVirtualDesktop = FancyZonesUtils::GuidFromString(L"{2D9F3E2D-F61D-4618-B35D-85C9B8DFDFD8}").value();
|
||||
|
||||
LayoutData layout1{ .uuid = FancyZonesUtils::GuidFromString(L"{D7DBECFA-23FC-4F45-9B56-51CFA9F6ABA2}").value() };
|
||||
LayoutData layout2{ .uuid = FancyZonesUtils::GuidFromString(L"{B9EDB48C-EC48-4E82-993F-A15DC1FF09D3}").value() };
|
||||
LayoutData layout3{ .uuid = FancyZonesUtils::GuidFromString(L"{94CF0000-7814-4D72-9624-794060FA269C}").value() };
|
||||
LayoutData layout4{ .uuid = FancyZonesUtils::GuidFromString(L"{13FA7ADF-1B6C-4FB6-8142-254B77C128E2}").value() };
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId GetWorkAreaID(int number, GUID virtualDesktop)
|
||||
{
|
||||
return FancyZonesDataTypes::WorkAreaId{
|
||||
.monitorId = {
|
||||
.deviceId = {
|
||||
.id = std::wstring(L"id-") + std::to_wstring(number),
|
||||
.instanceId = std::wstring(L"id-") + std::to_wstring(number),
|
||||
.number = number
|
||||
},
|
||||
.serialNumber = std::wstring(L"serial-number-") + std::to_wstring(number)
|
||||
},
|
||||
.virtualDesktopId = virtualDesktop
|
||||
};
|
||||
}
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
AppliedLayouts::instance().LoadData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
||||
}
|
||||
|
||||
TEST_METHOD(SyncVirtualDesktops_SwitchVirtualDesktop)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, virtualDesktop1), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, virtualDesktop1), layout2 });
|
||||
layouts.insert({ GetWorkAreaID(1, virtualDesktop2), layout3 });
|
||||
layouts.insert({ GetWorkAreaID(2, virtualDesktop2), layout4 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = virtualDesktop2;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop1)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop1)));
|
||||
Assert::IsTrue(layout3 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop2)));
|
||||
Assert::IsTrue(layout4 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop2)));
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_CurrentVirtualDesktopDeleted)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, virtualDesktop1), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, virtualDesktop1), layout2 });
|
||||
layouts.insert({ GetWorkAreaID(1, deletedVirtualDesktop), layout3 });
|
||||
layouts.insert({ GetWorkAreaID(2, deletedVirtualDesktop), layout4 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1 } };
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop1)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop1)));
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, deletedVirtualDesktop)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_NotCurrentVirtualDesktopDeleted)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, virtualDesktop1), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, virtualDesktop1), layout2 });
|
||||
layouts.insert({ GetWorkAreaID(1, deletedVirtualDesktop), layout3 });
|
||||
layouts.insert({ GetWorkAreaID(2, deletedVirtualDesktop), layout4 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = virtualDesktop1;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1 } };
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop1)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop1)));
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, deletedVirtualDesktop)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktops_AllIdsFromRegistryAreNew)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, deletedVirtualDesktop), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, deletedVirtualDesktop), layout2 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop1;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop1)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop1)));
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop2)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop2)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, deletedVirtualDesktop)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (SyncVirtualDesktop_NoDesktopsInRegistry)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, deletedVirtualDesktop), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, deletedVirtualDesktop), layout2 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = GUID_NULL;
|
||||
GUID lastUsedVirtualDesktop = deletedVirtualDesktop;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = std::nullopt;
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, GUID_NULL)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, GUID_NULL)));
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, deletedVirtualDesktop)).has_value());
|
||||
Assert::IsFalse(AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, deletedVirtualDesktop)).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD(SyncVirtualDesktops_SwithVirtualDesktopFirstTime)
|
||||
{
|
||||
AppliedLayouts::TAppliedLayoutsMap layouts{};
|
||||
layouts.insert({ GetWorkAreaID(1, GUID_NULL), layout1 });
|
||||
layouts.insert({ GetWorkAreaID(2, GUID_NULL), layout2 });
|
||||
AppliedLayouts::instance().SetAppliedLayouts(layouts);
|
||||
|
||||
GUID currentVirtualDesktop = virtualDesktop2;
|
||||
GUID lastUsedVirtualDesktop = GUID_NULL;
|
||||
std::optional<std::vector<GUID>> virtualDesktopsInRegistry = { { virtualDesktop1, virtualDesktop2 } };
|
||||
AppliedLayouts::instance().SyncVirtualDesktops(currentVirtualDesktop, lastUsedVirtualDesktop, virtualDesktopsInRegistry);
|
||||
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop1)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop1)));
|
||||
Assert::IsTrue(layout1 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(1, virtualDesktop2)));
|
||||
Assert::IsTrue(layout2 == AppliedLayouts::instance().GetDeviceLayout(GetWorkAreaID(2, virtualDesktop2)));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (AppliedLayoutsFromOutdatedFileMappingUnitTests)
|
||||
{
|
||||
FancyZonesData& m_fzData = FancyZonesDataInstance();
|
||||
std::wstring m_testFolder = L"FancyZonesUnitTests";
|
||||
std::wstring m_testFolderPath = PTSettingsHelper::get_module_save_folder_location(m_testFolder);
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init)
|
||||
{
|
||||
m_fzData.SetSettingsModulePath(m_testFolder);
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp)
|
||||
{
|
||||
// MoveAppliedLayoutsFromZonesSettings creates all of these files, clean up
|
||||
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
||||
std::filesystem::remove(CustomLayouts::CustomLayoutsFileName());
|
||||
std::filesystem::remove(LayoutHotkeys::LayoutHotkeysFileName());
|
||||
std::filesystem::remove(LayoutTemplates::LayoutTemplatesFileName());
|
||||
std::filesystem::remove_all(m_testFolderPath);
|
||||
AppliedLayouts::instance().LoadData(); // clean data
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettings)
|
||||
{
|
||||
// prepare
|
||||
json::JsonObject root{};
|
||||
json::JsonArray devicesArray{}, customLayoutsArray{}, templateLayoutsArray{}, quickLayoutKeysArray{};
|
||||
|
||||
{
|
||||
json::JsonObject activeZoneset{};
|
||||
activeZoneset.SetNamedValue(L"uuid", json::value(L"{ACE817FD-2C51-4E13-903A-84CAB86FD17C}"));
|
||||
activeZoneset.SetNamedValue(L"type", json::value(FancyZonesDataTypes::TypeToString(FancyZonesDataTypes::ZoneSetLayoutType::Rows)));
|
||||
|
||||
json::JsonObject obj{};
|
||||
obj.SetNamedValue(L"device-id", json::value(L"VSC9636#5&37ac4db&0&UID160005_3840_2160_{00000000-0000-0000-0000-000000000000}"));
|
||||
obj.SetNamedValue(L"active-zoneset", activeZoneset);
|
||||
|
||||
obj.SetNamedValue(L"editor-show-spacing", json::value(true));
|
||||
obj.SetNamedValue(L"editor-spacing", json::value(3));
|
||||
obj.SetNamedValue(L"editor-zone-count", json::value(4));
|
||||
obj.SetNamedValue(L"editor-sensitivity-radius", json::value(22));
|
||||
|
||||
devicesArray.Append(obj);
|
||||
}
|
||||
|
||||
root.SetNamedValue(L"devices", devicesArray);
|
||||
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||
root.SetNamedValue(L"quick-layout-keys", quickLayoutKeysArray);
|
||||
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::AreEqual((size_t)1, AppliedLayouts::instance().GetAppliedLayoutMap().size());
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId id{
|
||||
.monitorId = { .deviceId = { .id = L"VSC9636", .instanceId = L"5&37ac4db&0&UID160005" }, .serialNumber = L"" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}").value()
|
||||
};
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetDeviceLayout(id).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettingsNoAppliedLayoutsData)
|
||||
{
|
||||
// prepare
|
||||
json::JsonObject root{};
|
||||
json::JsonArray customLayoutsArray{}, templateLayoutsArray{}, quickLayoutKeysArray{};
|
||||
root.SetNamedValue(L"custom-zone-sets", customLayoutsArray);
|
||||
root.SetNamedValue(L"templates", templateLayoutsArray);
|
||||
root.SetNamedValue(L"quick-layout-keys", quickLayoutKeysArray);
|
||||
json::to_file(m_fzData.GetZoneSettingsPath(m_testFolder), root);
|
||||
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveAppliedLayoutsFromZonesSettingsNoFile)
|
||||
{
|
||||
// test
|
||||
m_fzData.ReplaceZoneSettingsFileFromOlderVersions();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().empty());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -43,11 +43,11 @@ namespace FancyZonesUnitTests
|
||||
Assert::IsFalse(id1 == id2);
|
||||
}
|
||||
|
||||
TEST_METHOD (VirtualDesktopNull)
|
||||
TEST_METHOD (VirtualDesktopDifferent)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId id1{
|
||||
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"serial-number" },
|
||||
.virtualDesktopId = GUID_NULL
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{F21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
|
||||
};
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId id2{
|
||||
@@ -55,14 +55,14 @@ namespace FancyZonesUnitTests
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{E21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
|
||||
};
|
||||
|
||||
Assert::IsTrue(id1 == id2);
|
||||
Assert::IsFalse(id1 == id2);
|
||||
}
|
||||
|
||||
TEST_METHOD (VirtualDesktopDifferent)
|
||||
TEST_METHOD (VirtualDesktopNull)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId id1{
|
||||
.monitorId = { .deviceId = { .id = L"device", .instanceId = L"instance-id" }, .serialNumber = L"serial-number" },
|
||||
.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{F21F6F29-76FD-4FC1-8970-17AB8AD64847}").value()
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId id2{
|
||||
|
||||
Reference in New Issue
Block a user