[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.
This commit is contained in:
vldmr11080
2020-05-31 12:36:45 +02:00
committed by GitHub
parent 595b15fcd9
commit 2216cda2f1
14 changed files with 330 additions and 269 deletions

View File

@@ -14,6 +14,7 @@
#include "lib/util.h"
#include "trace.h"
#include "VirtualDesktopUtils.h"
#include "MonitorWorkAreaHandler.h"
#include <interface/win_hook_event_data.h>
@@ -25,19 +26,6 @@ enum class DisplayChangeType
Initialization
};
namespace std
{
template<>
struct hash<GUID>
{
size_t operator()(const GUID& Value) const
{
RPC_STATUS status = RPC_S_OK;
return ::UuidHash(&const_cast<GUID&>(Value), &status);
}
};
}
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback, IZoneWindowHost>
{
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<GUID>& 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<HMONITOR, winrt::com_ptr<IZoneWindow>> m_zoneWindowMap; // Map of monitor to ZoneWindow (one per monitor)
winrt::com_ptr<IFancyZonesSettings> m_settings{};
GUID m_currentVirtualDesktopId{}; // UUID of the current virtual desktop. Is GUID_NULL until first VD switch per session.
std::unordered_map<GUID, std::vector<HMONITOR>> 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(&currentVirtualDesktopId))
{
m_currentVirtualDesktopId = currentVirtualDesktopId;
m_currentDesktopId = currentVirtualDesktopId;
}
if (changeType == DisplayChangeType::Initialization)
{
@@ -703,29 +665,32 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
{
std::unique_lock writeLock(m_lock);
if (m_workAreaHandler.IsNewWorkArea(m_currentDesktopId, monitor))
{
wil::unique_cotaskmem_string virtualDesktopId;
if (SUCCEEDED_LOG(StringFromCLSID(m_currentVirtualDesktopId, &virtualDesktopId)))
if (SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId)))
{
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 = m_settings->GetSettings()->zoneSetChange_flashZones;
const bool flash = false;
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash, newWorkArea);
if (zoneWindow)
std::wstring parentId{};
auto parentArea = m_workAreaHandler.GetWorkArea(m_previousDesktopId, monitor);
if (parentArea)
{
m_zoneWindowMap[monitor] = std::move(zoneWindow);
parentId = parentArea->UniqueId();
}
if (newWorkArea)
auto workArea = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, parentId, flash);
if (workArea)
{
RegisterNewWorkArea(m_currentVirtualDesktopId, monitor);
m_workAreaHandler.AddWorkArea(m_currentDesktopId, monitor, workArea);
JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData();
}
}
}
}
LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept
@@ -802,7 +767,11 @@ void FancyZones::UpdateWindowsPositions() noexcept
auto strongThis = reinterpret_cast<FancyZones*>(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<GUID>& ids) noexcept
{
std::unordered_set<GUID> activeVirtualDesktops(std::begin(ids), std::end(ids));
std::unique_lock writeLock(m_lock);
std::vector<GUID> 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())
{
// 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)))
if (SUCCEEDED(StringFromCLSID(id, &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;
}
}
if (modified)
{
JSONHelpers::FancyZonesDataInstance().SaveFancyZonesData();
}
// register new virtual desktops, if any
for (const auto& id : activeVirtualDesktops)
{
m_processedWorkAreas[id] = std::vector<HMONITOR>();
}
}
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<std::pair<HMONITOR, RECT>> FancyZones::GetRawMonitorData() noexcept
std::shared_lock readLock(m_lock);
std::vector<std::pair<HMONITOR, RECT>> 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);

View File

@@ -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).
*/

View File

@@ -101,6 +101,7 @@
<ClInclude Include="FancyZones.h" />
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
<ClInclude Include="JsonHelpers.h" />
<ClInclude Include="MonitorWorkAreaHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Settings.h" />
@@ -116,6 +117,7 @@
<ClCompile Include="FancyZones.cpp" />
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
<ClCompile Include="JsonHelpers.cpp" />
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>

View File

@@ -54,6 +54,9 @@
<ClInclude Include="FancyZonesWinHookEventIDs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorWorkAreaHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@@ -92,6 +95,9 @@
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonitorWorkAreaHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="fancyzones.rc">

View File

@@ -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)

View File

@@ -189,12 +189,6 @@ namespace JSONHelpers
std::optional<CustomZoneSetData> FindCustomZoneSet(const std::wstring& guid) const;
inline const std::wstring GetActiveDeviceId() const
{
std::scoped_lock lock{ dataLock };
return activeDeviceId;
}
inline const std::unordered_map<std::wstring, DeviceInfoData>& 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<std::wstring, DeviceInfoData> deviceInfoMap{};
std::unordered_map<std::wstring, CustomZoneSetData> customZoneSetsMap{};
std::wstring activeDeviceId;
std::wstring jsonFilePath;
std::wstring appZoneHistoryFilePath;
};

View File

@@ -0,0 +1,104 @@
#include "pch.h"
#include "MonitorWorkAreaHandler.h"
#include "VirtualDesktopUtils.h"
winrt::com_ptr<IZoneWindow> 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<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& MonitorWorkAreaHandler::GetWorkAreasByDesktopId(const GUID& desktopId)
{
if (workAreaMap.contains(desktopId))
{
return workAreaMap[desktopId];
}
return {};
}
std::vector<winrt::com_ptr<IZoneWindow>> MonitorWorkAreaHandler::GetAllWorkAreas()
{
std::vector<winrt::com_ptr<IZoneWindow>> 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<IZoneWindow>& 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<GUID>& active, std::vector<GUID>& deleted)
{
std::unordered_set<GUID> 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();
}

View File

@@ -0,0 +1,93 @@
#pragma once
interface IZoneWindow;
namespace std
{
template<>
struct hash<GUID>
{
size_t operator()(const GUID& Value) const
{
RPC_STATUS status = RPC_S_OK;
return ::UuidHash(&const_cast<GUID&>(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<IZoneWindow> 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<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& GetWorkAreasByDesktopId(const GUID& desktopId);
/**
* @returns All registered work areas.
*/
std::vector<winrt::com_ptr<IZoneWindow>> 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<IZoneWindow>& 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<GUID>& active, std::vector<GUID>& 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<GUID, std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>> workAreaMap;
};

View File

@@ -60,12 +60,12 @@ public:
return m_inMoveSize;
}
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR,winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
bool MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap);
void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap);
}
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
pimpl->MoveSizeUpdate(monitor, ptScreen, zoneWindowMap);
}
void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
pimpl->MoveSizeEnd(window, ptScreen, zoneWindowMap);
}
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet, winrt::com_ptr<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap)
bool WindowMoveHandler::MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& 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<int>& indexSet, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
void WindowMoveHandlerPrivate::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet, winrt::com_ptr<IZoneWindow> 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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap)
bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> 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

View File

@@ -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<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
bool MoveWindowIntoZoneByDirection(HMONITOR monitor, HWND window, DWORD vkCode, bool cycle, const std::map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap);
void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow);
private:
class WindowMoveHandlerPrivate* pimpl;

View File

@@ -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<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones) noexcept
{
auto self = winrt::make_self<ZoneWindow>(hinstance);
if (self->Init(host, hinstance, monitor, uniqueId, flashZones, newWorkArea))
if (self->Init(host, hinstance, monitor, uniqueId, parentUniqueId, flashZones))
{
return self;
}

View File

@@ -110,4 +110,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
};
winrt::com_ptr<IZoneWindow> 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;

View File

@@ -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)

View File

@@ -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<IZoneWindow> 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());