diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index 5e15f3065..efa70c88f 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -363,10 +363,10 @@ FancyZones::WindowCreated(HWND window) noexcept wil::unique_cotaskmem_string guidString; if (SUCCEEDED(StringFromCLSID(activeZoneSet->Id(), &guidString))) { - int zoneIndex = fancyZonesData.GetAppLastZoneIndex(window, zoneWindow->UniqueId(), guidString.get()); - if (zoneIndex != -1) + std::vector zoneIndexSet = fancyZonesData.GetAppLastZoneIndexSet(window, zoneWindow->UniqueId(), guidString.get()); + if (zoneIndexSet.size()) { - m_windowMoveHandler.MoveWindowIntoZoneByIndex(window, monitor, zoneIndex, m_zoneWindowMap); + m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, monitor, zoneIndexSet, m_zoneWindowMap); break; } } @@ -790,13 +790,22 @@ void FancyZones::UpdateZoneWindows() noexcept void FancyZones::UpdateWindowsPositions() noexcept { auto callback = [](HWND window, LPARAM data) -> BOOL { - int i = static_cast(reinterpret_cast(::GetProp(window, ZONE_STAMP))); - if (i != 0) + size_t bitmask = reinterpret_cast(::GetProp(window, MULTI_ZONE_STAMP)); + + if (bitmask != 0) { - // i is off by 1 since 0 is special. + std::vector indexSet; + for (int i = 0; i < std::numeric_limits::digits; i++) + { + if ((1ull << i) & bitmask) + { + indexSet.push_back(i); + } + } + auto strongThis = reinterpret_cast(data); std::unique_lock writeLock(strongThis->m_lock); - strongThis->m_windowMoveHandler.MoveWindowIntoZoneByIndex(window, nullptr, i - 1, strongThis->m_zoneWindowMap); + strongThis->m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, nullptr, indexSet, strongThis->m_zoneWindowMap); } return TRUE; }; diff --git a/src/modules/fancyzones/lib/JsonHelpers.cpp b/src/modules/fancyzones/lib/JsonHelpers.cpp index d5826485e..d4b595411 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.cpp +++ b/src/modules/fancyzones/lib/JsonHelpers.cpp @@ -23,6 +23,7 @@ namespace constexpr int c_blankCustomModelId = 0xFFFA; const wchar_t* FANCY_ZONES_DATA_FILE = L"zones-settings.json"; + const wchar_t* FANCY_ZONES_APP_ZONE_HISTORY_FILE = L"app-zone-history.json"; const wchar_t* DEFAULT_GUID = L"{00000000-0000-0000-0000-000000000000}"; const wchar_t* REG_SETTINGS = L"Software\\SuperFancyZones"; @@ -221,6 +222,7 @@ namespace JSONHelpers { std::wstring result = PTSettingsHelper::get_module_save_folder_location(L"FancyZones"); jsonFilePath = result + L"\\" + std::wstring(FANCY_ZONES_DATA_FILE); + appZoneHistoryFilePath = result + L"\\" + std::wstring(FANCY_ZONES_APP_ZONE_HISTORY_FILE); } json::JsonObject FancyZonesData::GetPersistFancyZonesJSON() @@ -232,6 +234,18 @@ namespace JSONHelpers auto result = json::from_file(save_file_path); if (result) { + if (!result->HasKey(L"app-zone-history")) + { + auto appZoneHistory = json::from_file(appZoneHistoryFilePath); + if (appZoneHistory) + { + result->SetNamedValue(L"app-zone-history", appZoneHistory->GetNamedArray(L"app-zone-history")); + } + else + { + result->SetNamedValue(L"app-zone-history", json::JsonArray()); + } + } return *result; } else @@ -368,7 +382,7 @@ namespace JSONHelpers SaveFancyZonesData(); } - int FancyZonesData::GetAppLastZoneIndex(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const + std::vector FancyZonesData::GetAppLastZoneIndexSet(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const { std::scoped_lock lock{ dataLock }; auto processPath = get_process_path(window); @@ -380,12 +394,12 @@ namespace JSONHelpers const auto& data = history->second; if (data.zoneSetUuid == zoneSetId && data.deviceId == deviceId) { - return history->second.zoneIndex; + return history->second.zoneIndexSet; } } } - return -1; + return {}; } bool FancyZonesData::RemoveAppLastZone(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) @@ -410,7 +424,7 @@ namespace JSONHelpers return false; } - bool FancyZonesData::SetAppLastZone(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, int zoneIndex) + bool FancyZonesData::SetAppLastZones(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, const std::vector& zoneIndexSet) { std::scoped_lock lock{ dataLock }; auto processPath = get_process_path(window); @@ -419,7 +433,7 @@ namespace JSONHelpers return false; } - appZoneHistoryMap[processPath] = AppZoneHistoryData{ .zoneSetUuid = zoneSetId, .deviceId = deviceId, .zoneIndex = zoneIndex }; + appZoneHistoryMap[processPath] = AppZoneHistoryData{ .zoneSetUuid = zoneSetId, .deviceId = deviceId, .zoneIndexSet = zoneIndexSet }; SaveFancyZonesData(); return true; } @@ -669,8 +683,9 @@ namespace JSONHelpers { std::scoped_lock lock{ dataLock }; json::JsonObject root{}; + json::JsonObject appZoneHistoryRoot{}; - root.SetNamedValue(L"app-zone-history", SerializeAppZoneHistory()); + appZoneHistoryRoot.SetNamedValue(L"app-zone-history", SerializeAppZoneHistory()); root.SetNamedValue(L"devices", SerializeDeviceInfos()); root.SetNamedValue(L"custom-zone-sets", SerializeCustomZoneSets()); @@ -681,6 +696,7 @@ namespace JSONHelpers } json::to_file(jsonFilePath, root); + json::to_file(appZoneHistoryFilePath, appZoneHistoryRoot); } void FancyZonesData::MigrateCustomZoneSetsFromRegistry() @@ -817,7 +833,14 @@ namespace JSONHelpers json::JsonObject result{}; result.SetNamedValue(L"app-path", json::value(appZoneHistory.appPath)); - result.SetNamedValue(L"zone-index", json::value(appZoneHistory.data.zoneIndex)); + + json::JsonArray jsonIndexSet; + for (int index : appZoneHistory.data.zoneIndexSet) + { + jsonIndexSet.Append(json::value(index)); + } + + result.SetNamedValue(L"zone-index-set", jsonIndexSet); result.SetNamedValue(L"device-id", json::value(appZoneHistory.data.deviceId)); result.SetNamedValue(L"zoneset-uuid", json::value(appZoneHistory.data.zoneSetUuid)); @@ -831,7 +854,19 @@ namespace JSONHelpers AppZoneHistoryJSON result; result.appPath = zoneSet.GetNamedString(L"app-path"); - result.data.zoneIndex = static_cast(zoneSet.GetNamedNumber(L"zone-index")); + if (zoneSet.HasKey(L"zone-index-set")) + { + result.data.zoneIndexSet = {}; + for (auto& value : zoneSet.GetNamedArray(L"zone-index-set")) + { + result.data.zoneIndexSet.push_back(static_cast(value.GetNumber())); + } + } + else if (zoneSet.HasKey(L"zone-index")) + { + result.data.zoneIndexSet = { static_cast(zoneSet.GetNamedNumber(L"zone-index")) }; + } + result.data.deviceId = zoneSet.GetNamedString(L"device-id"); result.data.zoneSetUuid = zoneSet.GetNamedString(L"zoneset-uuid"); diff --git a/src/modules/fancyzones/lib/JsonHelpers.h b/src/modules/fancyzones/lib/JsonHelpers.h index 9a10bc9f0..870ab066b 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.h +++ b/src/modules/fancyzones/lib/JsonHelpers.h @@ -134,7 +134,7 @@ namespace JSONHelpers { std::wstring zoneSetUuid; std::wstring deviceId; - int zoneIndex; + std::vector zoneIndexSet; }; struct AppZoneHistoryJSON @@ -174,6 +174,12 @@ namespace JSONHelpers { return jsonFilePath; } + + inline const std::wstring& GetPersistAppZoneHistoryFilePath() const + { + return appZoneHistoryFilePath; + } + json::JsonObject GetPersistFancyZonesJSON(); std::optional FindDeviceInfo(const std::wstring& zoneWindowId) const; @@ -236,9 +242,9 @@ namespace JSONHelpers void UpdatePrimaryDesktopData(const std::wstring& desktopId); void RemoveDeletedDesktops(const std::vector& activeDesktops); - int GetAppLastZoneIndex(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const; + std::vector GetAppLastZoneIndexSet(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId) const; bool RemoveAppLastZone(HWND window, const std::wstring_view& deviceId, const std::wstring_view& zoneSetId); - bool SetAppLastZone(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, int zoneIndex); + bool SetAppLastZones(HWND window, const std::wstring& deviceId, const std::wstring& zoneSetId, const std::vector& zoneIndexSet); void SetActiveZoneSet(const std::wstring& deviceId, const ZoneSetData& zoneSet); @@ -268,6 +274,7 @@ namespace JSONHelpers std::wstring activeDeviceId; std::wstring jsonFilePath; + std::wstring appZoneHistoryFilePath; }; FancyZonesData& FancyZonesDataInstance(); diff --git a/src/modules/fancyzones/lib/Settings.h b/src/modules/fancyzones/lib/Settings.h index d4abb961e..99ab7ab20 100644 --- a/src/modules/fancyzones/lib/Settings.h +++ b/src/modules/fancyzones/lib/Settings.h @@ -1,6 +1,6 @@ #pragma once -#define ZONE_STAMP L"FancyZones_zone" +#define MULTI_ZONE_STAMP L"FancyZones_zones" #include struct Settings diff --git a/src/modules/fancyzones/lib/WindowMoveHandler.cpp b/src/modules/fancyzones/lib/WindowMoveHandler.cpp index a73f0fb2e..b17233da6 100644 --- a/src/modules/fancyzones/lib/WindowMoveHandler.cpp +++ b/src/modules/fancyzones/lib/WindowMoveHandler.cpp @@ -116,9 +116,9 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const st pimpl->MoveSizeEnd(window, ptScreen, zoneWindowMap); } -void WindowMoveHandler::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index, const std::map>& zoneWindowMap) noexcept +void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector& indexSet, const std::map>& zoneWindowMap) noexcept { - pimpl->MoveWindowIntoZoneByIndexSet(window, monitor, { index }, zoneWindowMap); + pimpl->MoveWindowIntoZoneByIndexSet(window, monitor, indexSet, zoneWindowMap); } bool WindowMoveHandler::MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map>& zoneWindowMap) @@ -256,7 +256,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c } else { - ::RemoveProp(window, ZONE_STAMP); + ::RemoveProp(window, MULTI_ZONE_STAMP); auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL); if (monitor) diff --git a/src/modules/fancyzones/lib/WindowMoveHandler.h b/src/modules/fancyzones/lib/WindowMoveHandler.h index 572990e70..0a5851e91 100644 --- a/src/modules/fancyzones/lib/WindowMoveHandler.h +++ b/src/modules/fancyzones/lib/WindowMoveHandler.h @@ -16,7 +16,7 @@ public: 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 MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index, const std::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); private: diff --git a/src/modules/fancyzones/lib/Zone.cpp b/src/modules/fancyzones/lib/Zone.cpp index 620dbae9f..16eac7afa 100644 --- a/src/modules/fancyzones/lib/Zone.cpp +++ b/src/modules/fancyzones/lib/Zone.cpp @@ -20,57 +20,16 @@ public: } IFACEMETHODIMP_(RECT) GetZoneRect() noexcept { return m_zoneRect; } - IFACEMETHODIMP_(bool) IsEmpty() noexcept { return m_windows.empty(); }; - IFACEMETHODIMP_(bool) ContainsWindow(HWND window) noexcept; - IFACEMETHODIMP_(void) AddWindowToZone(HWND window, HWND zoneWindow, bool stampZone) noexcept; - IFACEMETHODIMP_(void) RemoveWindowFromZone(HWND window, bool restoreSize) noexcept; IFACEMETHODIMP_(void) SetId(size_t id) noexcept { m_id = id; } IFACEMETHODIMP_(size_t) Id() noexcept { return m_id; } IFACEMETHODIMP_(RECT) ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept; private: - void SizeWindowToZone(HWND window, HWND zoneWindow) noexcept; - void StampZone(HWND window, bool stamp) noexcept; - RECT m_zoneRect{}; size_t m_id{}; std::map m_windows{}; }; -IFACEMETHODIMP_(bool) Zone::ContainsWindow(HWND window) noexcept -{ - return (m_windows.find(window) != m_windows.end()); -} - -IFACEMETHODIMP_(void) Zone::AddWindowToZone(HWND window, HWND zoneWindow, bool stampZone) noexcept -{ - WINDOWPLACEMENT placement; - ::GetWindowPlacement(window, &placement); - ::GetWindowRect(window, &placement.rcNormalPosition); - m_windows.emplace(std::pair(window, placement.rcNormalPosition)); - - SizeWindowToZone(window, zoneWindow); - if (stampZone) - { - StampZone(window, true); - } -} - -IFACEMETHODIMP_(void) Zone::RemoveWindowFromZone(HWND window, bool restoreSize) noexcept -{ - auto iter = m_windows.find(window); - if (iter != m_windows.end()) - { - m_windows.erase(iter); - StampZone(window, false); - } -} - -void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept -{ - SizeWindowToRect(window, ComputeActualZoneRect(window, zoneWindow)); -} - static BOOL CALLBACK saveDisplayToVector(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) { reinterpret_cast*>(data)->emplace_back(monitor); @@ -161,18 +120,6 @@ RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept return newWindowRect; } -void Zone::StampZone(HWND window, bool stamp) noexcept -{ - if (stamp) - { - SetProp(window, ZONE_STAMP, reinterpret_cast(m_id)); - } - else - { - RemoveProp(window, ZONE_STAMP); - } -} - winrt::com_ptr MakeZone(const RECT& zoneRect) noexcept { return winrt::make_self(zoneRect); diff --git a/src/modules/fancyzones/lib/Zone.h b/src/modules/fancyzones/lib/Zone.h index 8cad96647..465ae4fc3 100644 --- a/src/modules/fancyzones/lib/Zone.h +++ b/src/modules/fancyzones/lib/Zone.h @@ -9,34 +9,6 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub * @returns Zone coordinates (top-left and bottom-right corner) represented as RECT structure. */ IFACEMETHOD_(RECT, GetZoneRect)() = 0; - /** - * @returns Boolean indicating if zone is empty or there are windows assigned to it. - */ - IFACEMETHOD_(bool, IsEmpty)() = 0; - /** - * @param window Window handle. - * @returns Boolean indicating if specified window is assigned to the zone. - */ - IFACEMETHOD_(bool, ContainsWindow)(HWND window) = 0; - /** - * Assign single window to this zone. - * - * @param window Handle of window which should be assigned to zone. - * @param zoneWindow The m_window of a ZoneWindow, it's a hidden window representing the - * current monitor desktop work area. - * @param stampZone Boolean indicating weather we should add special property on the - * window. This property is used on display change to rearrange windows - * to corresponding zones. - */ - IFACEMETHOD_(void, AddWindowToZone)(HWND window, HWND zoneWindow, bool stampZone) = 0; - /** - * Remove window from this zone (if it is assigned to it). - * - * @param window Handle of window to be removed from this zone. - * @param restoreSize Boolean indicating that window should fall back to dimensions - * before assigning to this zone. - */ - IFACEMETHOD_(void, RemoveWindowFromZone)(HWND window, bool restoreSize) = 0; /** * @param id Zone identifier. */ @@ -45,7 +17,6 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub * @returns Zone identifier. */ IFACEMETHOD_(size_t, Id)() = 0; - /** * Compute the coordinates of the rectangle to which a window should be resized. * diff --git a/src/modules/fancyzones/lib/ZoneSet.cpp b/src/modules/fancyzones/lib/ZoneSet.cpp index 15c0d8a4f..b771b26d4 100644 --- a/src/modules/fancyzones/lib/ZoneSet.cpp +++ b/src/modules/fancyzones/lib/ZoneSet.cpp @@ -2,6 +2,7 @@ #include "util.h" #include "lib/ZoneSet.h" +#include "Settings.h" #include @@ -123,8 +124,8 @@ public: IFACEMETHODIMP AddZone(winrt::com_ptr zone) noexcept; IFACEMETHODIMP_(std::vector) ZonesFromPoint(POINT pt) noexcept; - IFACEMETHODIMP_(int) - GetZoneIndexFromWindow(HWND window) noexcept; + IFACEMETHODIMP_(std::vector) + GetZoneIndexSetFromWindow(HWND window) noexcept; IFACEMETHODIMP_(std::vector>) GetZones() noexcept { return m_zones; } IFACEMETHODIMP_(void) @@ -137,6 +138,8 @@ public: MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient) noexcept; IFACEMETHODIMP_(bool) CalculateZones(MONITORINFO monitorInfo, int zoneCount, int spacing) noexcept; + IFACEMETHODIMP_(bool) + IsZoneEmpty(int zoneIndex) noexcept; private: bool CalculateFocusLayout(Rect workArea, int zoneCount) noexcept; @@ -144,12 +147,11 @@ private: bool CalculateGridLayout(Rect workArea, JSONHelpers::ZoneSetLayoutType type, int zoneCount, int spacing) noexcept; bool CalculateUniquePriorityGridLayout(Rect workArea, int zoneCount, int spacing) noexcept; bool CalculateCustomLayout(Rect workArea, int spacing) noexcept; - bool CalculateGridZones(Rect workArea, JSONHelpers::GridLayoutInfo gridLayoutInfo, int spacing); - - winrt::com_ptr ZoneFromWindow(HWND window) noexcept; + void StampWindow(HWND window, size_t bitmask) noexcept; std::vector> m_zones; + std::map> m_windowIndexSet; ZoneSetConfig m_config; }; @@ -238,45 +240,23 @@ ZoneSet::ZonesFromPoint(POINT pt) noexcept return capturedZones; } -IFACEMETHODIMP_(int) -ZoneSet::GetZoneIndexFromWindow(HWND window) noexcept +std::vector ZoneSet::GetZoneIndexSetFromWindow(HWND window) noexcept { - int zoneIndex = 0; - for (auto iter = m_zones.begin(); iter != m_zones.end(); iter++, zoneIndex++) + auto it = m_windowIndexSet.find(window); + if (it == m_windowIndexSet.end()) { - if (winrt::com_ptr zone = iter->try_as()) - { - if (zone->ContainsWindow(window)) - { - return zoneIndex; - } - } + return {}; + } + else + { + return it->second; } - return -1; } IFACEMETHODIMP_(void) ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index, bool stampZone) noexcept { - if (m_zones.empty()) - { - return; - } - - if (index >= int(m_zones.size())) - { - return; - } - - while (auto zoneDrop = ZoneFromWindow(window)) - { - zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window)); - } - - if (auto zone = m_zones.at(index)) - { - zone->AddWindowToZone(window, windowZone, stampZone); - } + MoveWindowIntoZoneByIndexSet(window, windowZone, { index }, stampZone); } IFACEMETHODIMP_(void) @@ -287,19 +267,12 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::v return; } - while (auto zoneDrop = ZoneFromWindow(window)) - { - zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window)); - } - - if (indexSet.size() == 1) - { - MoveWindowIntoZoneByIndex(window, windowZone, indexSet[0], stampZone); - return; - } - RECT size; bool sizeEmpty = true; + size_t bitmask = 0; + + auto& storedIndexSet = m_windowIndexSet[window]; + storedIndexSet = {}; for (int index : indexSet) { @@ -318,12 +291,23 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::v size = newSize; sizeEmpty = false; } + + storedIndexSet.push_back(index); + } + + if (index < std::numeric_limits::digits) + { + bitmask |= 1ull << index; } } if (!sizeEmpty) { SizeWindowToRect(window, size); + if (stampZone) + { + StampWindow(window, bitmask); + } } } @@ -335,64 +319,48 @@ ZoneSet::MoveWindowIntoZoneByDirection(HWND window, HWND windowZone, DWORD vkCod return false; } - winrt::com_ptr oldZone = nullptr; - winrt::com_ptr newZone = nullptr; + auto indexSet = GetZoneIndexSetFromWindow(window); + int numZones = static_cast(m_zones.size()); - auto iter = std::find(m_zones.begin(), m_zones.end(), ZoneFromWindow(window)); - if (iter == m_zones.end()) + // The window was not assigned to any zone here + if (indexSet.size() == 0) { - iter = (vkCode == VK_RIGHT) ? m_zones.begin() : m_zones.end() - 1; - } - else if (oldZone = iter->as()) - { - if (vkCode == VK_LEFT) - { - if (iter == m_zones.begin()) - { - if (!cycle) - { - oldZone->RemoveWindowFromZone(window, false); - return false; - } - iter = m_zones.end(); - } - iter--; - } - else if (vkCode == VK_RIGHT) - { - iter++; - if (iter == m_zones.end()) - { - if (!cycle) - { - oldZone->RemoveWindowFromZone(window, false); - return false; - } - iter = m_zones.begin(); - } - } - } - - if (newZone = iter->as()) - { - if (oldZone) - { - oldZone->RemoveWindowFromZone(window, false); - } - newZone->AddWindowToZone(window, windowZone, true); + MoveWindowIntoZoneByIndexSet(window, windowZone, { vkCode == VK_LEFT ? numZones - 1 : 0 }, true); return true; } - return false; + + int oldIndex = indexSet[0]; + + // We reached the edge + if ((vkCode == VK_LEFT && oldIndex == 0) || (vkCode == VK_RIGHT && oldIndex == numZones - 1)) + { + if (!cycle) + { + MoveWindowIntoZoneByIndexSet(window, windowZone, {}, true); + return false; + } + else + { + MoveWindowIntoZoneByIndexSet(window, windowZone, { vkCode == VK_LEFT ? numZones - 1 : 0 }, true); + return true; + } + } + + // We didn't reach the edge + if (vkCode == VK_LEFT) + { + MoveWindowIntoZoneByIndexSet(window, windowZone, { oldIndex - 1 }, true); + } + else + { + MoveWindowIntoZoneByIndexSet(window, windowZone, { oldIndex + 1 }, true); + } + return true; } IFACEMETHODIMP_(void) ZoneSet::MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient) noexcept { - while (auto zoneDrop = ZoneFromWindow(window)) - { - zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window)); - } - auto zones = ZonesFromPoint(ptClient); MoveWindowIntoZoneByIndexSet(window, zoneWindow, zones, true); } @@ -435,6 +403,19 @@ ZoneSet::CalculateZones(MONITORINFO monitorInfo, int zoneCount, int spacing) noe return success; } +bool ZoneSet::IsZoneEmpty(int zoneIndex) noexcept +{ + for (auto& [window, zones] : m_windowIndexSet) + { + if (find(begin(zones), end(zones), zoneIndex) != end(zones)) + { + return false; + } + } + + return true; +} + bool ZoneSet::CalculateFocusLayout(Rect workArea, int zoneCount) noexcept { bool success = true; @@ -713,19 +694,9 @@ bool ZoneSet::CalculateGridZones(Rect workArea, JSONHelpers::GridLayoutInfo grid return success; } -winrt::com_ptr ZoneSet::ZoneFromWindow(HWND window) noexcept +void ZoneSet::StampWindow(HWND window, size_t bitmask) noexcept { - for (auto iter = m_zones.begin(); iter != m_zones.end(); iter++) - { - if (winrt::com_ptr zone = iter->try_as()) - { - if (zone->ContainsWindow(window)) - { - return zone; - } - } - } - return nullptr; + SetProp(window, MULTI_ZONE_STAMP, reinterpret_cast(bitmask)); } winrt::com_ptr MakeZoneSet(ZoneSetConfig const& config) noexcept diff --git a/src/modules/fancyzones/lib/ZoneSet.h b/src/modules/fancyzones/lib/ZoneSet.h index 41564f83a..10513b5a6 100644 --- a/src/modules/fancyzones/lib/ZoneSet.h +++ b/src/modules/fancyzones/lib/ZoneSet.h @@ -31,12 +31,12 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : */ IFACEMETHOD_(std::vector, ZonesFromPoint)(POINT pt) = 0; /** - * Get index of the zone inside zone layout by window assigned to it. + * Get index set of the zones to which the window was assigned. * - * @param window Handle of window assigned to zone. - * @returns Zone index withing zone layout. + * @param window Handle of the window. + * @returns A vector of integers, 0-based, the index set. */ - IFACEMETHOD_(int, GetZoneIndexFromWindow)(HWND window) = 0; + IFACEMETHOD_(std::vector, GetZoneIndexSetFromWindow)(HWND window) = 0; /** * @returns Array of zone objects (defining coordinates of the zone) inside this zone layout. */ @@ -95,6 +95,14 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : * @returns Boolean indicating if calculation was successful. */ IFACEMETHOD_(bool, CalculateZones)(MONITORINFO monitorInfo, int zoneCount, int spacing) = 0; + /** + * Check if the zone with the specified index is empty. Returns true if the zone does not exist. + * + * @param zoneIndex The index of of the zone within this zone set. + * + * @returns Boolean indicating whether the zone is empty. + */ + IFACEMETHOD_(bool, IsZoneEmpty)(int zoneIndex) = 0; }; #define VERSION_PERSISTEDDATA 0x0000F00D diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index 61a00577c..ec93b10d8 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -484,13 +484,13 @@ ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept { if (m_activeZoneSet) { - DWORD zoneIndex = static_cast(m_activeZoneSet->GetZoneIndexFromWindow(window)); - if (zoneIndex != -1) + auto zoneIndexSet = m_activeZoneSet->GetZoneIndexSetFromWindow(window); + if (zoneIndexSet.size()) { OLECHAR* guidString; if (StringFromCLSID(m_activeZoneSet->Id(), &guidString) == S_OK) { - JSONHelpers::FancyZonesDataInstance().SetAppLastZone(window, m_uniqueId, guidString, zoneIndex); + JSONHelpers::FancyZonesDataInstance().SetAppLastZones(window, m_uniqueId, guidString, zoneIndexSet); } CoTaskMemFree(guidString); diff --git a/src/modules/fancyzones/lib/trace.cpp b/src/modules/fancyzones/lib/trace.cpp index 2d5c22acf..dd42234c9 100644 --- a/src/modules/fancyzones/lib/trace.cpp +++ b/src/modules/fancyzones/lib/trace.cpp @@ -24,10 +24,14 @@ ZoneSetInfo GetZoneSetInfo(_In_opt_ winrt::com_ptr set) noexcept { auto zones = set->GetZones(); info.NumberOfZones = zones.size(); - info.NumberOfWindows = std::count_if(zones.cbegin(), zones.cend(), [&](winrt::com_ptr zone) + info.NumberOfWindows = 0; + for (int i = 0; i < static_cast(zones.size()); i++) { - return !zone->IsEmpty(); - }); + if (!set->IsZoneEmpty(i)) + { + info.NumberOfWindows++; + } + } } return info; } diff --git a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp index 78fc684d1..e759bce93 100644 --- a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp +++ b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp @@ -715,8 +715,8 @@ namespace FancyZonesUnitTests { TEST_METHOD (ToJson) { - AppZoneHistoryJSON appZoneHistory{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"device-id", .zoneIndex = 54321 } }; - json::JsonObject expected = json::JsonObject::Parse(L"{\"app-path\": \"appPath\", \"device-id\": \"device-id\", \"zoneset-uuid\": \"zoneset-uuid\", \"zone-index\": 54321}"); + AppZoneHistoryJSON appZoneHistory{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"device-id", .zoneIndexSet = { 54321 } } }; + json::JsonObject expected = json::JsonObject::Parse(L"{\"app-path\": \"appPath\", \"device-id\": \"device-id\", \"zoneset-uuid\": \"zoneset-uuid\", \"zone-index-set\": [54321]}"); auto actual = AppZoneHistoryJSON::ToJson(appZoneHistory); compareJsonObjects(expected, actual); @@ -724,14 +724,14 @@ namespace FancyZonesUnitTests TEST_METHOD (FromJson) { - AppZoneHistoryJSON expected{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", .zoneIndex = 54321 } }; + AppZoneHistoryJSON expected{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", .zoneIndexSet = { 54321 } } }; json::JsonObject json = json::JsonObject::Parse(L"{\"app-path\": \"appPath\", \"device-id\": \"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\", \"zoneset-uuid\": \"{33A2B101-06E0-437B-A61E-CDBECF502906}\", \"zone-index\": 54321}"); auto actual = AppZoneHistoryJSON::FromJson(json); Assert::IsTrue(actual.has_value()); Assert::AreEqual(expected.appPath.c_str(), actual->appPath.c_str()); - Assert::AreEqual(expected.data.zoneIndex, actual->data.zoneIndex); + Assert::AreEqual(expected.data.zoneIndexSet, actual->data.zoneIndexSet); Assert::AreEqual(expected.data.deviceId.c_str(), actual->data.deviceId.c_str()); Assert::AreEqual(expected.data.zoneSetUuid.c_str(), actual->data.zoneSetUuid.c_str()); } @@ -752,7 +752,7 @@ namespace FancyZonesUnitTests TEST_METHOD (FromJsonMissingKeys) { - AppZoneHistoryJSON appZoneHistory{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", .zoneIndex = 54321 } }; + AppZoneHistoryJSON appZoneHistory{ L"appPath", AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", .zoneIndexSet = { 54321 } } }; const auto json = AppZoneHistoryJSON::ToJson(appZoneHistory); auto iter = json.First(); @@ -939,14 +939,16 @@ namespace FancyZonesUnitTests { FancyZonesData data; const auto jsonPath = data.GetPersistFancyZonesJSONPath(); + const auto appZoneHistoryPath = data.GetPersistAppZoneHistoryFilePath(); auto savedJson = json::from_file(jsonPath); + auto savedAppZoneHistory = json::from_file(appZoneHistoryPath); if (std::filesystem::exists(jsonPath)) { std::filesystem::remove(jsonPath); } - json::JsonObject expected = json::JsonObject::Parse(L"{\"fancy-zones\":{\"custom-zonesets \":[{\"uuid\":\"uuid1\",\"name\":\"Custom1\",\"type\":\"custom\" }] } }"); + json::JsonObject expected = json::JsonObject::Parse(L"{\"fancy-zones\":{\"custom-zonesets \":[{\"uuid\":\"uuid1\",\"name\":\"Custom1\",\"type\":\"custom\" }] }, \"app-zone-history\":[] }"); json::to_file(jsonPath, expected); auto actual = data.GetPersistFancyZonesJSON(); @@ -960,6 +962,15 @@ namespace FancyZonesUnitTests { std::filesystem::remove(jsonPath); } + + if (savedAppZoneHistory) + { + json::to_file(appZoneHistoryPath, *savedAppZoneHistory); + } + else + { + std::filesystem::remove(appZoneHistoryPath); + } } TEST_METHOD (FancyZonesDataDeviceInfoMap) @@ -1124,7 +1135,7 @@ namespace FancyZonesUnitTests const int expectedIndex = 54321; json::JsonObject json; - AppZoneHistoryJSON expected{ expectedAppPath, AppZoneHistoryData{ .zoneSetUuid = expectedZoneSetId, .deviceId = expectedDeviceId, .zoneIndex = expectedIndex } }; + AppZoneHistoryJSON expected{ expectedAppPath, AppZoneHistoryData{ .zoneSetUuid = expectedZoneSetId, .deviceId = expectedDeviceId, .zoneIndexSet = { expectedIndex } } }; json::JsonArray zoneHistoryArray; zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(expected)); json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(zoneHistoryArray.Stringify())); @@ -1141,17 +1152,17 @@ namespace FancyZonesUnitTests const auto actualAppZoneHistory = actualProcessHistory->second; Assert::AreEqual(expectedZoneSetId.c_str(), actualAppZoneHistory.zoneSetUuid.c_str()); Assert::AreEqual(expectedDeviceId.c_str(), actualAppZoneHistory.deviceId.c_str()); - Assert::AreEqual(expectedIndex, actualAppZoneHistory.zoneIndex); + Assert::AreEqual({ expectedIndex }, actualAppZoneHistory.zoneIndexSet); } TEST_METHOD (AppZoneHistoryParseManyApps) { json::JsonObject json; json::JsonArray zoneHistoryArray; - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-1", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502900}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1530}", .zoneIndex = 1 } })); - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-2", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502901}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1531}", .zoneIndex = 2 } })); - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-3", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502902}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1532}", .zoneIndex = 3 } })); - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-4", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502903}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1533}", .zoneIndex = 4 } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-1", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502900}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1530}", .zoneIndexSet = { 1 } } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-2", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502901}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1531}", .zoneIndexSet = { 2 } } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-3", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502902}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1532}", .zoneIndexSet = { 3 } } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-4", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502903}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1533}", .zoneIndexSet = { 4 } } })); json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(zoneHistoryArray.Stringify())); @@ -1172,7 +1183,7 @@ namespace FancyZonesUnitTests const auto actual = actualProcessHistoryMap.at(expected->appPath); Assert::AreEqual(expected->data.deviceId.c_str(), actual.deviceId.c_str()); Assert::AreEqual(expected->data.zoneSetUuid.c_str(), actual.zoneSetUuid.c_str()); - Assert::AreEqual(expected->data.zoneIndex, actual.zoneIndex); + Assert::AreEqual(expected->data.zoneIndexSet, actual.zoneIndexSet); iter.MoveNext(); } @@ -1184,10 +1195,10 @@ namespace FancyZonesUnitTests json::JsonArray zoneHistoryArray; const auto appPath = L"app-path"; - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502900}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1530}", .zoneIndex = 1 } })); - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502901}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1531}", .zoneIndex = 2 } })); - zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502902}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1532}", .zoneIndex = 3 } })); - const auto expected = AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502903}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1533}", .zoneIndex = 4 }; + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502900}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1530}", .zoneIndexSet = { 1 } } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502901}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1531}", .zoneIndexSet = { 2 } } })); + zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502902}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1532}", .zoneIndexSet = { 3 } } })); + const auto expected = AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502903}", .deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1533}", .zoneIndexSet = { 4 } }; zoneHistoryArray.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, expected })); json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(zoneHistoryArray.Stringify())); @@ -1200,7 +1211,7 @@ namespace FancyZonesUnitTests const auto actual = actualProcessHistoryMap.at(appPath); Assert::AreEqual(expected.deviceId.c_str(), actual.deviceId.c_str()); Assert::AreEqual(expected.zoneSetUuid.c_str(), actual.zoneSetUuid.c_str()); - Assert::AreEqual(expected.zoneIndex, actual.zoneIndex); + Assert::AreEqual(expected.zoneIndexSet, actual.zoneIndexSet); } TEST_METHOD (AppZoneHistoryParseEmpty) @@ -1216,7 +1227,7 @@ namespace FancyZonesUnitTests { const std::wstring appPath = L"appPath"; json::JsonObject json; - AppZoneHistoryJSON expected{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"device-id", .zoneIndex = 54321 } }; + AppZoneHistoryJSON expected{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"device-id", .zoneIndexSet = { 54321 } } }; json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(AppZoneHistoryJSON::ToJson(expected).Stringify())); FancyZonesData data; @@ -1229,7 +1240,7 @@ namespace FancyZonesUnitTests { const std::wstring appPath = L"appPath"; json::JsonObject json; - AppZoneHistoryJSON expected{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"device-id", .zoneIndex = 54321 } }; + AppZoneHistoryJSON expected{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"zoneset-uuid", .deviceId = L"device-id", .zoneIndexSet = { 54321 } } }; json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(AppZoneHistoryJSON::ToJson(expected).Stringify())); FancyZonesData data; @@ -1242,7 +1253,7 @@ namespace FancyZonesUnitTests { const std::wstring appPath = L"appPath"; json::JsonArray expected; - expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{39B25DD2-130D-4B5D-8851-4791D66B1539}", .deviceId = m_defaultDeviceId, .zoneIndex = 54321 } })); + expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ appPath, AppZoneHistoryData{ .zoneSetUuid = L"{39B25DD2-130D-4B5D-8851-4791D66B1539}", .deviceId = m_defaultDeviceId, .zoneIndexSet = { 54321 } } })); json::JsonObject json; json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(expected.Stringify())); @@ -1257,10 +1268,10 @@ namespace FancyZonesUnitTests { json::JsonObject json; json::JsonArray expected; - expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-1", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndex = 54321 } })); - expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-2", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndex = 54321 } })); - expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-3", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndex = 54321 } })); - expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-4", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndex = 54321 } })); + expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-1", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndexSet = { 54321 } } })); + expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-2", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndexSet = { 54321 } } })); + expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-3", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndexSet = { 54321 } } })); + expected.Append(AppZoneHistoryJSON::ToJson(AppZoneHistoryJSON{ L"app-path-4", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = m_defaultDeviceId, .zoneIndexSet = { 54321 } } })); json.SetNamedValue(L"app-zone-history", json::JsonValue::Parse(expected.Stringify())); FancyZonesData data; @@ -1590,7 +1601,7 @@ namespace FancyZonesUnitTests .columnsPercents = { 2500, 5000, 2500 }, .cellChildMap = { { 0, 1, 2 } } })); CustomZoneSetJSON zoneSets{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", CustomZoneSetData{ L"name", CustomLayoutType::Grid, grid } }; - AppZoneHistoryJSON appZoneHistory{ L"app-path", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"device-id", .zoneIndex = 54321 } }; + AppZoneHistoryJSON appZoneHistory{ L"app-path", AppZoneHistoryData{ .zoneSetUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}", .deviceId = L"device-id", .zoneIndexSet = { 54321 } } }; DeviceInfoJSON deviceInfo{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 } }; json::JsonArray zoneSetsArray, appZonesArray, deviceInfoArray; zoneSetsArray.Append(CustomZoneSetJSON::ToJson(zoneSets)); @@ -1761,11 +1772,11 @@ namespace FancyZonesUnitTests const auto window = Mocks::WindowCreate(m_hInst); FancyZonesData data; - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); const int expectedZoneIndex = 10; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex } )); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneIndexZero) @@ -1776,8 +1787,8 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = 0; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex })); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneIndexNegative) @@ -1788,8 +1799,8 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = -1; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex })); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneIndexOverflow) @@ -1800,8 +1811,8 @@ namespace FancyZonesUnitTests FancyZonesData data; const long expectedZoneIndex = LONG_MAX; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(static_cast(expectedZoneIndex), data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex })); + Assert::AreEqual({ static_cast(expectedZoneIndex) }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneIndexOverride) @@ -1812,10 +1823,10 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = 3; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, 1)); - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, 2)); - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { 1 })); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { 2 })); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex })); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneInvalidWindow) @@ -1825,10 +1836,10 @@ namespace FancyZonesUnitTests const auto window = Mocks::Window(); FancyZonesData data; - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); const int expectedZoneIndex = 1; - Assert::IsFalse(data.SetAppLastZone(window, deviceId, zoneSetId, expectedZoneIndex)); + Assert::IsFalse(data.SetAppLastZones(window, deviceId, zoneSetId, { expectedZoneIndex })); } TEST_METHOD (AppLastZoneNullWindow) @@ -1838,7 +1849,7 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = 1; - Assert::IsFalse(data.SetAppLastZone(window, L"device-id", zoneSetId, expectedZoneIndex)); + Assert::IsFalse(data.SetAppLastZones(window, L"device-id", zoneSetId, { expectedZoneIndex })); } TEST_METHOD (AppLastdeviceIdTest) @@ -1850,9 +1861,9 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = 10; - Assert::IsTrue(data.SetAppLastZone(window, deviceId1, zoneSetId, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId1, zoneSetId)); - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId2, zoneSetId)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId1, zoneSetId, { expectedZoneIndex })); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId1, zoneSetId)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId2, zoneSetId)); } TEST_METHOD (AppLastZoneSetIdTest) @@ -1864,9 +1875,9 @@ namespace FancyZonesUnitTests FancyZonesData data; const int expectedZoneIndex = 10; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId1, expectedZoneIndex)); - Assert::AreEqual(expectedZoneIndex, data.GetAppLastZoneIndex(window, deviceId, zoneSetId1)); - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId, zoneSetId2)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId1, { expectedZoneIndex })); + Assert::AreEqual({ expectedZoneIndex }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId1)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId2)); } TEST_METHOD (AppLastZoneRemoveWindow) @@ -1876,9 +1887,9 @@ namespace FancyZonesUnitTests const auto window = Mocks::WindowCreate(m_hInst); FancyZonesData data; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetId, 1)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetId, { 1 })); Assert::IsTrue(data.RemoveAppLastZone(window, deviceId, zoneSetId)); - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneRemoveUnknownWindow) @@ -1889,7 +1900,7 @@ namespace FancyZonesUnitTests FancyZonesData data; Assert::IsFalse(data.RemoveAppLastZone(window, deviceId, zoneSetId)); - Assert::AreEqual(-1, data.GetAppLastZoneIndex(window, deviceId, zoneSetId)); + Assert::AreEqual({}, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetId)); } TEST_METHOD (AppLastZoneRemoveUnknownZoneSetId) @@ -1900,9 +1911,9 @@ namespace FancyZonesUnitTests const auto window = Mocks::WindowCreate(m_hInst); FancyZonesData data; - Assert::IsTrue(data.SetAppLastZone(window, deviceId, zoneSetIdToInsert, 1)); + Assert::IsTrue(data.SetAppLastZones(window, deviceId, zoneSetIdToInsert, { 1 })); Assert::IsFalse(data.RemoveAppLastZone(window, deviceId, zoneSetIdToRemove)); - Assert::AreEqual(1, data.GetAppLastZoneIndex(window, deviceId, zoneSetIdToInsert)); + Assert::AreEqual({ 1 }, data.GetAppLastZoneIndexSet(window, deviceId, zoneSetIdToInsert)); } TEST_METHOD (AppLastZoneRemoveUnknownWindowId) @@ -1913,9 +1924,9 @@ namespace FancyZonesUnitTests const auto window = Mocks::WindowCreate(m_hInst); FancyZonesData data; - Assert::IsTrue(data.SetAppLastZone(window, deviceIdToInsert, zoneSetId, 1)); + Assert::IsTrue(data.SetAppLastZones(window, deviceIdToInsert, zoneSetId, { 1 })); Assert::IsFalse(data.RemoveAppLastZone(window, deviceIdToRemove, zoneSetId)); - Assert::AreEqual(1, data.GetAppLastZoneIndex(window, deviceIdToInsert, zoneSetId)); + Assert::AreEqual({ 1 }, data.GetAppLastZoneIndexSet(window, deviceIdToInsert, zoneSetId)); } TEST_METHOD (AppLastZoneRemoveNullWindow) diff --git a/src/modules/fancyzones/tests/UnitTests/Util.h b/src/modules/fancyzones/tests/UnitTests/Util.h index 91a9d509c..b77e11945 100644 --- a/src/modules/fancyzones/tests/UnitTests/Util.h +++ b/src/modules/fancyzones/tests/UnitTests/Util.h @@ -57,4 +57,20 @@ namespace Helpers { std::wstring GuidToString(const GUID& guid); std::wstring CreateGuidString(); -} \ No newline at end of file +} + +template<> +std::wstring Microsoft::VisualStudio::CppUnitTestFramework::ToString(const std::vector& vec) +{ + std::wstring str = L"{"; + for (size_t i = 0; i < vec.size(); i++) + { + str += std::to_wstring(vec[i]); + if (i != vec.size() - 1) + { + str += L","; + } + } + str += L"}"; + return str; +} diff --git a/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp index ae5be7c31..6c13af916 100644 --- a/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp @@ -14,23 +14,6 @@ namespace FancyZonesUnitTests RECT m_zoneRect{ 10, 10, 200, 200 }; HINSTANCE m_hInst{}; - HWND addWindow(const winrt::com_ptr& zone, bool stamp) - { - HWND window = Mocks::WindowCreate(m_hInst); - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - zone->AddWindowToZone(window, zoneWindow, stamp); - - return window; - } - - void addMany(const winrt::com_ptr& zone) - { - for (int i = 0; i < 10; i++) - { - addWindow(zone, i % 2 == 0); - } - } - TEST_METHOD_INITIALIZE(Init) { m_hInst = (HINSTANCE)GetModuleHandleW(nullptr); @@ -60,367 +43,5 @@ namespace FancyZonesUnitTests zone->SetId(id); Assert::AreEqual(zone->Id(), id); } - - TEST_METHOD(IsEmpty) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - Assert::IsTrue(zone->IsEmpty()); - } - - TEST_METHOD(IsNonEmptyStampTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - addWindow(zone, true); - - Assert::IsFalse(zone->IsEmpty()); - } - - TEST_METHOD(IsNonEmptyStampFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - addWindow(zone, false); - - Assert::IsFalse(zone->IsEmpty()); - } - - TEST_METHOD(IsNonEmptyManyWindows) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - for (int i = 0; i < 10; i++) - { - HWND window = Mocks::WindowCreate(m_hInst); - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - Assert::IsFalse(zone->IsEmpty()); - } - - TEST_METHOD(IsNonEmptyManyZoneWindows) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = Mocks::WindowCreate(m_hInst); - for (int i = 0; i < 10; i++) - { - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - Assert::IsFalse(zone->IsEmpty()); - } - - TEST_METHOD(IsNonEmptyMany) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - addMany(zone); - - Assert::IsFalse(zone->IsEmpty()); - } - - TEST_METHOD(ContainsWindowEmpty) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = Mocks::WindowCreate(m_hInst); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(ContainsWindowNot) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - addMany(zone); - - HWND newWindow = Mocks::WindowCreate(m_hInst); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(ContainsWindowStampTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND window = addWindow(zone, true); - - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(ContainsWindowStampFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND window = addWindow(zone, false); - - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(ContainsWindowManyWindows) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - std::vector windowVec{}; - for (int i = 0; i < 10; i++) - { - HWND window = Mocks::WindowCreate(m_hInst); - windowVec.push_back(window); - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - for (auto wnd : windowVec) - { - Assert::IsTrue(zone->ContainsWindow(wnd)); - } - } - - TEST_METHOD(ContainsWindowManyZoneWindows) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = Mocks::WindowCreate(m_hInst); - std::vector windowVec{}; - for (int i = 0; i < 10; i++) - { - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - windowVec.push_back(window); - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - for (auto wnd : windowVec) - { - Assert::IsTrue(zone->ContainsWindow(wnd)); - } - } - - TEST_METHOD(ContainsWindowMany) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - std::vector windowVec{}; - for (int i = 0; i < 10; i++) - { - HWND window = addWindow(zone, i % 2 == 0); - windowVec.push_back(window); - } - - for (auto wnd : windowVec) - { - Assert::IsTrue(zone->ContainsWindow(wnd)); - } - } - - TEST_METHOD(AddWindowNullptr) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = nullptr; - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - zone->AddWindowToZone(window, zoneWindow, true); - - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(AddWindowZoneNullptr) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = Mocks::WindowCreate(m_hInst); - HWND zoneWindow = nullptr; - zone->AddWindowToZone(window, zoneWindow, true); - - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(AddManySame) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - HWND window = Mocks::WindowCreate(m_hInst); - for (int i = 0; i < 10; i++) - { - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(AddManySameNullptr) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = nullptr; - HWND window = nullptr; - for (int i = 0; i < 10; i++) - { - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - Assert::IsTrue(zone->ContainsWindow(window)); - } - - TEST_METHOD(RemoveWindowRestoreSizeTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = Mocks::WindowCreate(m_hInst); - - zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true); - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(newWindow)); - - zone->RemoveWindowFromZone(newWindow, true); - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveWindowRestoreSizeFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = Mocks::WindowCreate(m_hInst); - - zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true); - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(newWindow)); - - zone->RemoveWindowFromZone(newWindow, false); - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveInvalidWindowRestoreSizeTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = Mocks::WindowCreate(m_hInst); - zone->RemoveWindowFromZone(newWindow, true); - - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveInvalidWindowRestoreSizeFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = Mocks::WindowCreate(m_hInst); - zone->RemoveWindowFromZone(newWindow, false); - - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveNullptrWindowRestoreSizeTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = nullptr; - - zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true); - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(newWindow)); - - zone->RemoveWindowFromZone(newWindow, true); - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveNullptrWindowRestoreSizeFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - HWND newWindow = nullptr; - - zone->AddWindowToZone(newWindow, Mocks::WindowCreate(m_hInst), true); - Assert::IsFalse(zone->IsEmpty()); - Assert::IsTrue(zone->ContainsWindow(newWindow)); - - zone->RemoveWindowFromZone(newWindow, false); - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(newWindow)); - } - - TEST_METHOD(RemoveMany) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - std::vector windowVec{}; - for (int i = 0; i < 10; i++) - { - HWND window = addWindow(zone, i % 2 == 0); - windowVec.push_back(window); - } - - for (auto wnd : windowVec) - { - zone->RemoveWindowFromZone(wnd, true); - } - - Assert::IsTrue(zone->IsEmpty()); - } - - TEST_METHOD(RemoveManySame) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - HWND window = Mocks::WindowCreate(m_hInst); - for (int i = 0; i < 10; i++) - { - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - zone->RemoveWindowFromZone(window, true); - - Assert::IsTrue(zone->IsEmpty()); - Assert::IsFalse(zone->ContainsWindow(window)); - } - - TEST_METHOD(RemoveDouble) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND zoneWindow = Mocks::WindowCreate(m_hInst); - HWND window = Mocks::WindowCreate(m_hInst); - for (int i = 0; i < 10; i++) - { - zone->AddWindowToZone(window, zoneWindow, i % 2 == 0); - } - - zone->RemoveWindowFromZone(window, true); - zone->RemoveWindowFromZone(window, true); - - Assert::IsTrue(zone->IsEmpty()); - } - - TEST_METHOD(StampTrue) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - size_t expected = 123456; - zone->SetId(expected); - - HWND window = addWindow(zone, true); - - HANDLE actual = GetProp(window, ZONE_STAMP); - Assert::IsNotNull(actual); - - size_t actualVal = HandleToLong(actual); - Assert::AreEqual(expected, actualVal); - } - - TEST_METHOD(StampTrueNoId) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = addWindow(zone, true); - - HANDLE actual = GetProp(window, ZONE_STAMP); - Assert::IsNull(actual); - } - - TEST_METHOD(StampFalse) - { - winrt::com_ptr zone = MakeZone(m_zoneRect); - - HWND window = addWindow(zone, false); - - HANDLE actual = GetProp(window, ZONE_STAMP); - Assert::IsNull(actual); - } }; } diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp index bbd32f483..fcd706c95 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp @@ -287,66 +287,16 @@ namespace FancyZonesUnitTests Assert::IsTrue(actual.size() == 0); } - TEST_METHOD (ZoneIndexFromWindow) - { - HWND window = Mocks::Window(); - HWND zoneWindow = Mocks::Window(); - - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 20, 20, 200, 200 }); - winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone4 = MakeZone({ 10, 10, 100, 100 }); - winrt::com_ptr zone5 = MakeZone({ 20, 20, 100, 100 }); - - zone3->AddWindowToZone(window, zoneWindow, true); - - m_set->AddZone(zone1); - m_set->AddZone(zone2); - m_set->AddZone(zone3); - m_set->AddZone(zone4); - m_set->AddZone(zone5); - - const int expected = 2; - auto actual = m_set->GetZoneIndexFromWindow(window); - Assert::AreEqual(expected, actual); - } - - TEST_METHOD (ZoneIndexFromWindowWithEqualWindows) - { - HWND window = Mocks::Window(); - HWND zoneWindow = Mocks::Window(); - - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 20, 20, 200, 200 }); - winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone4 = MakeZone({ 10, 10, 100, 100 }); - winrt::com_ptr zone5 = MakeZone({ 20, 20, 100, 100 }); - - zone3->AddWindowToZone(window, zoneWindow, true); - zone4->AddWindowToZone(window, zoneWindow, true); - - m_set->AddZone(zone1); - m_set->AddZone(zone2); - m_set->AddZone(zone3); - m_set->AddZone(zone4); - m_set->AddZone(zone5); - - const int expected = 2; - auto actual = m_set->GetZoneIndexFromWindow(window); - Assert::AreEqual(expected, actual); - } - TEST_METHOD (ZoneIndexFromWindowUnknown) { winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); HWND window = Mocks::Window(); HWND zoneWindow = Mocks::Window(); - zone->AddWindowToZone(window, zoneWindow, true); m_set->AddZone(zone); + m_set->MoveWindowIntoZoneByIndexSet(window, zoneWindow, { 0 }, true); - const int expected = -1; - auto actual = m_set->GetZoneIndexFromWindow(Mocks::Window()); - Assert::AreEqual(expected, actual); + auto actual = m_set->GetZoneIndexSetFromWindow(Mocks::Window()); + Assert::AreEqual({}, actual); } TEST_METHOD (ZoneIndexFromWindowNull) @@ -354,12 +304,11 @@ namespace FancyZonesUnitTests winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); HWND window = Mocks::Window(); HWND zoneWindow = Mocks::Window(); - zone->AddWindowToZone(window, zoneWindow, true); m_set->AddZone(zone); + m_set->MoveWindowIntoZoneByIndexSet(window, zoneWindow, { 0 }, true); - const int expected = -1; - auto actual = m_set->GetZoneIndexFromWindow(nullptr); - Assert::AreEqual(expected, actual); + auto actual = m_set->GetZoneIndexSetFromWindow(nullptr); + Assert::AreEqual({}, actual); } TEST_METHOD (MoveWindowIntoZoneByIndex) @@ -373,9 +322,7 @@ namespace FancyZonesUnitTests HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsTrue(zone2->ContainsWindow(window)); - Assert::IsFalse(zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByIndexWithNoZones) @@ -395,9 +342,7 @@ namespace FancyZonesUnitTests HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100, false); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsFalse(zone2->ContainsWindow(window)); - Assert::IsFalse(zone3->ContainsWindow(window)); + Assert::AreEqual({} , m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameWindow) @@ -412,19 +357,13 @@ namespace FancyZonesUnitTests HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); - Assert::IsTrue(zone1->ContainsWindow(window)); - Assert::IsFalse(zone2->ContainsWindow(window)); - Assert::IsFalse(zone3->ContainsWindow(window)); + Assert::AreEqual({0}, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsTrue(zone2->ContainsWindow(window)); - Assert::IsFalse(zone3->ContainsWindow(window)); + Assert::AreEqual({1}, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsFalse(zone2->ContainsWindow(window)); - Assert::IsTrue(zone3->ContainsWindow(window)); + Assert::AreEqual({2}, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameIndex) @@ -441,9 +380,7 @@ namespace FancyZonesUnitTests m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); - Assert::IsTrue(zone1->ContainsWindow(window)); - Assert::IsFalse(zone2->ContainsWindow(window)); - Assert::IsFalse(zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointEmpty) @@ -459,7 +396,7 @@ namespace FancyZonesUnitTests auto window = Mocks::Window(); m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 200, 200 }); - Assert::IsFalse(zone1->ContainsWindow(window)); + Assert::AreEqual({}, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointInnerPoint) @@ -470,7 +407,7 @@ namespace FancyZonesUnitTests auto window = Mocks::Window(); m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 }); - Assert::IsTrue(zone1->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointInnerPointOverlappingZones) @@ -483,8 +420,7 @@ namespace FancyZonesUnitTests auto window = Mocks::Window(); m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 }); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsTrue(zone2->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointDropAddWindow) @@ -495,15 +431,14 @@ namespace FancyZonesUnitTests winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); - zone1->AddWindowToZone(window, zoneWindow, false); - m_set->AddZone(zone1); m_set->AddZone(zone2); + + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, true); m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 }); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsTrue(zone2->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointDropAddWindowToSameZone) @@ -514,15 +449,14 @@ namespace FancyZonesUnitTests winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); - zone2->AddWindowToZone(window, zoneWindow, false); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, true); m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 }); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsTrue(zone2->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByPointSeveralZonesWithSameWindow) @@ -534,19 +468,15 @@ namespace FancyZonesUnitTests winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); winrt::com_ptr zone3 = MakeZone({ 20, 20, 80, 80 }); - zone1->AddWindowToZone(window, zoneWindow, false); - zone2->AddWindowToZone(window, zoneWindow, false); - zone3->AddWindowToZone(window, zoneWindow, false); - m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->AddZone(zone3); + m_set->MoveWindowIntoZoneByIndexSet(window, Mocks::Window(), { 0, 1, 2 }, true); + m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 50, 50 }); - Assert::IsFalse(zone1->ContainsWindow(window)); - Assert::IsFalse(zone2->ContainsWindow(window)); - Assert::IsTrue(zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } }; @@ -592,18 +522,14 @@ namespace FancyZonesUnitTests { HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveLeftNoZones) { HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveRightTwice) @@ -611,9 +537,7 @@ namespace FancyZonesUnitTests HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveLeftTwice) @@ -621,9 +545,7 @@ namespace FancyZonesUnitTests HWND window = Mocks::Window(); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveRightMoreThanZonesCount) @@ -634,9 +556,7 @@ namespace FancyZonesUnitTests m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); } - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveLeftMoreThanZonesCount) @@ -646,187 +566,132 @@ namespace FancyZonesUnitTests { m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); } - - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByDirectionRight) { HWND window = Mocks::Window(); - m_zone1->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false /* stampZone */); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveRightWithSameWindowAdded) { HWND window = Mocks::Window(); - m_zone1->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); - m_zone2->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndexSet(window, Mocks::Window(), { 0, 1 }, false); - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0, 1 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveRightWithDifferentWindowsAdded) { HWND window1 = Mocks::Window(); HWND window2 = Mocks::Window(); - m_zone1->AddWindowToZone(window1, Mocks::Window(), false /*stampZone*/); - m_zone2->AddWindowToZone(window2, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window1, Mocks::Window(), { 0 }, false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window2, Mocks::Window(), { 1 }, false /*stampZone*/); - Assert::IsTrue(m_zone1->ContainsWindow(window1)); - Assert::IsFalse(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - Assert::IsFalse(m_zone1->ContainsWindow(window2)); - Assert::IsTrue(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window2)); m_set->MoveWindowIntoZoneByDirection(window1, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window1)); - Assert::IsTrue(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - Assert::IsFalse(m_zone1->ContainsWindow(window2)); - Assert::IsTrue(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window2)); m_set->MoveWindowIntoZoneByDirection(window1, Mocks::Window(), VK_RIGHT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window1)); - Assert::IsFalse(m_zone2->ContainsWindow(window1)); - Assert::IsTrue(m_zone3->ContainsWindow(window1)); - Assert::IsFalse(m_zone1->ContainsWindow(window2)); - Assert::IsTrue(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window2)); } TEST_METHOD (MoveWindowIntoZoneByDirectionLeft) { HWND window = Mocks::Window(); - m_zone3->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false /*stampZone*/); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveLeftWithSameWindowAdded) { HWND window = Mocks::Window(); - m_zone2->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); - m_zone3->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndexSet(window, Mocks::Window(), {1, 2}, false /*stampZone*/); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsTrue(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 1, 2 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveLeftWithDifferentWindowsAdded) { HWND window1 = Mocks::Window(); HWND window2 = Mocks::Window(); - m_zone2->AddWindowToZone(window1, Mocks::Window(), false /*stampZone*/); - m_zone3->AddWindowToZone(window2, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window1, Mocks::Window(), 1, false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window2, Mocks::Window(), 2, false /*stampZone*/); - Assert::IsFalse(m_zone1->ContainsWindow(window1)); - Assert::IsTrue(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - Assert::IsFalse(m_zone1->ContainsWindow(window2)); - Assert::IsFalse(m_zone2->ContainsWindow(window2)); - Assert::IsTrue(m_zone3->ContainsWindow(window2)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window2)); m_set->MoveWindowIntoZoneByDirection(window2, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window1)); - Assert::IsTrue(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - Assert::IsFalse(m_zone1->ContainsWindow(window2)); - Assert::IsTrue(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window2)); m_set->MoveWindowIntoZoneByDirection(window2, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window1)); - Assert::IsTrue(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - Assert::IsTrue(m_zone1->ContainsWindow(window2)); - Assert::IsFalse(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + Assert::AreEqual({ 1 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window2)); } TEST_METHOD (MoveWindowIntoZoneByDirectionWrapAroundRight) { HWND window = Mocks::Window(); - m_zone3->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false /*stampZone*/); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, true); - Assert::IsTrue(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsFalse(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveWindowIntoZoneByDirectionWrapAroundLeft) { HWND window = Mocks::Window(); - m_zone1->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false /*stampZone*/); m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, true); - Assert::IsFalse(m_zone1->ContainsWindow(window)); - Assert::IsFalse(m_zone2->ContainsWindow(window)); - Assert::IsTrue(m_zone3->ContainsWindow(window)); + Assert::AreEqual({ 2 }, m_set->GetZoneIndexSetFromWindow(window)); } TEST_METHOD (MoveSecondWindowIntoSameZone) { HWND window1 = Mocks::Window(); - m_zone1->AddWindowToZone(window1, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window1, Mocks::Window(), 0, false /*stampZone*/); HWND window2 = Mocks::Window(); m_set->MoveWindowIntoZoneByDirection(window2, Mocks::Window(), VK_RIGHT, true); - Assert::IsTrue(m_zone1->ContainsWindow(window1)); - Assert::IsFalse(m_zone2->ContainsWindow(window1)); - Assert::IsFalse(m_zone3->ContainsWindow(window1)); - - Assert::IsTrue(m_zone1->ContainsWindow(window2)); - Assert::IsFalse(m_zone2->ContainsWindow(window2)); - Assert::IsFalse(m_zone3->ContainsWindow(window2)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window1)); + Assert::AreEqual({ 0 }, m_set->GetZoneIndexSetFromWindow(window2)); } TEST_METHOD (MoveRightMoreThanZoneCountReturnsFalse) { HWND window = Mocks::Window(); - m_zone1->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false /*stampZone*/); for (size_t i = 0; i < m_set->GetZones().size() - 1; ++i) { m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_RIGHT, false); @@ -838,7 +703,7 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveLeftMoreThanZoneCountReturnsFalse) { HWND window = Mocks::Window(); - m_zone3->AddWindowToZone(window, Mocks::Window(), false /*stampZone*/); + m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false /*stampZone*/); for (size_t i = 0; i < m_set->GetZones().size() - 1; ++i) { m_set->MoveWindowIntoZoneByDirection(window, Mocks::Window(), VK_LEFT, false); @@ -893,9 +758,10 @@ namespace FancyZonesUnitTests auto zones = set->GetZones(); Assert::AreEqual(expectedCount, zones.size()); + int zoneId = 0; for (const auto& zone : zones) { - Assert::IsTrue(zone->IsEmpty()); + Assert::IsTrue(set->IsZoneEmpty(zoneId)); const auto& zoneRect = zone->GetZoneRect(); Assert::IsTrue(zoneRect.left >= 0, L"left border is less than zero"); @@ -906,6 +772,8 @@ namespace FancyZonesUnitTests Assert::IsTrue(zoneRect.right <= monitorInfo.rcWork.right, L"right border is bigger than monitor work space"); Assert::IsTrue(zoneRect.bottom <= monitorInfo.rcWork.bottom, L"bottom border is bigger than monitor work space"); + + zoneId++; } } diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp index 7d845b82c..8075bdff9 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp @@ -512,8 +512,8 @@ namespace FancyZonesUnitTests const auto zoneSet = zoneWindow->ActiveZoneSet(); zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); - const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window); - Assert::AreNotEqual(-1, actualZoneIndex); + const auto actualZoneIndexSet = zoneSet->GetZoneIndexSetFromWindow(window); + Assert::AreNotEqual({}, actualZoneIndexSet); } TEST_METHOD(MoveSizeEndWindowNotAdded) @@ -528,8 +528,8 @@ namespace FancyZonesUnitTests Assert::AreEqual(expected, actual); const auto zoneSet = zoneWindow->ActiveZoneSet(); - const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window); - Assert::AreEqual(-1, actualZoneIndex); + const auto actualZoneIndexSet = zoneSet->GetZoneIndexSetFromWindow(window); + Assert::AreEqual({}, actualZoneIndexSet); } TEST_METHOD(MoveSizeEndDifferentWindows) @@ -568,8 +568,8 @@ namespace FancyZonesUnitTests const auto zoneSet = zoneWindow->ActiveZoneSet(); zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false); - const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window); - Assert::AreNotEqual(-1, actualZoneIndex); //with invalid point zone remains the same + const auto actualZoneIndex = zoneSet->GetZoneIndexSetFromWindow(window); + Assert::AreNotEqual({}, actualZoneIndex); //with invalid point zone remains the same } TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet) @@ -609,7 +609,7 @@ namespace FancyZonesUnitTests const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap(); Assert::AreEqual((size_t)1, actualAppZoneHistory.size()); const auto actual = actualAppZoneHistory.begin()->second; - Assert::AreEqual(0, actual.zoneIndex); + Assert::AreEqual({ 0 }, actual.zoneIndexSet); } TEST_METHOD(MoveWindowIntoZoneByDirectionManyTimes) @@ -625,7 +625,7 @@ namespace FancyZonesUnitTests const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap(); Assert::AreEqual((size_t)1, actualAppZoneHistory.size()); const auto actual = actualAppZoneHistory.begin()->second; - Assert::AreEqual(2, actual.zoneIndex); + Assert::AreEqual({ 2 }, actual.zoneIndexSet); } TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet) @@ -676,9 +676,9 @@ namespace FancyZonesUnitTests const auto zoneSetId = m_zoneWindow->ActiveZoneSet()->Id(); //fill app zone history map - Assert::IsTrue(m_fancyZonesData.SetAppLastZone(window, deviceId, Helpers::GuidToString(zoneSetId), 0)); + Assert::IsTrue(m_fancyZonesData.SetAppLastZones(window, deviceId, Helpers::GuidToString(zoneSetId), { 0 })); Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size()); - Assert::AreEqual(0, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex); + Assert::AreEqual({ 0 }, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndexSet); //add zone without window const auto zone = MakeZone(RECT{ 0, 0, 100, 100 }); @@ -686,7 +686,7 @@ namespace FancyZonesUnitTests m_zoneWindow->SaveWindowProcessToZoneIndex(window); Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size()); - Assert::AreEqual(0, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex); + Assert::AreEqual({ 0 }, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndexSet); } TEST_METHOD(SaveWindowProcessToZoneIndexWindowAdded) @@ -700,20 +700,20 @@ namespace FancyZonesUnitTests const auto zoneSetId = m_zoneWindow->ActiveZoneSet()->Id(); auto zone = MakeZone(RECT{ 0, 0, 100, 100 }); - zone->AddWindowToZone(window, Mocks::Window(), false); m_zoneWindow->ActiveZoneSet()->AddZone(zone); + m_zoneWindow->MoveWindowIntoZoneByIndex(window, 0); //fill app zone history map - Assert::IsTrue(m_fancyZonesData.SetAppLastZone(window, deviceId, Helpers::GuidToString(zoneSetId), 2)); + Assert::IsTrue(m_fancyZonesData.SetAppLastZones(window, deviceId, Helpers::GuidToString(zoneSetId), { 2 })); Assert::AreEqual((size_t)1, m_fancyZonesData.GetAppZoneHistoryMap().size()); - Assert::AreEqual(2, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex); + Assert::AreEqual({ 2 }, m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndexSet); m_zoneWindow->SaveWindowProcessToZoneIndex(window); const auto actualAppZoneHistory = m_fancyZonesData.GetAppZoneHistoryMap(); Assert::AreEqual((size_t)1, actualAppZoneHistory.size()); - const auto expected = m_zoneWindow->ActiveZoneSet()->GetZoneIndexFromWindow(window); - const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex; + const auto expected = m_zoneWindow->ActiveZoneSet()->GetZoneIndexSetFromWindow(window); + const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndexSet; Assert::AreEqual(expected, actual); }