From 2216cda2f1c9dbd6f32f372c668edbe66e9600d3 Mon Sep 17 00:00:00 2001 From: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Date: Sun, 31 May 2020 12:36:45 +0200 Subject: [PATCH] [FancyZones] Improve monitor work area handling (#3418) * Initial design for improving handling of different engaged work areas in fancyzones. * Remove active device id check in ZoneWindow. * Remove concept of active device identifier in JSONHelpers. * Refactor interface description and add new method. * Simplify ZoneWindow initialization. * Default value for active ZoneWindow during move/size. * Add newline at the end of file. * Use COM pointers for ZoneWindow instead of passing raw ptr. * Solve few issues after merging with master. * Fix typo in documentation. --- src/modules/fancyzones/lib/FancyZones.cpp | 192 ++++++------------ src/modules/fancyzones/lib/FancyZones.h | 4 - .../fancyzones/lib/FancyZonesLib.vcxproj | 2 + .../lib/FancyZonesLib.vcxproj.filters | 6 + src/modules/fancyzones/lib/JsonHelpers.cpp | 11 +- src/modules/fancyzones/lib/JsonHelpers.h | 14 -- .../fancyzones/lib/MonitorWorkAreaHandler.cpp | 104 ++++++++++ .../fancyzones/lib/MonitorWorkAreaHandler.h | 93 +++++++++ .../fancyzones/lib/WindowMoveHandler.cpp | 62 ++---- .../fancyzones/lib/WindowMoveHandler.h | 10 +- src/modules/fancyzones/lib/ZoneWindow.cpp | 33 +-- src/modules/fancyzones/lib/ZoneWindow.h | 2 +- .../tests/UnitTests/FancyZones.Spec.cpp | 12 -- .../tests/UnitTests/ZoneWindow.Spec.cpp | 54 ++--- 14 files changed, 330 insertions(+), 269 deletions(-) create mode 100644 src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp create mode 100644 src/modules/fancyzones/lib/MonitorWorkAreaHandler.h diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index cce83bd131..86b330164a 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -14,6 +14,7 @@ #include "lib/util.h" #include "trace.h" #include "VirtualDesktopUtils.h" +#include "MonitorWorkAreaHandler.h" #include @@ -25,19 +26,6 @@ enum class DisplayChangeType Initialization }; -namespace std -{ - template<> - struct hash - { - size_t operator()(const GUID& Value) const - { - RPC_STATUS status = RPC_S_OK; - return ::UuidHash(&const_cast(Value), &status); - } - }; -} - struct FancyZones : public winrt::implements { public: @@ -58,19 +46,19 @@ public: void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept { std::unique_lock writeLock(m_lock); - m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_zoneWindowMap); + m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId)); } void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept { std::unique_lock writeLock(m_lock); - m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_zoneWindowMap); + m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId)); } void MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept { std::unique_lock writeLock(m_lock); - m_windowMoveHandler.MoveSizeEnd(window, ptScreen, m_zoneWindowMap); + m_windowMoveHandler.MoveSizeEnd(window, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId)); } IFACEMETHODIMP_(void) HandleWinHookEvent(const WinHookEvent* data) noexcept @@ -153,18 +141,6 @@ public: const auto nB = (tmp & 0xFF); return RGB(nR, nG, nB); } - IFACEMETHODIMP_(IZoneWindow*) - GetParentZoneWindow(HMONITOR monitor) noexcept - { - //NOTE: as public method it's unsafe without lock, but it's called from AddZoneWindow through making ZoneWindow that causes deadlock - //TODO: needs refactoring - auto it = m_zoneWindowMap.find(monitor); - if (it != m_zoneWindowMap.end()) - { - return it->second.get(); - } - return nullptr; - } IFACEMETHODIMP_(int) GetZoneHighlightOpacity() noexcept { @@ -223,9 +199,6 @@ private: void RegisterVirtualDesktopUpdates(std::vector& ids) noexcept; - void RegisterNewWorkArea(GUID virtualDesktopId, HMONITOR monitor) noexcept; - bool IsNewWorkArea(GUID virtualDesktopId, HMONITOR monitor) noexcept; - bool IsSplashScreen(HWND window); void OnEditorExitEvent() noexcept; @@ -239,11 +212,11 @@ private: mutable std::shared_mutex m_lock; HWND m_window{}; WindowMoveHandler m_windowMoveHandler; + MonitorWorkAreaHandler m_workAreaHandler; - std::map> m_zoneWindowMap; // Map of monitor to ZoneWindow (one per monitor) winrt::com_ptr m_settings{}; - GUID m_currentVirtualDesktopId{}; // UUID of the current virtual desktop. Is GUID_NULL until first VD switch per session. - std::unordered_map> m_processedWorkAreas; // Work area is defined by monitor and virtual desktop id. + GUID m_previousDesktopId{}; // UUID of previously active virtual desktop. + GUID m_currentDesktopId{}; // UUID of the current virtual desktop. wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on wil::unique_handle m_terminateVirtualDesktopTrackerEvent; @@ -309,7 +282,7 @@ IFACEMETHODIMP_(void) FancyZones::Destroy() noexcept { std::unique_lock writeLock(m_lock); - m_zoneWindowMap.clear(); + m_workAreaHandler.Clear(); BufferedPaintUnInit(); if (m_window) { @@ -346,18 +319,9 @@ FancyZones::WindowCreated(HWND window) noexcept if (m_settings->GetSettings()->appLastZone_moveWindows && IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray)) { - for (const auto& [monitor, zoneWindow] : m_zoneWindowMap) + auto zoneWindow = m_workAreaHandler.GetWorkArea(window); + if (zoneWindow) { - // WindowCreated is also invoked when a virtual desktop switch occurs, we need a way - // to figure out when that happens to avoid moving windows that should not be moved. - GUID windowDesktopId{}; - GUID zoneWindowDesktopId{}; - if (VirtualDesktopUtils::GetWindowDesktopId(window, &windowDesktopId) && - VirtualDesktopUtils::GetZoneWindowDesktopId(zoneWindow.get(), &zoneWindowDesktopId) && - (windowDesktopId != zoneWindowDesktopId)) - { - return; - } const auto activeZoneSet = zoneWindow->ActiveZoneSet(); if (activeZoneSet) { @@ -371,9 +335,8 @@ FancyZones::WindowCreated(HWND window) noexcept !IsSplashScreen(window) && !fancyZonesData.IsAnotherWindowOfApplicationInstanceZoned(window)) { - m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, monitor, zoneIndexSet, m_zoneWindowMap); + m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, zoneWindow); fancyZonesData.UpdateProcessIdToHandleMap(window); - break; } } } @@ -468,8 +431,8 @@ void FancyZones::ToggleEditor() noexcept } std::shared_lock readLock(m_lock); - auto iter = m_zoneWindowMap.find(monitor); - if (iter == m_zoneWindowMap.end()) + auto zoneWindow = m_workAreaHandler.GetWorkArea(m_currentDesktopId, monitor); + if (!zoneWindow) { return; } @@ -482,8 +445,6 @@ void FancyZones::ToggleEditor() noexcept } }) .wait(); - auto zoneWindow = iter->second; - const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance(); fancyZonesData.CustomZoneSetsToJsonFile(ZoneWindowUtils::GetCustomZoneSetsTmpPath()); @@ -673,10 +634,11 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept if (changeType == DisplayChangeType::VirtualDesktop || changeType == DisplayChangeType::Initialization) { + m_previousDesktopId = m_currentDesktopId; GUID currentVirtualDesktopId{}; if (VirtualDesktopUtils::GetCurrentVirtualDesktopId(¤tVirtualDesktopId)) { - m_currentVirtualDesktopId = currentVirtualDesktopId; + m_currentDesktopId = currentVirtualDesktopId; } if (changeType == DisplayChangeType::Initialization) { @@ -703,27 +665,30 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept { std::unique_lock writeLock(m_lock); - wil::unique_cotaskmem_string virtualDesktopId; - if (SUCCEEDED_LOG(StringFromCLSID(m_currentVirtualDesktopId, &virtualDesktopId))) + + if (m_workAreaHandler.IsNewWorkArea(m_currentDesktopId, monitor)) { - std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get()); - JSONHelpers::FancyZonesDataInstance().SetActiveDeviceId(uniqueId); - - const bool newWorkArea = IsNewWorkArea(m_currentVirtualDesktopId, monitor); - // "Turning FLASHING_ZONE option off" - //const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones && newWorkArea; - const bool flash = false; - - auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash, newWorkArea); - if (zoneWindow) + wil::unique_cotaskmem_string virtualDesktopId; + if (SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId))) { - m_zoneWindowMap[monitor] = std::move(zoneWindow); - } + std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get()); - if (newWorkArea) - { - RegisterNewWorkArea(m_currentVirtualDesktopId, monitor); - JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData(); + // "Turning FLASHING_ZONE option off" + //const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones; + const bool flash = false; + + std::wstring parentId{}; + auto parentArea = m_workAreaHandler.GetWorkArea(m_previousDesktopId, monitor); + if (parentArea) + { + parentId = parentArea->UniqueId(); + } + auto workArea = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, parentId, flash); + if (workArea) + { + m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea); + JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData(); + } } } } @@ -802,7 +767,11 @@ void FancyZones::UpdateWindowsPositions() noexcept auto strongThis = reinterpret_cast(data); std::unique_lock writeLock(strongThis->m_lock); - strongThis->m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, nullptr, indexSet, strongThis->m_zoneWindowMap); + auto zoneWindow = strongThis->m_workAreaHandler.GetWorkArea(window); + if (zoneWindow) + { + strongThis->m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, indexSet, zoneWindow); + } } return TRUE; }; @@ -819,11 +788,10 @@ void FancyZones::CycleActiveZoneSet(DWORD vkCode) noexcept { std::shared_lock readLock(m_lock); - auto iter = m_zoneWindowMap.find(monitor); - if (iter != m_zoneWindowMap.end()) + auto zoneWindow = m_workAreaHandler.GetWorkArea(m_currentDesktopId, monitor); + if (zoneWindow) { - const auto& zoneWindowPtr = iter->second; - zoneWindowPtr->CycleActiveZoneSet(vkCode); + zoneWindow->CycleActiveZoneSet(vkCode); } } } @@ -845,7 +813,7 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept do { std::unique_lock writeLock(m_lock); - if (m_windowMoveHandler.MoveWindowIntoZoneByDirection(*currMonitorInfo, window, vkCode, false /* cycle through zones */, m_zoneWindowMap)) + if (m_windowMoveHandler.MoveWindowIntoZoneByDirection(window, vkCode, false /* cycle through zones */, m_workAreaHandler.GetWorkArea(m_currentDesktopId, *currMonitorInfo))) { return true; } @@ -872,7 +840,7 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept { // Single monitor environment. std::unique_lock writeLock(m_lock); - return m_windowMoveHandler.MoveWindowIntoZoneByDirection(current, window, vkCode, true /* cycle through zones */, m_zoneWindowMap); + return m_windowMoveHandler.MoveWindowIntoZoneByDirection(window, vkCode, true /* cycle through zones */, m_workAreaHandler.GetWorkArea(m_currentDesktopId, current)); } } } @@ -881,60 +849,24 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept void FancyZones::RegisterVirtualDesktopUpdates(std::vector& ids) noexcept { - std::unordered_set activeVirtualDesktops(std::begin(ids), std::end(ids)); std::unique_lock writeLock(m_lock); + + std::vector deleted{}; + m_workAreaHandler.RegisterUpdates(ids, deleted); + bool modified{ false }; - for (auto it = std::begin(m_processedWorkAreas); it != std::end(m_processedWorkAreas);) + for (const auto& id : deleted) { - auto iter = activeVirtualDesktops.find(it->first); - if (iter == activeVirtualDesktops.end()) + wil::unique_cotaskmem_string virtualDesktopId; + if (SUCCEEDED(StringFromCLSID(id, &virtualDesktopId))) { - // if we couldn't find the GUID in currentVirtualDesktopIds, we must remove it from both m_processedWorkAreas and deviceInfoMap - wil::unique_cotaskmem_string virtualDesktopId; - if (SUCCEEDED_LOG(StringFromCLSID(it->first, &virtualDesktopId))) - { - modified |= JSONHelpers::FancyZonesDataInstance().RemoveDevicesByVirtualDesktopId(virtualDesktopId.get()); - } - it = m_processedWorkAreas.erase(it); - } - else - { - activeVirtualDesktops.erase(it->first); // virtual desktop already in map, skip it - ++it; + modified |= JSONHelpers::FancyZonesDataInstance().RemoveDevicesByVirtualDesktopId(virtualDesktopId.get()); } } if (modified) { JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData(); } - // register new virtual desktops, if any - for (const auto& id : activeVirtualDesktops) - { - m_processedWorkAreas[id] = std::vector(); - } -} - -void FancyZones::RegisterNewWorkArea(GUID virtualDesktopId, HMONITOR monitor) noexcept -{ - if (!m_processedWorkAreas.contains(virtualDesktopId)) - { - m_processedWorkAreas[virtualDesktopId] = { monitor }; - } - else - { - m_processedWorkAreas[virtualDesktopId].push_back(monitor); - } -} - -bool FancyZones::IsNewWorkArea(GUID virtualDesktopId, HMONITOR monitor) noexcept -{ - auto it = m_processedWorkAreas.find(virtualDesktopId); - if (it != m_processedWorkAreas.end()) - { - // virtual desktop exists, check if it's processed on given monitor - return std::find(it->second.begin(), it->second.end(), monitor) == it->second.end(); - } - return true; } bool FancyZones::IsSplashScreen(HWND window) @@ -956,10 +888,10 @@ void FancyZones::OnEditorExitEvent() noexcept JSONHelpers::FancyZonesDataInstance().ParseDeletedCustomZoneSetsFromTmpFile(ZoneWindowUtils::GetCustomZoneSetsTmpPath()); JSONHelpers::FancyZonesDataInstance().ParseCustomZoneSetFromTmpFile(ZoneWindowUtils::GetAppliedZoneSetTmpPath()); JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData(); - // Update zone sets for currently active work areas. - for (auto& [monitor, zoneWindow] : m_zoneWindowMap) + + for (auto workArea : m_workAreaHandler.GetAllWorkAreas()) { - zoneWindow->UpdateActiveZoneSet(); + workArea->UpdateActiveZoneSet(); } if (m_settings->GetSettings()->zoneSetChange_moveWindows) { @@ -974,9 +906,8 @@ bool FancyZones::ProcessSnapHotkey() noexcept const HMONITOR monitor = MonitorFromWindow(GetForegroundWindow(), MONITOR_DEFAULTTONULL); if (monitor) { - auto zoneWindow = m_zoneWindowMap.find(monitor); - if (zoneWindow != m_zoneWindowMap.end() && - zoneWindow->second->ActiveZoneSet()) + auto zoneWindow = m_workAreaHandler.GetWorkArea(m_currentDesktopId, monitor); + if (zoneWindow->ActiveZoneSet() != nullptr) { return true; } @@ -1001,9 +932,10 @@ std::vector> FancyZones::GetRawMonitorData() noexcept std::shared_lock readLock(m_lock); std::vector> monitorInfo; - for (const auto& [monitor, window] : m_zoneWindowMap) + const auto& activeWorkAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId); + for (const auto& [monitor, workArea] : activeWorkAreaMap) { - if (window->ActiveZoneSet() != nullptr) + if (workArea->ActiveZoneSet() != nullptr) { MONITORINFOEX mi; mi.cbSize = sizeof(mi); diff --git a/src/modules/fancyzones/lib/FancyZones.h b/src/modules/fancyzones/lib/FancyZones.h index 143e082d84..5dc8fdbebc 100644 --- a/src/modules/fancyzones/lib/FancyZones.h +++ b/src/modules/fancyzones/lib/FancyZones.h @@ -72,10 +72,6 @@ interface __declspec(uuid("{5C8D99D6-34B2-4F4A-A8E5-7483F6869775}")) IZoneWindow * @returns Color used to highlight zone while giving zone layout hints. */ IFACEMETHOD_(COLORREF, GetZoneHighlightColor)() = 0; - /** - * @returns ZoneWindow (representing work area) currently being processed. - */ - IFACEMETHOD_(IZoneWindow*, GetParentZoneWindow) (HMONITOR monitor) = 0; /** * @returns Integer in range [0, 100] indicating opacity of highlighted zone (while giving zone layout hints). */ diff --git a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj index fd9e7c6df1..27ef3c88e9 100644 --- a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj @@ -101,6 +101,7 @@ + @@ -116,6 +117,7 @@ + Create diff --git a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters index de21273593..9f52e02bfe 100644 --- a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters +++ b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters @@ -54,6 +54,9 @@ Header Files + + Header Files + @@ -92,6 +95,9 @@ Source Files + + Source Files + diff --git a/src/modules/fancyzones/lib/JsonHelpers.cpp b/src/modules/fancyzones/lib/JsonHelpers.cpp index 69f719caef..e95e2c4ee3 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.cpp +++ b/src/modules/fancyzones/lib/JsonHelpers.cpp @@ -356,10 +356,6 @@ namespace JSONHelpers mapEntry.key() = replaceDesktopId(id); deviceInfoMap.insert(std::move(mapEntry)); } - if (activeDeviceId == DEFAULT_GUID) - { - activeDeviceId = replaceDesktopId(activeDeviceId); - } SaveFancyZonesData(); } @@ -552,16 +548,11 @@ namespace JSONHelpers { if (auto deviceInfo = DeviceInfoJSON::FromJson(zoneSetJson.value()); deviceInfo.has_value()) { - activeDeviceId = deviceInfo->deviceId; - deviceInfoMap[activeDeviceId] = std::move(deviceInfo->data); + deviceInfoMap[deviceInfo->deviceId] = std::move(deviceInfo->data); DeleteTmpFile(tmpFilePath); } } } - else - { - activeDeviceId.clear(); - } } bool FancyZonesData::ParseCustomZoneSetFromTmpFile(std::wstring_view tmpFilePath) diff --git a/src/modules/fancyzones/lib/JsonHelpers.h b/src/modules/fancyzones/lib/JsonHelpers.h index ccd4d3aabc..08cfb3c80d 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.h +++ b/src/modules/fancyzones/lib/JsonHelpers.h @@ -189,12 +189,6 @@ namespace JSONHelpers std::optional FindCustomZoneSet(const std::wstring& guid) const; - inline const std::wstring GetActiveDeviceId() const - { - std::scoped_lock lock{ dataLock }; - return activeDeviceId; - } - inline const std::unordered_map& GetDeviceInfoMap() const { std::scoped_lock lock{ dataLock }; @@ -219,7 +213,6 @@ namespace JSONHelpers appZoneHistoryMap.clear(); deviceInfoMap.clear(); customZoneSetsMap.clear(); - activeDeviceId.clear(); } inline void SetDeviceInfo(const std::wstring& deviceId, DeviceInfoData data) @@ -234,12 +227,6 @@ namespace JSONHelpers } #endif - inline void SetActiveDeviceId(const std::wstring& deviceId) - { - std::scoped_lock lock{ dataLock }; - activeDeviceId = deviceId; - } - inline bool DeleteTmpFile(std::wstring_view tmpFilePath) const { return DeleteFileW(tmpFilePath.data()); @@ -283,7 +270,6 @@ namespace JSONHelpers std::unordered_map deviceInfoMap{}; std::unordered_map customZoneSetsMap{}; - std::wstring activeDeviceId; std::wstring jsonFilePath; std::wstring appZoneHistoryFilePath; }; diff --git a/src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp b/src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp new file mode 100644 index 0000000000..9b51dc26fc --- /dev/null +++ b/src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp @@ -0,0 +1,104 @@ +#include "pch.h" +#include "MonitorWorkAreaHandler.h" +#include "VirtualDesktopUtils.h" + +winrt::com_ptr MonitorWorkAreaHandler::GetWorkArea(const GUID& desktopId, HMONITOR monitor) +{ + auto desktopIt = workAreaMap.find(desktopId); + if (desktopIt != std::end(workAreaMap)) + { + auto& perDesktopData = desktopIt->second; + auto monitorIt = perDesktopData.find(monitor); + if (monitorIt != std::end(perDesktopData)) + { + return monitorIt->second; + } + } + return nullptr; +} + +winrt::com_ptr MonitorWorkAreaHandler::GetWorkArea(HWND window) +{ + HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL); + GUID desktopId{}; + if (monitor && VirtualDesktopUtils::GetWindowDesktopId(window, &desktopId)) + { + return GetWorkArea(desktopId, monitor); + } + return nullptr; +} + +const std::unordered_map>& MonitorWorkAreaHandler::GetWorkAreasByDesktopId(const GUID& desktopId) +{ + if (workAreaMap.contains(desktopId)) + { + return workAreaMap[desktopId]; + } + return {}; +} + +std::vector> MonitorWorkAreaHandler::GetAllWorkAreas() +{ + std::vector> workAreas{}; + for (const auto& [desktopId, perDesktopData] : workAreaMap) + { + std::transform(std::begin(perDesktopData), + std::end(perDesktopData), + std::back_inserter(workAreas), + [](const auto& item) { return item.second; }); + } + return workAreas; +} + +void MonitorWorkAreaHandler::AddWorkArea(const GUID& desktopId, HMONITOR monitor, winrt::com_ptr& workArea) +{ + if (!workAreaMap.contains(desktopId)) + { + workAreaMap[desktopId] = {}; + } + auto& perDesktopData = workAreaMap[desktopId]; + perDesktopData[monitor] = std::move(workArea); +} + +bool MonitorWorkAreaHandler::IsNewWorkArea(const GUID& desktopId, HMONITOR monitor) +{ + if (workAreaMap.contains(desktopId)) + { + const auto& perDesktopData = workAreaMap[desktopId]; + if (perDesktopData.contains(monitor)) + { + return false; + } + } + return true; +} + +void MonitorWorkAreaHandler::RegisterUpdates(const std::vector& active, std::vector& deleted) +{ + std::unordered_set activeVirtualDesktops(std::begin(active), std::end(active)); + for (auto desktopIt = std::begin(workAreaMap); desktopIt != std::end(workAreaMap);) + { + auto activeIt = activeVirtualDesktops.find(desktopIt->first); + if (activeIt == std::end(activeVirtualDesktops)) + { + // register deleted virtual desktop + deleted.push_back(desktopIt->first); + desktopIt = workAreaMap.erase(desktopIt); + } + else + { + activeVirtualDesktops.erase(desktopIt->first); // virtual desktop already in map, skip it + ++desktopIt; + } + } + // register new virtual desktops, if any + for (const auto& id : activeVirtualDesktops) + { + workAreaMap[id] = {}; + } +} + +void MonitorWorkAreaHandler::Clear() +{ + workAreaMap.clear(); +} diff --git a/src/modules/fancyzones/lib/MonitorWorkAreaHandler.h b/src/modules/fancyzones/lib/MonitorWorkAreaHandler.h new file mode 100644 index 0000000000..7b00f377bd --- /dev/null +++ b/src/modules/fancyzones/lib/MonitorWorkAreaHandler.h @@ -0,0 +1,93 @@ +#pragma once + +interface IZoneWindow; + +namespace std +{ + template<> + struct hash + { + size_t operator()(const GUID& Value) const + { + RPC_STATUS status = RPC_S_OK; + return ::UuidHash(&const_cast(Value), &status); + } + }; +} + +class MonitorWorkAreaHandler +{ +public: + /** + * Get work area based on virtual desktop id and monitor handle. + * + * @param[in] desktopId Virtual desktop identifier. + * @param[in] monitor Monitor handle. + * + * @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). + */ + winrt::com_ptr GetWorkArea(const GUID& desktopId, HMONITOR monitor); + + /** + * Get work area on which specified window is located. + * + * @param[in] window Window handle. + * + * @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). + */ + winrt::com_ptr GetWorkArea(HWND window); + + /** + * Get map of all work areas on single virtual desktop. Key in the map is monitor handle, while value + * represents single work area. + * + * @param[in] desktopId Virtual desktop identifier. + * + * @returns Map containing pairs of monitor and work area for that monitor (within same virtual desktop). + */ + const std::unordered_map>& GetWorkAreasByDesktopId(const GUID& desktopId); + + /** + * @returns All registered work areas. + */ + std::vector> GetAllWorkAreas(); + + /** + * Register new work area. + * + * @param[in] desktopId Virtual desktop identifier. + * @param[in] monitor Monitor handle. + * @param[in] workAra Object representing single work area. + */ + void AddWorkArea(const GUID& desktopId, HMONITOR monitor, winrt::com_ptr& workArea); + + /** + * Check if work area is already registered. + * + * @param[in] desktopId Virtual desktop identifier. + * @param[in] monitor Monitor handle. + * + * @returns Boolean indicating whether work area defined by virtual desktop id and monitor is already registered. + */ + bool IsNewWorkArea(const GUID& desktopId, HMONITOR monitor); + + /** + * Register changes in current virtual desktop layout. + * + * @param[in] active Array of currently active virtual desktop identifiers. + * @param[out] deleted Array of virtual desktop identifiers belonging to previously registered but now deleted + * work areas. + */ + void RegisterUpdates(const std::vector& active, std::vector& deleted); + + /** + * Clear all persisted work area related data. + */ + void Clear(); + +private: + // Work area is uniquely defined by monitor and virtual desktop id. + std::unordered_map>> workAreaMap; +}; diff --git a/src/modules/fancyzones/lib/WindowMoveHandler.cpp b/src/modules/fancyzones/lib/WindowMoveHandler.cpp index d5aadcb88e..a545228df0 100644 --- a/src/modules/fancyzones/lib/WindowMoveHandler.cpp +++ b/src/modules/fancyzones/lib/WindowMoveHandler.cpp @@ -60,12 +60,12 @@ public: return m_inMoveSize; } - void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; - void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; - void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; + void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; + void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; + void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; - void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector& indexSet, const std::map>& zoneWindowMap) noexcept; - bool MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map>& zoneWindowMap); + void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector& indexSet, winrt::com_ptr zoneWindow) noexcept; + bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr zoneWindow); private: void UpdateDragState(HWND window) noexcept; @@ -101,32 +101,32 @@ bool WindowMoveHandler::IsDragEnabled() const noexcept return pimpl->IsDragEnabled(); } -void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap); } -void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { pimpl->MoveSizeUpdate(monitor, ptScreen, zoneWindowMap); } -void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { pimpl->MoveSizeEnd(window, ptScreen, zoneWindowMap); } -void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector& indexSet, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector& indexSet, winrt::com_ptr zoneWindow) noexcept { - pimpl->MoveWindowIntoZoneByIndexSet(window, monitor, indexSet, zoneWindowMap); + pimpl->MoveWindowIntoZoneByIndexSet(window, indexSet, zoneWindow); } -bool WindowMoveHandler::MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map>& zoneWindowMap) +bool WindowMoveHandler::MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr zoneWindow) { - return pimpl->MoveWindowIntoZoneByDirection(monitor, window, vkCode, cycle, zoneWindowMap); + return pimpl->MoveWindowIntoZoneByDirection(window, vkCode, cycle, zoneWindow); } -void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { if (!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent()) { @@ -178,7 +178,7 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN } } -void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { if (!m_inMoveSize) { @@ -239,7 +239,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS } } -void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept { if (window != m_windowMoveSize && !IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray)) { @@ -288,41 +288,17 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c } } -void WindowMoveHandlerPrivate::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector& indexSet, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandlerPrivate::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector& indexSet, winrt::com_ptr zoneWindow) noexcept { if (window != m_windowMoveSize) { - const HMONITOR hm = (monitor != nullptr) ? monitor : MonitorFromWindow(window, MONITOR_DEFAULTTONULL); - if (hm) - { - auto zoneWindow = zoneWindowMap.find(hm); - if (zoneWindow != zoneWindowMap.end()) - { - const auto& zoneWindowPtr = zoneWindow->second; - // Only process windows located on currently active work area. - GUID windowDesktopId{}; - GUID zoneWindowDesktopId{}; - if (VirtualDesktopUtils::GetWindowDesktopId(window, &windowDesktopId) && - VirtualDesktopUtils::GetZoneWindowDesktopId(zoneWindowPtr.get(), &zoneWindowDesktopId) && - (windowDesktopId != zoneWindowDesktopId)) - { - return; - } - zoneWindowPtr->MoveWindowIntoZoneByIndexSet(window, indexSet); - } - } + zoneWindow->MoveWindowIntoZoneByIndexSet(window, indexSet); } } -bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map>& zoneWindowMap) +bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr zoneWindow) { - auto iter = zoneWindowMap.find(monitor); - if (iter != std::end(zoneWindowMap)) - { - const auto& zoneWindowPtr = iter->second; - return zoneWindowPtr->MoveWindowIntoZoneByDirection(window, vkCode, cycle); - } - return false; + return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirection(window, vkCode, cycle); } void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept diff --git a/src/modules/fancyzones/lib/WindowMoveHandler.h b/src/modules/fancyzones/lib/WindowMoveHandler.h index 0a5851e918..9b7937c683 100644 --- a/src/modules/fancyzones/lib/WindowMoveHandler.h +++ b/src/modules/fancyzones/lib/WindowMoveHandler.h @@ -12,12 +12,12 @@ public: bool InMoveSize() const noexcept; bool IsDragEnabled() const noexcept; - void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; - void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; - void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map>& zoneWindowMap) noexcept; + void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; + void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; + void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map>& zoneWindowMap) noexcept; - void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector& indexSet, const std::map>& zoneWindowMap) noexcept; - bool MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map>& zoneWindowMap); + void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector& indexSet, winrt::com_ptr zoneWindow) noexcept; + bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr zoneWindow); private: class WindowMoveHandlerPrivate* pimpl; diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index 556637da51..83cfc33922 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -204,7 +204,7 @@ public: ZoneWindow(HINSTANCE hinstance); ~ZoneWindow(); - bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea); + bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones); IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept; IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept; @@ -240,8 +240,7 @@ protected: static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept; private: - void LoadSettings() noexcept; - void InitializeZoneSets(bool newWorkArea) noexcept; + void InitializeZoneSets(const std::wstring& parentUniqueId) noexcept; void CalculateZoneSet() noexcept; void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept; LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept; @@ -296,7 +295,7 @@ ZoneWindow::~ZoneWindow() Gdiplus::GdiplusShutdown(gdiplusToken); } -bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) +bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) { m_host.copy_from(host); @@ -314,8 +313,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit StringCchPrintf(m_workArea, ARRAYSIZE(m_workArea), L"%d_%d", monitorRect.width(), monitorRect.height()); m_uniqueId = uniqueId; - LoadSettings(); - InitializeZoneSets(newWorkArea); + InitializeZoneSets(parentUniqueId); m_window = wil::unique_hwnd{ CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones_ZoneWindow", L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this) @@ -550,18 +548,13 @@ ZoneWindow::UpdateActiveZoneSet() noexcept #pragma region private -void ZoneWindow::LoadSettings() noexcept +void ZoneWindow::InitializeZoneSets(const std::wstring& parentUniqueId) noexcept { + // If there is not defined zone layout for this work area, created default entry. JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId); -} - -void ZoneWindow::InitializeZoneSets(bool newWorkArea) noexcept -{ - auto parent = m_host->GetParentZoneWindow(m_monitor); - if (newWorkArea && parent) + if (!parentUniqueId.empty()) { - // Update device info with device info from parent virtual desktop (if empty). - JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parent->UniqueId(), m_uniqueId); + JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parentUniqueId, m_uniqueId); } CalculateZoneSet(); } @@ -570,12 +563,6 @@ void ZoneWindow::CalculateZoneSet() noexcept { const auto& fancyZonesData = JSONHelpers::FancyZonesDataInstance(); const auto deviceInfoData = fancyZonesData.FindDeviceInfo(m_uniqueId); - const auto& activeDeviceId = fancyZonesData.GetActiveDeviceId(); - - if (!activeDeviceId.empty() && activeDeviceId != m_uniqueId) - { - return; - } if (!deviceInfoData.has_value()) { @@ -799,10 +786,10 @@ LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam, DefWindowProc(window, message, wparam, lparam); } -winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept +winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) noexcept { auto self = winrt::make_self(hinstance); - if (self->Init(host, hinstance, monitor, uniqueId, flashZones, newWorkArea)) + if (self->Init(host, hinstance, monitor, uniqueId, parentUniqueId, flashZones)) { return self; } diff --git a/src/modules/fancyzones/lib/ZoneWindow.h b/src/modules/fancyzones/lib/ZoneWindow.h index ebe2a77d40..650ddd951b 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.h +++ b/src/modules/fancyzones/lib/ZoneWindow.h @@ -110,4 +110,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow }; winrt::com_ptr MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, - const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept; + const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) noexcept; diff --git a/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp index cbb8f8b807..f742fc063d 100644 --- a/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp @@ -256,18 +256,6 @@ namespace FancyZonesUnitTests Assert::AreEqual(expected, m_zoneWindowHost->isMakeDraggedWindowTransparentActive()); } - - TEST_METHOD (GetCurrentMonitorZoneSetEmpty) - { - const auto* actual = m_zoneWindowHost->GetParentZoneWindow(Mocks::Monitor()); - Assert::IsNull(actual); - } - - TEST_METHOD (GetCurrentMonitorZoneSetNullMonitor) - { - const auto* actual = m_zoneWindowHost->GetParentZoneWindow(nullptr); - Assert::IsNull(actual); - } }; TEST_CLASS (FancyZonesIFancyZonesCallbackUnitTests) diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp index 73f42811ea..bf3accf9f5 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp @@ -121,7 +121,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); } void testZoneWindow(winrt::com_ptr zoneWindow) @@ -137,14 +137,14 @@ namespace FancyZonesUnitTests public: TEST_METHOD(CreateZoneWindow) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(m_zoneWindow); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); } TEST_METHOD(CreateZoneWindowNoHinst) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(m_zoneWindow); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); @@ -152,7 +152,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoHinstFlashZones) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(m_zoneWindow); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); @@ -160,7 +160,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoMonitor) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), {}, false); Assert::IsNull(m_zoneWindow.get()); Assert::IsNotNull(m_hostPtr); @@ -168,7 +168,7 @@ namespace FancyZonesUnitTests TEST_METHOD(CreateZoneWindowNoMonitorFlashZones) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), {}, false); Assert::IsNull(m_zoneWindow.get()); Assert::IsNotNull(m_hostPtr); @@ -178,7 +178,7 @@ namespace FancyZonesUnitTests { // Generate unique id without device id std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str()); - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, {}, false); const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom); const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId; @@ -194,7 +194,7 @@ namespace FancyZonesUnitTests { // Generate unique id without virtual desktop id std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr); - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, {}, false); const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom); Assert::IsNotNull(m_zoneWindow.get()); @@ -221,7 +221,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(actual); @@ -245,7 +245,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(actual); @@ -281,7 +281,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(actual); @@ -328,7 +328,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(actual); @@ -375,7 +375,7 @@ namespace FancyZonesUnitTests m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath); //temp file read on initialization - auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); testZoneWindow(actual); @@ -396,11 +396,11 @@ namespace FancyZonesUnitTests const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount }; m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo); - auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false); + auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), {}, false); m_zoneWindowHost->m_zoneWindow = parentZoneWindow.get(); // newWorkArea = true - zoneWindow will be cloned from parent - auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, true); + auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), m_parentUniqueId.str(), false); Assert::IsNotNull(actualZoneWindow->ActiveZoneSet()); const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones(); @@ -425,11 +425,11 @@ namespace FancyZonesUnitTests const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount }; m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo); - auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false); + auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), {}, false); m_zoneWindowHost->m_zoneWindow = parentZoneWindow.get(); // newWorkArea = false - zoneWindow won't be cloned from parent - auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); Assert::IsNull(actualZoneWindow->ActiveZoneSet()); @@ -445,7 +445,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEnter) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = S_OK; const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true); @@ -456,7 +456,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEnterTwice) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = E_INVALIDARG; @@ -469,7 +469,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdate) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = S_OK; const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true); @@ -480,7 +480,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = S_OK; const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true); @@ -491,7 +491,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeUpdatePointBigCoordinates) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = S_OK; const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true); @@ -535,7 +535,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndDifferentWindows) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto window = Mocks::Window(); m_zoneWindow->MoveSizeEnter(window, true); @@ -548,7 +548,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveSizeEndWindowNotSet) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); const auto expected = E_INVALIDARG; const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 }); @@ -575,7 +575,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0); @@ -593,7 +593,7 @@ namespace FancyZonesUnitTests TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0); @@ -631,7 +631,7 @@ namespace FancyZonesUnitTests TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet) { - m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false); + m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false); Assert::IsNull(m_zoneWindow->ActiveZoneSet()); m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());