mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-25 10:01:57 +08:00
8f98866d71
* Added the setting * Added a property to Editor Settings This will be used later * Fixed a bug in the previous commit * Simplified a method * Added snapping points to the editor * Simplified a method in ZoneSet * Updated ZoneSet testcases * Add a method to FancyZones / ZoneWindowHost * Almost works * The editor now launches, but FZ does not understand the results * Refactored some code * Snapping to a zone by dragging seems to work * Hotkeys seem to work * Refresh the work area handler after changing settings * Fixed zones not snapping to monitor edges when moved * Remove unused method in FancyZones.h * Fixed an issue with DPI awareness * Renamed setting to spanZonesAcrossMonitors * Renamed a function * Fixed a bug with the magnetic effect * Fix restoring window positions on layout changes
116 lines
3.5 KiB
C++
116 lines
3.5 KiB
C++
#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)
|
|
{
|
|
GUID desktopId{};
|
|
if (VirtualDesktopUtils::GetWindowDesktopId(window, &desktopId))
|
|
{
|
|
auto allMonitorsWorkArea = GetWorkArea(desktopId, NULL);
|
|
if (allMonitorsWorkArea)
|
|
{
|
|
// First, check if there's a work area spanning all monitors (signalled by the NULL monitor handle)
|
|
return allMonitorsWorkArea;
|
|
}
|
|
else
|
|
{
|
|
// Otherwise, look for the work area based on the window's position
|
|
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
|
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];
|
|
}
|
|
static const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>> empty;
|
|
return empty;
|
|
}
|
|
|
|
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::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))
|
|
{
|
|
// virtual desktop deleted, remove entry from the map
|
|
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();
|
|
}
|