mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
[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:
104
src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp
Normal file
104
src/modules/fancyzones/lib/MonitorWorkAreaHandler.cpp
Normal 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();
|
||||
}
|
||||
Reference in New Issue
Block a user