[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

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