mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
[FancyZones] Improve code quality (part 5: work area initialization) (#23671)
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||
#include <FancyZonesLib/MonitorUtils.h>
|
||||
#include <FancyZonesLib/MonitorWorkAreaHandler.h>
|
||||
#include <FancyZonesLib/MonitorWorkAreaMap.h>
|
||||
#include <FancyZonesLib/on_thread_executor.h>
|
||||
#include <FancyZonesLib/Settings.h>
|
||||
#include <FancyZonesLib/SettingsObserver.h>
|
||||
@@ -129,17 +129,16 @@ private:
|
||||
bool OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexcept;
|
||||
bool OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept;
|
||||
bool OnSnapHotkey(DWORD vkCode) noexcept;
|
||||
bool ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept;
|
||||
bool ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle, WorkArea* const workArea) noexcept;
|
||||
|
||||
void RegisterVirtualDesktopUpdates() noexcept;
|
||||
|
||||
void UpdateHotkey(int hotkeyId, const PowerToysSettings::HotkeyObject& hotkeyObject, bool enable) noexcept;
|
||||
|
||||
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
|
||||
void MoveWindowIntoZone(HWND window, std::shared_ptr<WorkArea> workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
||||
std::pair<WorkArea*, ZoneIndexSet> GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& workAreas) noexcept;
|
||||
void MoveWindowIntoZone(HWND window, WorkArea* const workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
||||
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
|
||||
void RefreshWorkAreaWindows(bool updatePositions);
|
||||
|
||||
|
||||
void OnEditorExitEvent() noexcept;
|
||||
void UpdateZoneSets() noexcept;
|
||||
bool ShouldProcessSnapHotkey(DWORD vkCode) noexcept;
|
||||
@@ -156,7 +155,7 @@ private:
|
||||
|
||||
HWND m_window{};
|
||||
std::unique_ptr<WindowDrag> m_windowDrag{};
|
||||
MonitorWorkAreaHandler m_workAreaHandler;
|
||||
MonitorWorkAreaMap m_workAreaHandler;
|
||||
DraggingState m_draggingState;
|
||||
|
||||
wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on
|
||||
@@ -283,7 +282,7 @@ FancyZones::VirtualDesktopChanged() noexcept
|
||||
|
||||
void FancyZones::MoveSizeStart(HWND window, HMONITOR monitor)
|
||||
{
|
||||
m_windowDrag = WindowDrag::Create(window, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
||||
m_windowDrag = WindowDrag::Create(window, m_workAreaHandler.GetAllWorkAreas());
|
||||
if (m_windowDrag)
|
||||
{
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||
@@ -321,70 +320,54 @@ void FancyZones::MoveSizeEnd()
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> FancyZones::GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
|
||||
std::pair<WorkArea*, ZoneIndexSet> FancyZones::GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& workAreas) noexcept
|
||||
{
|
||||
if (monitor)
|
||||
for (const auto& [workAreaMonitor, workArea] : workAreas)
|
||||
{
|
||||
if (workAreaMap.contains(monitor))
|
||||
if (workAreaMonitor == monitor && workArea)
|
||||
{
|
||||
auto workArea = workAreaMap.at(monitor);
|
||||
return std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet>{ workArea, workArea->GetWindowZoneIndexes(window) };
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::debug(L"No work area for the currently active monitor.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& [mon, workArea] : workAreaMap)
|
||||
{
|
||||
auto zoneIndexSet = workArea->GetWindowZoneIndexes(window);
|
||||
if (!zoneIndexSet.empty())
|
||||
{
|
||||
return std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet>{ workArea, zoneIndexSet };
|
||||
}
|
||||
return std::pair<WorkArea*, ZoneIndexSet>{ workArea.get(), workArea->GetWindowZoneIndexes(window) };
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet>{ nullptr, {} };
|
||||
Logger::error(L"No work area for the currently active monitor.");
|
||||
return std::pair<WorkArea*, ZoneIndexSet>{ nullptr, {} };
|
||||
}
|
||||
|
||||
void FancyZones::MoveWindowIntoZone(HWND window, std::shared_ptr<WorkArea> workArea, const ZoneIndexSet& zoneIndexSet) noexcept
|
||||
void FancyZones::MoveWindowIntoZone(HWND window, WorkArea* const workArea, const ZoneIndexSet& zoneIndexSet) noexcept
|
||||
{
|
||||
if (workArea)
|
||||
{
|
||||
Trace::FancyZones::SnapNewWindowIntoZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||
workArea->MoveWindowIntoZoneByIndexSet(window, zoneIndexSet);
|
||||
AppZoneHistory::instance().UpdateProcessIdToHandleMap(window, workArea->UniqueId());
|
||||
}
|
||||
|
||||
AppZoneHistory::instance().UpdateProcessIdToHandleMap(window, workArea->UniqueId());
|
||||
}
|
||||
|
||||
bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept
|
||||
{
|
||||
auto workAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||
if (workAreaMap.empty())
|
||||
const auto& workAreas = m_workAreaHandler.GetAllWorkAreas();
|
||||
if (workAreas.empty())
|
||||
{
|
||||
Logger::trace(L"No work area for the current desktop.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search application history on currently active monitor.
|
||||
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> appZoneHistoryInfo = GetAppZoneHistoryInfo(window, active, workAreaMap);
|
||||
auto appZoneHistoryInfo = GetAppZoneHistoryInfo(window, active, workAreas);
|
||||
|
||||
// No application history on currently active monitor
|
||||
if (appZoneHistoryInfo.second.empty())
|
||||
{
|
||||
// Search application history on primary monitor.
|
||||
appZoneHistoryInfo = GetAppZoneHistoryInfo(window, primary, workAreaMap);
|
||||
appZoneHistoryInfo = GetAppZoneHistoryInfo(window, primary, workAreas);
|
||||
}
|
||||
|
||||
// No application history on currently active and primary monitors
|
||||
if (appZoneHistoryInfo.second.empty())
|
||||
{
|
||||
// Search application history on remaining monitors.
|
||||
appZoneHistoryInfo = GetAppZoneHistoryInfo(window, nullptr, workAreaMap);
|
||||
appZoneHistoryInfo = GetAppZoneHistoryInfo(window, nullptr, workAreas);
|
||||
}
|
||||
|
||||
if (!appZoneHistoryInfo.second.empty())
|
||||
@@ -400,25 +383,6 @@ bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primar
|
||||
return false;
|
||||
}
|
||||
|
||||
void FancyZones::RefreshWorkAreaWindows(bool updatePositions)
|
||||
{
|
||||
auto activeWorkAreas = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
||||
{
|
||||
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||
if (zoneIndexSet.size() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||
if (monitor && activeWorkAreas.contains(monitor))
|
||||
{
|
||||
activeWorkAreas.at(monitor)->MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZones::WindowCreated(HWND window) noexcept
|
||||
{
|
||||
const bool moveToAppLastZone = FancyZonesSettings::settings().appLastZone_moveWindows;
|
||||
@@ -457,9 +421,19 @@ void FancyZones::WindowCreated(HWND window) noexcept
|
||||
}
|
||||
|
||||
bool movedToAppLastZone = false;
|
||||
if (moveToAppLastZone)
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||
{
|
||||
movedToAppLastZone = MoveToAppLastZone(window, active, primary);
|
||||
if (moveToAppLastZone)
|
||||
{
|
||||
movedToAppLastZone = MoveToAppLastZone(window, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moveToAppLastZone)
|
||||
{
|
||||
movedToAppLastZone = MoveToAppLastZone(window, active, primary);
|
||||
}
|
||||
}
|
||||
|
||||
// Open on active monitor if window wasn't zoned
|
||||
@@ -609,7 +583,6 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
||||
{
|
||||
// Changes in taskbar position resulted in different size of work area.
|
||||
// Invalidate cached work-areas so they can be recreated with latest information.
|
||||
m_workAreaHandler.Clear();
|
||||
OnDisplayChange(DisplayChangeType::WorkArea);
|
||||
}
|
||||
}
|
||||
@@ -618,7 +591,6 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
// Display resolution changed. Invalidate cached work-areas so they can be recreated with latest information.
|
||||
m_workAreaHandler.Clear();
|
||||
OnDisplayChange(DisplayChangeType::DisplayChange);
|
||||
}
|
||||
break;
|
||||
@@ -740,42 +712,38 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
||||
}
|
||||
|
||||
UpdateWorkAreas();
|
||||
RefreshWorkAreaWindows(FancyZonesSettings::settings().displayChange_moveWindows && changeType != DisplayChangeType::VirtualDesktop);
|
||||
}
|
||||
|
||||
void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept
|
||||
{
|
||||
if (m_workAreaHandler.IsNewWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor))
|
||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
||||
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr)))
|
||||
{
|
||||
wil::unique_cotaskmem_string virtualDesktopIdStr;
|
||||
if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr)))
|
||||
{
|
||||
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
||||
}
|
||||
Logger::debug(L"Add new work area on virtual desktop {}", virtualDesktopIdStr.get());
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId parentId{};
|
||||
auto parentArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetPreviousVirtualDesktopId(), monitor);
|
||||
if (parentArea)
|
||||
{
|
||||
parentId = parentArea->UniqueId();
|
||||
}
|
||||
FancyZonesDataTypes::WorkAreaId parentId{};
|
||||
auto parentArea = m_workAreaHandler.GetWorkArea(monitor);
|
||||
if (parentArea)
|
||||
{
|
||||
parentId = parentArea->UniqueId();
|
||||
}
|
||||
|
||||
FancyZonesUtils::Rect rect{};
|
||||
if (monitor)
|
||||
{
|
||||
rect = MonitorUtils::GetWorkAreaRect(monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
||||
}
|
||||
FancyZonesUtils::Rect rect{};
|
||||
if (monitor)
|
||||
{
|
||||
rect = MonitorUtils::GetWorkAreaRect(monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
||||
}
|
||||
|
||||
auto workArea = MakeWorkArea(m_hinstance, id, parentId, rect);
|
||||
if (workArea)
|
||||
{
|
||||
m_workAreaHandler.AddWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor, workArea);
|
||||
AppliedLayouts::instance().SaveData();
|
||||
}
|
||||
auto workArea = WorkArea::Create(m_hinstance, id, parentId, rect);
|
||||
if (workArea)
|
||||
{
|
||||
m_workAreaHandler.AddWorkArea(monitor, std::move(workArea));
|
||||
AppliedLayouts::instance().SaveData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,6 +763,8 @@ LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam,
|
||||
|
||||
void FancyZones::UpdateWorkAreas() noexcept
|
||||
{
|
||||
m_workAreaHandler.Clear();
|
||||
|
||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId workAreaId;
|
||||
@@ -822,7 +792,7 @@ void FancyZones::CycleWindows(bool reverse) noexcept
|
||||
auto window = GetForegroundWindow();
|
||||
HMONITOR current = WorkAreaKeyFromWindow(window);
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(current);
|
||||
if (workArea)
|
||||
{
|
||||
workArea->CycleWindows(window, reverse);
|
||||
@@ -840,13 +810,13 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
||||
auto currMonitorInfo = std::find(std::begin(monitorInfo), std::end(monitorInfo), current);
|
||||
do
|
||||
{
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), *currMonitorInfo);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(*currMonitorInfo);
|
||||
if (workArea && workArea->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */))
|
||||
{
|
||||
// unassign from previous work area
|
||||
for (auto& prevWorkArea : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (auto& [_, prevWorkArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
{
|
||||
if (workArea != prevWorkArea)
|
||||
if (prevWorkArea && workArea != prevWorkArea.get())
|
||||
{
|
||||
prevWorkArea->UnsnapWindow(window);
|
||||
}
|
||||
@@ -876,7 +846,7 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
||||
}
|
||||
else
|
||||
{
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(current);
|
||||
// Single monitor environment, or combined multi-monitor environment.
|
||||
if (FancyZonesSettings::settings().restoreSize)
|
||||
{
|
||||
@@ -918,7 +888,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
{
|
||||
// Multi monitor environment.
|
||||
// First, try to stay on the same monitor
|
||||
bool success = ProcessDirectedSnapHotkey(window, vkCode, false, m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current));
|
||||
bool success = ProcessDirectedSnapHotkey(window, vkCode, false, m_workAreaHandler.GetWorkArea(current));
|
||||
if (success)
|
||||
{
|
||||
return true;
|
||||
@@ -937,7 +907,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(monitor);
|
||||
if (workArea)
|
||||
{
|
||||
const auto& layout = workArea->GetLayout();
|
||||
@@ -977,9 +947,9 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
if (workArea)
|
||||
{
|
||||
workArea->MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx });
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||
}
|
||||
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -989,7 +959,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
// Sanity check: the current monitor is valid
|
||||
if (currentMonitorRect.top <= currentMonitorRect.bottom)
|
||||
{
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(current);
|
||||
if (workArea)
|
||||
{
|
||||
const auto& layout = workArea->GetLayout();
|
||||
@@ -1027,9 +997,9 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
if (workArea)
|
||||
{
|
||||
workArea->MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx });
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||
}
|
||||
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -1041,7 +1011,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
||||
else
|
||||
{
|
||||
// Single monitor environment, or combined multi-monitor environment.
|
||||
return ProcessDirectedSnapHotkey(window, vkCode, true, m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), current));
|
||||
return ProcessDirectedSnapHotkey(window, vkCode, true, m_workAreaHandler.GetWorkArea(current));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1057,7 +1027,7 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept
|
||||
return (vkCode == VK_LEFT || vkCode == VK_RIGHT) && OnSnapHotkeyBasedOnZoneNumber(window, vkCode);
|
||||
}
|
||||
|
||||
bool FancyZones::ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept
|
||||
bool FancyZones::ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle, WorkArea* const workArea) noexcept
|
||||
{
|
||||
// Check whether Alt is used in the shortcut key combination
|
||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
||||
@@ -1085,7 +1055,6 @@ void FancyZones::RegisterVirtualDesktopUpdates() noexcept
|
||||
auto guids = VirtualDesktop::instance().GetVirtualDesktopIdsFromRegistry();
|
||||
if (guids.has_value())
|
||||
{
|
||||
m_workAreaHandler.RegisterUpdates(*guids);
|
||||
AppZoneHistory::instance().RemoveDeletedVirtualDesktops(*guids);
|
||||
AppliedLayouts::instance().RemoveDeletedVirtualDesktops(*guids);
|
||||
}
|
||||
@@ -1156,12 +1125,13 @@ void FancyZones::OnEditorExitEvent() noexcept
|
||||
|
||||
void FancyZones::UpdateZoneSets() noexcept
|
||||
{
|
||||
for (auto workArea : m_workAreaHandler.GetAllWorkAreas())
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
{
|
||||
workArea->UpdateActiveZoneSet();
|
||||
if (workArea)
|
||||
{
|
||||
workArea->UpdateActiveZoneSet();
|
||||
}
|
||||
}
|
||||
|
||||
RefreshWorkAreaWindows(FancyZonesSettings::settings().zoneSetChange_moveWindows);
|
||||
}
|
||||
|
||||
bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
||||
@@ -1177,7 +1147,7 @@ bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
||||
{
|
||||
HMONITOR monitor = WorkAreaKeyFromWindow(window);
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), monitor);
|
||||
auto workArea = m_workAreaHandler.GetWorkArea(monitor);
|
||||
if (!workArea)
|
||||
{
|
||||
Logger::error(L"No work area for processing snap hotkey");
|
||||
@@ -1222,20 +1192,26 @@ void FancyZones::ApplyQuickLayout(int key) noexcept
|
||||
return;
|
||||
}
|
||||
|
||||
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
||||
AppliedLayouts::instance().SaveData();
|
||||
UpdateZoneSets();
|
||||
FlashZones();
|
||||
auto workArea = m_workAreaHandler.GetWorkAreaFromCursor();
|
||||
if (workArea)
|
||||
{
|
||||
AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value());
|
||||
AppliedLayouts::instance().SaveData();
|
||||
UpdateZoneSets();
|
||||
FlashZones();
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZones::FlashZones() noexcept
|
||||
{
|
||||
if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_draggingState.IsDragging())
|
||||
{
|
||||
for (auto [monitor, workArea] : m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()))
|
||||
for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas())
|
||||
{
|
||||
workArea->FlashZones();
|
||||
if (workArea)
|
||||
{
|
||||
workArea->FlashZones();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1252,10 +1228,10 @@ std::vector<HMONITOR> FancyZones::GetMonitorsSorted() noexcept
|
||||
std::vector<std::pair<HMONITOR, RECT>> FancyZones::GetRawMonitorData() noexcept
|
||||
{
|
||||
std::vector<std::pair<HMONITOR, RECT>> monitorInfo;
|
||||
const auto& activeWorkAreaMap = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||
const auto& activeWorkAreaMap = m_workAreaHandler.GetAllWorkAreas();
|
||||
for (const auto& [monitor, workArea] : activeWorkAreaMap)
|
||||
{
|
||||
if (workArea->GetLayout() != nullptr)
|
||||
if (workArea && workArea->GetLayout() != nullptr)
|
||||
{
|
||||
MONITORINFOEX mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<ClInclude Include="LayoutAssignedWindows.h" />
|
||||
<ClInclude Include="ModuleConstants.h" />
|
||||
<ClInclude Include="MonitorUtils.h" />
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
||||
<ClInclude Include="MonitorWorkAreaMap.h" />
|
||||
<ClInclude Include="NotificationUtil.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Generated Files/resource.h" />
|
||||
@@ -113,7 +113,7 @@
|
||||
<ClCompile Include="LayoutConfigurator.cpp" />
|
||||
<ClCompile Include="LayoutAssignedWindows.cpp" />
|
||||
<ClCompile Include="MonitorUtils.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaMap.cpp" />
|
||||
<ClCompile Include="OnThreadExecutor.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<ClInclude Include="SecondaryMouseButtonsHook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h">
|
||||
<ClInclude Include="MonitorWorkAreaMap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GenericKeyHook.h">
|
||||
@@ -197,7 +197,7 @@
|
||||
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp">
|
||||
<ClCompile Include="MonitorWorkAreaMap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FancyZonesData.cpp">
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "MonitorWorkAreaHandler.h"
|
||||
#include "VirtualDesktop.h"
|
||||
#include "WorkArea.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
std::shared_ptr<WorkArea> MonitorWorkAreaHandler::GetWorkArea(const GUID& desktopId, HMONITOR monitor)
|
||||
{
|
||||
auto desktopIt = workAreaMap.find(desktopId);
|
||||
if (desktopIt != workAreaMap.end())
|
||||
{
|
||||
auto& perDesktopData = desktopIt->second;
|
||||
auto monitorIt = perDesktopData.find(monitor);
|
||||
if (monitorIt != std::end(perDesktopData))
|
||||
{
|
||||
return monitorIt->second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkArea> MonitorWorkAreaHandler::GetWorkAreaFromCursor(const GUID& 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 cursor position
|
||||
POINT cursorPoint;
|
||||
if (!GetCursorPos(&cursorPoint))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetWorkArea(desktopId, MonitorFromPoint(cursorPoint, MONITOR_DEFAULTTONULL));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkArea> MonitorWorkAreaHandler::GetWorkArea(HWND window, const GUID& 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);
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& MonitorWorkAreaHandler::GetWorkAreasByDesktopId(const GUID& desktopId)
|
||||
{
|
||||
if (workAreaMap.contains(desktopId))
|
||||
{
|
||||
return workAreaMap[desktopId];
|
||||
}
|
||||
|
||||
static const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>> empty{};
|
||||
return empty;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<WorkArea>> MonitorWorkAreaHandler::GetAllWorkAreas()
|
||||
{
|
||||
std::vector<std::shared_ptr<WorkArea>> 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, std::shared_ptr<WorkArea>& workArea)
|
||||
{
|
||||
if (!workAreaMap.contains(desktopId))
|
||||
{
|
||||
workAreaMap[desktopId] = {};
|
||||
|
||||
auto desktopIdStr = FancyZonesUtils::GuidToString(desktopId);
|
||||
if (desktopIdStr)
|
||||
{
|
||||
Logger::info(L"Add work area on the desktop {}", desktopIdStr.value());
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuidUtils.h"
|
||||
|
||||
class WorkArea;
|
||||
struct ZoneColors;
|
||||
enum struct OverlappingZonesAlgorithm;
|
||||
|
||||
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).
|
||||
*/
|
||||
std::shared_ptr<WorkArea> GetWorkArea(const GUID& desktopId, HMONITOR monitor);
|
||||
|
||||
/**
|
||||
* Get work area based on virtual desktop id and the current cursor position.
|
||||
*
|
||||
* @param[in] desktopId Virtual desktop identifier.
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
std::shared_ptr<WorkArea> GetWorkAreaFromCursor(const GUID& desktopId);
|
||||
|
||||
/**
|
||||
* Get work area on which specified window is located.
|
||||
*
|
||||
* @param[in] window Window handle.
|
||||
* @param[in] desktopId GUID current desktop id
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
std::shared_ptr<WorkArea> GetWorkArea(HWND window, const GUID& desktopId);
|
||||
|
||||
/**
|
||||
* 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, std::shared_ptr<WorkArea>>& GetWorkAreasByDesktopId(const GUID& desktopId);
|
||||
|
||||
/**
|
||||
* @returns All registered work areas.
|
||||
*/
|
||||
std::vector<std::shared_ptr<WorkArea>> 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, std::shared_ptr<WorkArea>& 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.
|
||||
*/
|
||||
void RegisterUpdates(const std::vector<GUID>& active);
|
||||
|
||||
/**
|
||||
* 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, std::shared_ptr<WorkArea>>> workAreaMap;
|
||||
};
|
||||
67
src/modules/fancyzones/FancyZonesLib/MonitorWorkAreaMap.cpp
Normal file
67
src/modules/fancyzones/FancyZonesLib/MonitorWorkAreaMap.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "pch.h"
|
||||
#include "MonitorWorkAreaMap.h"
|
||||
|
||||
#include <FancyZonesLib/WorkArea.h>
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkArea(HMONITOR monitor) const
|
||||
{
|
||||
auto iter = m_workAreaMap.find(monitor);
|
||||
if (iter != m_workAreaMap.end())
|
||||
{
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromCursor() const
|
||||
{
|
||||
const auto allMonitorsWorkArea = GetWorkArea(nullptr);
|
||||
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 cursor position
|
||||
POINT cursorPoint;
|
||||
if (!GetCursorPos(&cursorPoint))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetWorkArea(MonitorFromPoint(cursorPoint, MONITOR_DEFAULTTONULL));
|
||||
}
|
||||
}
|
||||
|
||||
WorkArea* const MonitorWorkAreaMap::GetWorkAreaFromWindow(HWND window) const
|
||||
{
|
||||
const auto allMonitorsWorkArea = GetWorkArea(nullptr);
|
||||
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(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& MonitorWorkAreaMap::GetAllWorkAreas() const noexcept
|
||||
{
|
||||
return m_workAreaMap;
|
||||
}
|
||||
|
||||
void MonitorWorkAreaMap::AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea)
|
||||
{
|
||||
m_workAreaMap.insert({ monitor, std::move(workArea) });
|
||||
}
|
||||
|
||||
void MonitorWorkAreaMap::Clear() noexcept
|
||||
{
|
||||
m_workAreaMap.clear();
|
||||
}
|
||||
58
src/modules/fancyzones/FancyZonesLib/MonitorWorkAreaMap.h
Normal file
58
src/modules/fancyzones/FancyZonesLib/MonitorWorkAreaMap.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuidUtils.h"
|
||||
|
||||
class WorkArea;
|
||||
|
||||
class MonitorWorkAreaMap
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Get work area based on virtual desktop id and monitor handle.
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
WorkArea* const GetWorkArea(HMONITOR monitor) const;
|
||||
|
||||
/**
|
||||
* Get work area based on virtual desktop id and the current cursor position.
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
WorkArea* const GetWorkAreaFromCursor() const;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
WorkArea* const GetWorkAreaFromWindow(HWND window) const;
|
||||
|
||||
/**
|
||||
* @returns All registered work areas.
|
||||
*/
|
||||
const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& GetAllWorkAreas() const noexcept;
|
||||
|
||||
/**
|
||||
* Register new work area.
|
||||
*
|
||||
* @param[in] monitor Monitor handle.
|
||||
* @param[in] workAra Object representing single work area.
|
||||
*/
|
||||
void AddWorkArea(HMONITOR monitor, std::unique_ptr<WorkArea> workArea);
|
||||
|
||||
/**
|
||||
* Clear all persisted work area related data.
|
||||
*/
|
||||
void Clear() noexcept;
|
||||
|
||||
private:
|
||||
std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>> m_workAreaMap;
|
||||
};
|
||||
@@ -13,9 +13,10 @@
|
||||
|
||||
#include <common/utils/elevation.h>
|
||||
|
||||
WindowDrag::WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas) :
|
||||
WindowDrag::WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& activeWorkAreas) :
|
||||
m_window(window),
|
||||
m_activeWorkAreas(activeWorkAreas),
|
||||
m_currentWorkArea(nullptr),
|
||||
m_snappingMode(false)
|
||||
{
|
||||
m_windowProperties.hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(m_window);
|
||||
@@ -28,7 +29,7 @@ WindowDrag::~WindowDrag()
|
||||
ResetWindowTransparency();
|
||||
}
|
||||
|
||||
std::unique_ptr<WindowDrag> WindowDrag::Create(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas)
|
||||
std::unique_ptr<WindowDrag> WindowDrag::Create(HWND window, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& activeWorkAreas)
|
||||
{
|
||||
if (!FancyZonesWindowProcessing::IsProcessable(window) ||
|
||||
!FancyZonesWindowUtils::IsCandidateForZoning(window) ||
|
||||
@@ -57,7 +58,7 @@ bool WindowDrag::MoveSizeStart(HMONITOR monitor, bool isSnapping)
|
||||
|
||||
if (isSnapping)
|
||||
{
|
||||
m_currentWorkArea = iter->second;
|
||||
m_currentWorkArea = iter->second.get();
|
||||
}
|
||||
|
||||
SwitchSnappingMode(isSnapping);
|
||||
@@ -72,7 +73,7 @@ void WindowDrag::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, bool is
|
||||
{
|
||||
// The drag has moved to a different monitor.
|
||||
// Change work area
|
||||
if (iter->second != m_currentWorkArea)
|
||||
if (iter->second.get() != m_currentWorkArea)
|
||||
{
|
||||
m_highlightedZones.Reset();
|
||||
|
||||
@@ -88,7 +89,7 @@ void WindowDrag::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, bool is
|
||||
}
|
||||
}
|
||||
|
||||
m_currentWorkArea = iter->second;
|
||||
m_currentWorkArea = iter->second.get();
|
||||
}
|
||||
|
||||
if (m_currentWorkArea)
|
||||
@@ -169,18 +170,6 @@ void WindowDrag::SwitchSnappingMode(bool isSnapping)
|
||||
if (m_currentWorkArea)
|
||||
{
|
||||
m_currentWorkArea->UnsnapWindow(m_window);
|
||||
FancyZonesWindowProperties::RemoveZoneIndexProperty(m_window);
|
||||
|
||||
const auto& layout = m_currentWorkArea->GetLayout();
|
||||
if (layout)
|
||||
{
|
||||
auto guidStr = FancyZonesUtils::GuidToString(layout->Id());
|
||||
if (guidStr.has_value())
|
||||
{
|
||||
AppZoneHistory::instance().RemoveAppLastZone(m_window, m_currentWorkArea->UniqueId(), guidStr.value());
|
||||
}
|
||||
}
|
||||
|
||||
Trace::WorkArea::MoveOrResizeStarted(m_currentWorkArea->GetLayout().get(), m_currentWorkArea->GetLayoutWindows().get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ class WorkArea;
|
||||
|
||||
class WindowDrag
|
||||
{
|
||||
WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas);
|
||||
WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& activeWorkAreas);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<WindowDrag> Create(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas);
|
||||
static std::unique_ptr<WindowDrag> Create(HWND window, const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& activeWorkAreas);
|
||||
~WindowDrag();
|
||||
|
||||
bool MoveSizeStart(HMONITOR monitor, bool isSnapping);
|
||||
@@ -38,8 +38,8 @@ private:
|
||||
const HWND m_window;
|
||||
WindowProperties m_windowProperties; // MoveSizeWindowInfo of the window at the moment when dragging started
|
||||
|
||||
const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& m_activeWorkAreas; // all WorkAreas on current virtual desktop, mapped with monitors
|
||||
std::shared_ptr<WorkArea> m_currentWorkArea; // "Active" WorkArea, where the move/size is happening. Will update as drag moves between monitors.
|
||||
const std::unordered_map<HMONITOR, std::unique_ptr<WorkArea>>& m_activeWorkAreas; // all WorkAreas on current virtual desktop, mapped with monitors
|
||||
WorkArea* m_currentWorkArea; // "Active" WorkArea, where the move/size is happening. Will update as drag moves between monitors.
|
||||
|
||||
bool m_snappingMode{ false };
|
||||
|
||||
|
||||
@@ -127,12 +127,12 @@ WorkArea::~WorkArea()
|
||||
windowPool.FreeZonesOverlayWindow(m_window);
|
||||
}
|
||||
|
||||
void WorkArea::MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept
|
||||
void WorkArea::MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index)
|
||||
{
|
||||
MoveWindowIntoZoneByIndexSet(window, { index });
|
||||
}
|
||||
|
||||
void WorkArea::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition /* = true*/) noexcept
|
||||
void WorkArea::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition /* = true*/)
|
||||
{
|
||||
if (!m_layout || !m_layoutWindows || m_layout->Zones().empty() || indexSet.empty())
|
||||
{
|
||||
@@ -143,18 +143,15 @@ void WorkArea::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& ind
|
||||
|
||||
if (updatePosition)
|
||||
{
|
||||
auto rect = m_layout->GetCombinedZonesRect(indexSet);
|
||||
auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||
const auto rect = m_layout->GetCombinedZonesRect(indexSet);
|
||||
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
||||
}
|
||||
|
||||
m_layoutWindows->Assign(window, indexSet);
|
||||
FancyZonesWindowProperties::StampZoneIndexProperty(window, indexSet);
|
||||
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
SnapWindow(window, indexSet);
|
||||
}
|
||||
|
||||
bool WorkArea::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle) noexcept
|
||||
bool WorkArea::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle)
|
||||
{
|
||||
if (!m_layout || !m_layoutWindows || m_layout->Zones().empty())
|
||||
{
|
||||
@@ -162,7 +159,7 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode,
|
||||
}
|
||||
|
||||
auto zoneIndexes = m_layoutWindows->GetZoneIndexSetFromWindow(window);
|
||||
auto numZones = m_layout->Zones().size();
|
||||
const auto numZones = m_layout->Zones().size();
|
||||
|
||||
// The window was not assigned to any zone here
|
||||
if (zoneIndexes.size() == 0)
|
||||
@@ -171,7 +168,7 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode,
|
||||
}
|
||||
else
|
||||
{
|
||||
ZoneIndex oldId = zoneIndexes[0];
|
||||
const ZoneIndex oldId = zoneIndexes[0];
|
||||
|
||||
// We reached the edge
|
||||
if ((vkCode == VK_LEFT && oldId == 0) || (vkCode == VK_RIGHT && oldId == static_cast<int64_t>(numZones) - 1))
|
||||
@@ -197,15 +194,10 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode,
|
||||
}
|
||||
}
|
||||
|
||||
if (!FancyZonesWindowUtils::HasVisibleOwner(window))
|
||||
{
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle) noexcept
|
||||
bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle)
|
||||
{
|
||||
if (!m_layout || !m_layoutWindows || m_layout->Zones().empty())
|
||||
{
|
||||
@@ -216,7 +208,7 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCod
|
||||
std::vector<bool> usedZoneIndices(zones.size(), false);
|
||||
auto windowZones = m_layoutWindows->GetZoneIndexSetFromWindow(window);
|
||||
|
||||
for (ZoneIndex id : windowZones)
|
||||
for (const ZoneIndex id : windowZones)
|
||||
{
|
||||
usedZoneIndices[id] = true;
|
||||
}
|
||||
@@ -250,7 +242,6 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCod
|
||||
if (result < zoneRects.size())
|
||||
{
|
||||
MoveWindowIntoZoneByIndex(window, freeZoneIndices[result]);
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(m_layout.get(), m_layoutWindows.get());
|
||||
return true;
|
||||
}
|
||||
@@ -266,7 +257,6 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCod
|
||||
if (result < zoneRects.size())
|
||||
{
|
||||
MoveWindowIntoZoneByIndex(window, result);
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
Trace::FancyZones::KeyboardSnapWindowToZone(m_layout.get(), m_layoutWindows.get());
|
||||
return true;
|
||||
}
|
||||
@@ -275,7 +265,7 @@ bool WorkArea::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCod
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noexcept
|
||||
bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode)
|
||||
{
|
||||
if (!m_layout || !m_layoutWindows || m_layout->Zones().empty())
|
||||
{
|
||||
@@ -307,7 +297,7 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noe
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ZoneIndex idx : appliedZones)
|
||||
for (const ZoneIndex idx : appliedZones)
|
||||
{
|
||||
usedZoneIndices[idx] = true;
|
||||
}
|
||||
@@ -327,7 +317,7 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noe
|
||||
}
|
||||
}
|
||||
|
||||
auto result = FancyZonesUtils::ChooseNextZoneByPosition(vkCode, windowRect, zoneRects);
|
||||
const auto result = FancyZonesUtils::ChooseNextZoneByPosition(vkCode, windowRect, zoneRects);
|
||||
if (result < zoneRects.size())
|
||||
{
|
||||
ZoneIndex targetZone = freeZoneIndices[result];
|
||||
@@ -357,14 +347,13 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noe
|
||||
resultIndexSet = m_layout->GetCombinedZoneRange(extendModeData->windowInitialIndexSet[window], { targetZone });
|
||||
}
|
||||
|
||||
auto rect = m_layout->GetCombinedZonesRect(resultIndexSet);
|
||||
auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||
const auto rect = m_layout->GetCombinedZonesRect(resultIndexSet);
|
||||
const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window);
|
||||
FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect);
|
||||
|
||||
m_layoutWindows->Extend(window, resultIndexSet);
|
||||
FancyZonesWindowProperties::StampZoneIndexProperty(window, resultIndexSet);
|
||||
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
SnapWindow(window, resultIndexSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -372,39 +361,43 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noe
|
||||
return false;
|
||||
}
|
||||
|
||||
void WorkArea::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
||||
void WorkArea::SnapWindow(HWND window, const ZoneIndexSet& zones)
|
||||
{
|
||||
if (m_layout && m_layoutWindows)
|
||||
if (!m_layoutWindows || !m_layout)
|
||||
{
|
||||
auto zoneIndexSet = m_layoutWindows->GetZoneIndexSetFromWindow(window);
|
||||
if (zoneIndexSet.size())
|
||||
{
|
||||
auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id());
|
||||
if (guidStr.has_value())
|
||||
{
|
||||
AppZoneHistory::instance().SetAppLastZones(window, m_uniqueId, guidStr.value(), zoneIndexSet);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_layoutWindows->Assign(window, zones);
|
||||
|
||||
auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id());
|
||||
if (guidStr.has_value())
|
||||
{
|
||||
AppZoneHistory::instance().SetAppLastZones(window, m_uniqueId, guidStr.value(), zones);
|
||||
}
|
||||
|
||||
FancyZonesWindowProperties::StampZoneIndexProperty(window, zones);
|
||||
}
|
||||
|
||||
bool WorkArea::UnsnapWindow(HWND window) noexcept
|
||||
void WorkArea::UnsnapWindow(HWND window)
|
||||
{
|
||||
if (!m_layoutWindows)
|
||||
if (!m_layoutWindows || !m_layout)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_layoutWindows->GetZoneIndexSetFromWindow(window).empty())
|
||||
m_layoutWindows->Dismiss(window);
|
||||
|
||||
auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id());
|
||||
if (guidStr.has_value())
|
||||
{
|
||||
m_layoutWindows->Dismiss(window);
|
||||
return true;
|
||||
AppZoneHistory::instance().RemoveAppLastZone(window, m_uniqueId, guidStr.value());
|
||||
}
|
||||
|
||||
return false;
|
||||
FancyZonesWindowProperties::RemoveZoneIndexProperty(window);
|
||||
}
|
||||
|
||||
ZoneIndexSet WorkArea::GetWindowZoneIndexes(HWND window) const noexcept
|
||||
ZoneIndexSet WorkArea::GetWindowZoneIndexes(HWND window) const
|
||||
{
|
||||
if (m_layout)
|
||||
{
|
||||
@@ -454,9 +447,9 @@ void WorkArea::FlashZones()
|
||||
}
|
||||
}
|
||||
|
||||
void WorkArea::UpdateActiveZoneSet() noexcept
|
||||
void WorkArea::UpdateActiveZoneSet()
|
||||
{
|
||||
bool isLayoutAlreadyApplied = AppliedLayouts::instance().IsLayoutApplied(m_uniqueId);
|
||||
const bool isLayoutAlreadyApplied = AppliedLayouts::instance().IsLayoutApplied(m_uniqueId);
|
||||
if (!isLayoutAlreadyApplied)
|
||||
{
|
||||
AppliedLayouts::instance().ApplyDefaultLayout(m_uniqueId);
|
||||
@@ -469,7 +462,7 @@ void WorkArea::UpdateActiveZoneSet() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
void WorkArea::CycleWindows(HWND window, bool reverse) noexcept
|
||||
void WorkArea::CycleWindows(HWND window, bool reverse)
|
||||
{
|
||||
if (m_layoutWindows)
|
||||
{
|
||||
@@ -479,7 +472,7 @@ void WorkArea::CycleWindows(HWND window, bool reverse) noexcept
|
||||
|
||||
#pragma region private
|
||||
|
||||
bool WorkArea::InitWindow(HINSTANCE hinstance) noexcept
|
||||
bool WorkArea::InitWindow(HINSTANCE hinstance)
|
||||
{
|
||||
m_window = windowPool.NewZonesOverlayWindow(m_workAreaRect, hinstance, this);
|
||||
if (!m_window)
|
||||
@@ -492,11 +485,11 @@ bool WorkArea::InitWindow(HINSTANCE hinstance) noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId) noexcept
|
||||
void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId)
|
||||
{
|
||||
Logger::info(L"Initialize layout on {}", m_uniqueId.toString());
|
||||
Logger::info(L"Initialize layout on {}, work area rect = {}x{}", m_uniqueId.toString(), m_workAreaRect.width(), m_workAreaRect.height());
|
||||
|
||||
bool isLayoutAlreadyApplied = AppliedLayouts::instance().IsLayoutApplied(m_uniqueId);
|
||||
const bool isLayoutAlreadyApplied = AppliedLayouts::instance().IsLayoutApplied(m_uniqueId);
|
||||
if (!isLayoutAlreadyApplied)
|
||||
{
|
||||
if (parentUniqueId.virtualDesktopId != GUID_NULL)
|
||||
@@ -512,7 +505,37 @@ void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId)
|
||||
CalculateZoneSet();
|
||||
}
|
||||
|
||||
void WorkArea::CalculateZoneSet() noexcept
|
||||
void WorkArea::InitSnappedWindows()
|
||||
{
|
||||
static bool updatePositionOnceOnStartFlag = true;
|
||||
Logger::info(L"Init work area windows, update positions = {}", updatePositionOnceOnStartFlag);
|
||||
|
||||
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
||||
{
|
||||
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||
if (zoneIndexSet.size() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_uniqueId.monitorId.monitor) // one work area across monitors
|
||||
{
|
||||
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||
if (monitor && m_uniqueId.monitorId.monitor == monitor)
|
||||
{
|
||||
MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatePositionOnceOnStartFlag = false;
|
||||
}
|
||||
|
||||
void WorkArea::CalculateZoneSet()
|
||||
{
|
||||
const auto appliedLayout = AppliedLayouts::instance().GetDeviceLayout(m_uniqueId);
|
||||
if (!appliedLayout.has_value())
|
||||
@@ -561,7 +584,7 @@ void WorkArea::SetWorkAreaWindowAsTopmost(HWND draggedWindow) noexcept
|
||||
|
||||
HWND windowInsertAfter = draggedWindow ? draggedWindow : HWND_TOPMOST;
|
||||
|
||||
const UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
|
||||
constexpr UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
|
||||
SetWindowPos(m_window, windowInsertAfter, 0, 0, 0, 0, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,27 @@
|
||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||
#include <FancyZonesLib/Layout.h>
|
||||
#include <FancyZonesLib/LayoutAssignedWindows.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
class ZonesOverlay;
|
||||
|
||||
class WorkArea
|
||||
{
|
||||
public:
|
||||
WorkArea(HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& uniqueId, const FancyZonesUtils::Rect& workAreaRect);
|
||||
~WorkArea();
|
||||
|
||||
public:
|
||||
~WorkArea();
|
||||
|
||||
static std::unique_ptr<WorkArea> Create(HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& uniqueId, const FancyZonesDataTypes::WorkAreaId& parentUniqueId, const FancyZonesUtils::Rect& workAreaRect)
|
||||
{
|
||||
auto self = std::unique_ptr<WorkArea>(new WorkArea(hinstance, uniqueId, workAreaRect));
|
||||
if (!self->Init(hinstance, parentUniqueId))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
inline bool Init([[maybe_unused]] HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& parentUniqueId)
|
||||
{
|
||||
#ifndef UNIT_TESTS
|
||||
@@ -23,42 +33,48 @@ public:
|
||||
}
|
||||
#endif
|
||||
InitLayout(parentUniqueId);
|
||||
InitSnappedWindows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FancyZonesDataTypes::WorkAreaId UniqueId() const noexcept { return { m_uniqueId }; }
|
||||
const std::unique_ptr<Layout>& GetLayout() const noexcept { return m_layout; }
|
||||
const std::unique_ptr<LayoutAssignedWindows>& GetLayoutWindows() const noexcept { return m_layoutWindows; }
|
||||
const HWND GetWorkAreaWindow() const noexcept { return m_window; }
|
||||
|
||||
ZoneIndexSet GetWindowZoneIndexes(HWND window) const noexcept;
|
||||
ZoneIndexSet GetWindowZoneIndexes(HWND window) const;
|
||||
|
||||
void MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept;
|
||||
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition = true) noexcept;
|
||||
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noexcept;
|
||||
void SaveWindowProcessToZoneIndex(HWND window) noexcept;
|
||||
bool UnsnapWindow(HWND window) noexcept;
|
||||
void MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index);
|
||||
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition = true);
|
||||
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle);
|
||||
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle);
|
||||
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode);
|
||||
|
||||
void UpdateActiveZoneSet() noexcept;
|
||||
void SnapWindow(HWND window, const ZoneIndexSet& zones);
|
||||
void UnsnapWindow(HWND window);
|
||||
|
||||
void UpdateActiveZoneSet();
|
||||
|
||||
void ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow = nullptr);
|
||||
void HideZonesOverlay();
|
||||
void FlashZones();
|
||||
|
||||
void CycleWindows(HWND window, bool reverse) noexcept;
|
||||
void CycleWindows(HWND window, bool reverse);
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
|
||||
private:
|
||||
bool InitWindow(HINSTANCE hinstance) noexcept;
|
||||
void InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId) noexcept;
|
||||
void CalculateZoneSet() noexcept;
|
||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
bool InitWindow(HINSTANCE hinstance);
|
||||
void InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId);
|
||||
void InitSnappedWindows();
|
||||
|
||||
void CalculateZoneSet();
|
||||
void SetWorkAreaWindowAsTopmost(HWND draggedWindow) noexcept;
|
||||
|
||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
|
||||
const FancyZonesUtils::Rect m_workAreaRect{};
|
||||
const FancyZonesDataTypes::WorkAreaId m_uniqueId;
|
||||
HWND m_window{}; // Hidden tool window used to represent current monitor desktop work area.
|
||||
@@ -66,14 +82,3 @@ private:
|
||||
std::unique_ptr<LayoutAssignedWindows> m_layoutWindows;
|
||||
std::unique_ptr<ZonesOverlay> m_zonesOverlay;
|
||||
};
|
||||
|
||||
inline std::shared_ptr<WorkArea> MakeWorkArea(HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& uniqueId, const FancyZonesDataTypes::WorkAreaId& parentUniqueId, const FancyZonesUtils::Rect& workAreaRect)
|
||||
{
|
||||
auto self = std::make_shared<WorkArea>(hinstance, uniqueId, workAreaRect);
|
||||
if (!self->Init(hinstance, parentUniqueId))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
|
||||
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
||||
#include <FancyZonesLib/FancyZonesData/DefaultLayouts.h>
|
||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||
#include <FancyZonesLib/LayoutAssignedWindows.h>
|
||||
#include "Util.h"
|
||||
|
||||
@@ -20,7 +21,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_CLASS (WorkAreaCreationUnitTests)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId m_uniqueId;
|
||||
FancyZonesDataTypes::WorkAreaId m_workAreaId;
|
||||
FancyZonesDataTypes::WorkAreaId m_emptyUniqueId;
|
||||
FancyZonesUtils::Rect m_workAreaRect{ RECT(0,0,1920,1080) };
|
||||
|
||||
@@ -29,10 +30,10 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init) noexcept
|
||||
{
|
||||
m_uniqueId.monitorId.deviceId.id = L"DELA026";
|
||||
m_uniqueId.monitorId.deviceId.instanceId = L"5&10a58c63&0&UID16777488";
|
||||
m_uniqueId.monitorId.serialNumber = L"serial-number";
|
||||
m_uniqueId.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{39B25DD2-130D-4B5D-8851-4791D66B1539}").value();
|
||||
m_workAreaId.monitorId.deviceId.id = L"DELA026";
|
||||
m_workAreaId.monitorId.deviceId.instanceId = L"5&10a58c63&0&UID16777488";
|
||||
m_workAreaId.monitorId.serialNumber = L"serial-number";
|
||||
m_workAreaId.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{39B25DD2-130D-4B5D-8851-4791D66B1539}").value();
|
||||
|
||||
AppZoneHistory::instance().LoadData();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
@@ -51,9 +52,9 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const auto defaultLayout = DefaultLayouts::instance().GetDefaultLayout();
|
||||
|
||||
auto workArea = MakeWorkArea({}, m_uniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create({}, m_workAreaId, m_emptyUniqueId, m_workAreaRect);
|
||||
Assert::IsFalse(workArea == nullptr);
|
||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||
Assert::IsTrue(m_workAreaId == workArea->UniqueId());
|
||||
|
||||
const auto& layout = workArea->GetLayout();
|
||||
Assert::IsNotNull(layout.get());
|
||||
@@ -66,9 +67,9 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const auto defaultLayout = DefaultLayouts::instance().GetDefaultLayout();
|
||||
|
||||
auto workArea = MakeWorkArea({}, m_uniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create({}, m_workAreaId, m_emptyUniqueId, m_workAreaRect);
|
||||
Assert::IsFalse(workArea == nullptr);
|
||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||
Assert::IsTrue(m_workAreaId == workArea->UniqueId());
|
||||
|
||||
const auto& layout = workArea->GetLayout();
|
||||
Assert::IsNotNull(layout.get());
|
||||
@@ -96,15 +97,15 @@ namespace FancyZonesUnitTests
|
||||
.sensitivityRadius = 20,
|
||||
};
|
||||
|
||||
auto parentWorkArea = MakeWorkArea(m_hInst, parentUniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
auto parentWorkArea = WorkArea::Create(m_hInst, parentUniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
AppliedLayouts::instance().ApplyLayout(parentUniqueId, layout);
|
||||
|
||||
auto actualWorkArea = MakeWorkArea(m_hInst, m_uniqueId, parentUniqueId, m_workAreaRect);
|
||||
auto actualWorkArea = WorkArea::Create(m_hInst, m_workAreaId, parentUniqueId, m_workAreaRect);
|
||||
Assert::IsNotNull(actualWorkArea->GetLayout().get());
|
||||
Assert::IsNotNull(actualWorkArea->GetLayoutWindows().get());
|
||||
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().contains(m_uniqueId));
|
||||
const auto& actualLayout = AppliedLayouts::instance().GetAppliedLayoutMap().at(m_uniqueId);
|
||||
Assert::IsTrue(AppliedLayouts::instance().GetAppliedLayoutMap().contains(m_workAreaId));
|
||||
const auto& actualLayout = AppliedLayouts::instance().GetAppliedLayoutMap().at(m_workAreaId);
|
||||
|
||||
Assert::AreEqual(static_cast<int>(layout.type), static_cast<int>(actualLayout.type));
|
||||
Assert::AreEqual(FancyZonesUtils::GuidToString(layout.uuid).value(), FancyZonesUtils::GuidToString(actualLayout.uuid).value());
|
||||
@@ -132,9 +133,9 @@ namespace FancyZonesUnitTests
|
||||
DefaultLayouts::instance().LoadData();
|
||||
|
||||
// test
|
||||
auto workArea = MakeWorkArea({}, m_uniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create({}, m_workAreaId, m_emptyUniqueId, m_workAreaRect);
|
||||
Assert::IsFalse(workArea == nullptr);
|
||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||
Assert::IsTrue(m_workAreaId == workArea->UniqueId());
|
||||
|
||||
Assert::IsNotNull(workArea->GetLayout().get());
|
||||
|
||||
@@ -165,9 +166,9 @@ namespace FancyZonesUnitTests
|
||||
DefaultLayouts::instance().LoadData();
|
||||
|
||||
// test
|
||||
auto workArea = MakeWorkArea({}, m_uniqueId, m_emptyUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create({}, m_workAreaId, m_emptyUniqueId, m_workAreaRect);
|
||||
Assert::IsFalse(workArea == nullptr);
|
||||
Assert::IsTrue(m_uniqueId == workArea->UniqueId());
|
||||
Assert::IsTrue(m_workAreaId == workArea->UniqueId());
|
||||
|
||||
Assert::IsNotNull(workArea->GetLayout().get());
|
||||
|
||||
@@ -178,134 +179,10 @@ namespace FancyZonesUnitTests
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (WorkAreaUnitTests)
|
||||
{
|
||||
FancyZonesDataTypes::WorkAreaId m_uniqueId;
|
||||
FancyZonesDataTypes::WorkAreaId m_parentUniqueId; // default empty
|
||||
FancyZonesUtils::Rect m_workAreaRect{ RECT(0, 0, 1920, 1080) };
|
||||
|
||||
HINSTANCE m_hInst{};
|
||||
|
||||
TEST_METHOD_INITIALIZE(Init) noexcept
|
||||
{
|
||||
m_uniqueId.monitorId.deviceId.id = L"DELA026";
|
||||
m_uniqueId.monitorId.deviceId.instanceId = L"5&10a58c63&0&UID16777488";
|
||||
m_uniqueId.monitorId.serialNumber = L"serial-number";
|
||||
m_uniqueId.virtualDesktopId = FancyZonesUtils::GuidFromString(L"{39B25DD2-130D-4B5D-8851-4791D66B1539}").value();
|
||||
|
||||
AppZoneHistory::instance().LoadData();
|
||||
AppliedLayouts::instance().LoadData();
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(CleanUp) noexcept
|
||||
{
|
||||
std::filesystem::remove(AppZoneHistory::AppZoneHistoryFileName());
|
||||
std::filesystem::remove(AppliedLayouts::AppliedLayoutsFileName());
|
||||
}
|
||||
|
||||
public:
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNullptrWindow)
|
||||
{
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(nullptr);
|
||||
|
||||
const auto actualAppZoneHistory = AppZoneHistory::instance().GetFullAppZoneHistory();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNoWindowAdded)
|
||||
{
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->GetLayout()->Init(RECT{ 0, 0, 1920, 1080 }, Mocks::Monitor());
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto actualAppZoneHistory = AppZoneHistory::instance().GetFullAppZoneHistory();
|
||||
Assert::IsTrue(actualAppZoneHistory.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexNoWindowAddedWithFilledAppZoneHistory)
|
||||
{
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = workArea->UniqueId();
|
||||
const auto& layoutId = workArea->GetLayout()->Id();
|
||||
|
||||
// fill app zone history map
|
||||
Assert::IsTrue(AppZoneHistory::instance().SetAppLastZones(window, deviceId, Helpers::GuidToString(layoutId), { 0 }));
|
||||
Assert::AreEqual((size_t)1, AppZoneHistory::instance().GetFullAppZoneHistory().size());
|
||||
const auto& appHistoryArray1 = AppZoneHistory::instance().GetFullAppZoneHistory().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray1.size());
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == appHistoryArray1.at(0).zoneIndexSet);
|
||||
|
||||
// add zone without window
|
||||
workArea->GetLayout()->Init(RECT{ 0, 0, 1920, 1080 }, Mocks::Monitor());
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(window);
|
||||
Assert::AreEqual((size_t)1, AppZoneHistory::instance().GetFullAppZoneHistory().size());
|
||||
const auto& appHistoryArray2 = AppZoneHistory::instance().GetFullAppZoneHistory().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray2.size());
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 0 } == appHistoryArray2.at(0).zoneIndexSet);
|
||||
}
|
||||
|
||||
TEST_METHOD (SaveWindowProcessToZoneIndexWindowAdded)
|
||||
{
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto deviceId = workArea->UniqueId();
|
||||
const auto& layoutId = workArea->GetLayout()->Id();
|
||||
|
||||
workArea->MoveWindowIntoZoneByIndex(window, 0);
|
||||
|
||||
//fill app zone history map
|
||||
Assert::IsTrue(AppZoneHistory::instance().SetAppLastZones(window, deviceId, Helpers::GuidToString(layoutId), { 2 }));
|
||||
Assert::AreEqual((size_t)1, AppZoneHistory::instance().GetFullAppZoneHistory().size());
|
||||
const auto& appHistoryArray = AppZoneHistory::instance().GetFullAppZoneHistory().at(processPath);
|
||||
Assert::AreEqual((size_t)1, appHistoryArray.size());
|
||||
Assert::IsTrue(std::vector<ZoneIndex>{ 2 } == appHistoryArray.at(0).zoneIndexSet);
|
||||
|
||||
workArea->SaveWindowProcessToZoneIndex(window);
|
||||
|
||||
const auto& actualAppZoneHistory = AppZoneHistory::instance().GetFullAppZoneHistory();
|
||||
Assert::AreEqual((size_t)1, actualAppZoneHistory.size());
|
||||
const auto& expected = workArea->GetLayoutWindows()->GetZoneIndexSetFromWindow(window);
|
||||
const auto& actual = appHistoryArray.at(0).zoneIndexSet;
|
||||
Assert::IsTrue(expected == actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt)
|
||||
{
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
const int originalWidth = 450;
|
||||
const int originalHeight = 550;
|
||||
|
||||
SetWindowPos(window, nullptr, 150, 150, originalWidth, originalHeight, SWP_SHOWWINDOW);
|
||||
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
|
||||
workArea->GetLayout()->Init(RECT{ 0, 0, 1920, 1080 }, Mocks::Monitor());
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_LEFT, true);
|
||||
|
||||
RECT inZoneRect;
|
||||
GetWindowRect(window, &inZoneRect);
|
||||
Assert::AreEqual(originalWidth, (int)inZoneRect.right - (int)inZoneRect.left);
|
||||
Assert::AreEqual(originalHeight, (int)inZoneRect.bottom - (int)inZoneRect.top);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS (WorkAreaMoveWindowUnitTests)
|
||||
{
|
||||
const std::wstring m_virtualDesktopIdStr = L"{A998CA86-F08D-4BCA-AED8-77F5C8FC9925}";
|
||||
const FancyZonesDataTypes::WorkAreaId m_uniqueId{
|
||||
const FancyZonesDataTypes::WorkAreaId m_workAreaId{
|
||||
.monitorId = {
|
||||
.monitor = Mocks::Monitor(),
|
||||
.deviceId = {
|
||||
@@ -338,10 +215,10 @@ namespace FancyZonesUnitTests
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::SensitivityRadiusID, json::value(0));
|
||||
|
||||
json::JsonObject workAreaId{};
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(m_uniqueId.monitorId.deviceId.id));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(m_uniqueId.monitorId.deviceId.instanceId));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(m_uniqueId.monitorId.serialNumber));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, json::value(m_uniqueId.monitorId.deviceId.number));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(m_workAreaId.monitorId.deviceId.id));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(m_workAreaId.monitorId.deviceId.instanceId));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(m_workAreaId.monitorId.serialNumber));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, json::value(m_workAreaId.monitorId.deviceId.number));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID, json::value(m_virtualDesktopIdStr));
|
||||
|
||||
json::JsonObject obj{};
|
||||
@@ -372,10 +249,10 @@ namespace FancyZonesUnitTests
|
||||
layout.SetNamedValue(NonLocalizable::AppliedLayoutsIds::SensitivityRadiusID, json::value(20));
|
||||
|
||||
json::JsonObject workAreaId{};
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(m_uniqueId.monitorId.deviceId.id));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(m_uniqueId.monitorId.deviceId.instanceId));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(m_uniqueId.monitorId.serialNumber));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, json::value(m_uniqueId.monitorId.deviceId.number));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorID, json::value(m_workAreaId.monitorId.deviceId.id));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorInstanceID, json::value(m_workAreaId.monitorId.deviceId.instanceId));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorSerialNumberID, json::value(m_workAreaId.monitorId.serialNumber));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::MonitorNumberID, json::value(m_workAreaId.monitorId.deviceId.number));
|
||||
workAreaId.SetNamedValue(NonLocalizable::AppliedLayoutsIds::VirtualDesktopID, json::value(m_virtualDesktopIdStr));
|
||||
|
||||
json::JsonObject obj{};
|
||||
@@ -407,7 +284,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareEmptyLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -424,7 +301,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareEmptyLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -441,7 +318,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -458,7 +335,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -475,7 +352,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto& layoutWindows = workArea->GetLayoutWindows();
|
||||
|
||||
@@ -494,7 +371,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -512,7 +389,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -530,7 +407,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareEmptyLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -547,7 +424,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -564,7 +441,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
// test
|
||||
@@ -581,7 +458,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -599,7 +476,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -617,7 +494,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -635,7 +512,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -653,7 +530,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
const auto& layoutWindows = workArea->GetLayoutWindows();
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
@@ -672,7 +549,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -690,7 +567,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -708,7 +585,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// prepare
|
||||
PrepareGridLayout();
|
||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||
auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_RIGHT, true); // apply to 1st zone
|
||||
|
||||
@@ -721,5 +598,86 @@ namespace FancyZonesUnitTests
|
||||
const auto& layoutWindows = workArea->GetLayoutWindows();
|
||||
Assert::IsTrue(ZoneIndexSet{ 0, 2 } == layoutWindows->GetZoneIndexSetFromWindow(window));
|
||||
}
|
||||
|
||||
TEST_METHOD (WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt)
|
||||
{
|
||||
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
constexpr int originalWidth = 450;
|
||||
constexpr int originalHeight = 550;
|
||||
|
||||
SetWindowPos(window, nullptr, 150, 150, originalWidth, originalHeight, SWP_SHOWWINDOW);
|
||||
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
|
||||
workArea->MoveWindowIntoZoneByDirectionAndIndex(window, VK_LEFT, true);
|
||||
|
||||
RECT inZoneRect;
|
||||
GetWindowRect(window, &inZoneRect);
|
||||
|
||||
Assert::AreEqual(originalWidth, (int)inZoneRect.right - (int)inZoneRect.left);
|
||||
Assert::AreEqual(originalHeight, (int)inZoneRect.bottom - (int)inZoneRect.top);
|
||||
}
|
||||
|
||||
TEST_METHOD (SnapWindowPropertyTest)
|
||||
{
|
||||
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
const ZoneIndexSet expected = { 1, 2 };
|
||||
workArea->SnapWindow(window, expected);
|
||||
|
||||
const auto actual = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||
Assert::AreEqual(expected.size(), actual.size());
|
||||
for (int i = 0; i < expected.size(); i++)
|
||||
{
|
||||
Assert::AreEqual(expected.at(i), actual.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (SnapAppZoneHistoryTest)
|
||||
{
|
||||
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
const ZoneIndexSet expected = { 1, 2 };
|
||||
workArea->SnapWindow(window, expected);
|
||||
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto history = AppZoneHistory::instance().GetZoneHistory(processPath, m_workAreaId);
|
||||
|
||||
Assert::IsTrue(history.has_value());
|
||||
Assert::AreEqual(expected.size(), history->zoneIndexSet.size());
|
||||
for (int i = 0; i < expected.size(); i++)
|
||||
{
|
||||
Assert::AreEqual(expected.at(i), history->zoneIndexSet.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (UnsnapPropertyTest)
|
||||
{
|
||||
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
workArea->SnapWindow(window, { 1, 2 });
|
||||
workArea->UnsnapWindow(window);
|
||||
|
||||
const auto actual = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||
Assert::IsTrue(actual.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD (UnsnapAppZoneHistoryTest)
|
||||
{
|
||||
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
|
||||
const auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
workArea->SnapWindow(window, { 1, 2 });
|
||||
workArea->UnsnapWindow(window);
|
||||
|
||||
const auto processPath = get_process_path(window);
|
||||
const auto history = AppZoneHistory::instance().GetZoneHistory(processPath, m_workAreaId);
|
||||
|
||||
Assert::IsFalse(history.has_value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user