From 7e008af00ab73ef7466dfab05dc4b4e73089d7a8 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Mon, 6 Feb 2023 17:15:19 +0100 Subject: [PATCH] [FancyZones] Fix window resize on layout change (#23829) --- .../fancyzones/FancyZonesLib/FancyZones.cpp | 53 +++++++++---------- .../FancyZonesLib/LayoutAssignedWindows.cpp | 5 ++ .../FancyZonesLib/LayoutAssignedWindows.h | 1 + .../fancyzones/FancyZonesLib/WorkArea.cpp | 47 +++++++++++----- .../fancyzones/FancyZonesLib/WorkArea.h | 3 +- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp index 4659f7b34f..b45e28ac59 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp +++ b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp @@ -118,13 +118,13 @@ public: LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept; void OnDisplayChange(DisplayChangeType changeType) noexcept; - void AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept; + void AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id, bool updateWindowsPositions) noexcept; protected: static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept; private: - void UpdateWorkAreas() noexcept; + void UpdateWorkAreas(bool updateWindowPositions) noexcept; void CycleWindows(bool reverse) noexcept; bool OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexcept; bool OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept; @@ -139,8 +139,7 @@ private: void MoveWindowIntoZone(HWND window, WorkArea* const workArea, const ZoneIndexSet& zoneIndexSet) noexcept; bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept; - void OnEditorExitEvent() noexcept; - void UpdateZoneSets() noexcept; + void UpdateActiveLayouts() noexcept; bool ShouldProcessSnapHotkey(DWORD vkCode) noexcept; void ApplyQuickLayout(int key) noexcept; void FlashZones() noexcept; @@ -618,15 +617,8 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa } else if (message == WM_PRIV_EDITOR) { - if (lparam == static_cast(EditorExitKind::Exit)) - { - OnEditorExitEvent(); - } - - { - // Clean up the event either way - m_terminateEditorEvent.release(); - } + // Clean up the event either way + m_terminateEditorEvent.release(); } else if (message == WM_PRIV_MOVESIZESTART) { @@ -667,7 +659,7 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa else if (message == WM_PRIV_APPLIED_LAYOUTS_FILE_UPDATE) { AppliedLayouts::instance().LoadData(); - UpdateZoneSets(); + UpdateActiveLayouts(); } else if (message == WM_PRIV_DEFAULT_LAYOUTS_FILE_UPDATE) { @@ -711,10 +703,12 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept } } - UpdateWorkAreas(); + bool updateWindowsPositionsOnResolutionChange = FancyZonesSettings::settings().displayChange_moveWindows && changeType == DisplayChangeType::DisplayChange; + bool updateWindowsPositionsOnStart = FancyZonesSettings::settings().zoneSetChange_moveWindows && changeType == DisplayChangeType::Initialization; + UpdateWorkAreas(updateWindowsPositionsOnResolutionChange || updateWindowsPositionsOnStart); } -void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept +void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id, bool updateWindowsPositions) noexcept { wil::unique_cotaskmem_string virtualDesktopIdStr; if (!SUCCEEDED(StringFromCLSID(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), &virtualDesktopIdStr))) @@ -742,8 +736,12 @@ void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAr auto workArea = WorkArea::Create(m_hinstance, id, parentId, rect); if (workArea) { + if (updateWindowsPositions) + { + workArea->UpdateWindowPositions(); + } + m_workAreaHandler.AddWorkArea(monitor, std::move(workArea)); - AppliedLayouts::instance().SaveData(); } } @@ -761,7 +759,7 @@ LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam, DefWindowProc(window, message, wparam, lparam); } -void FancyZones::UpdateWorkAreas() noexcept +void FancyZones::UpdateWorkAreas(bool updateWindowPositions) noexcept { m_workAreaHandler.Clear(); @@ -771,7 +769,7 @@ void FancyZones::UpdateWorkAreas() noexcept workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId(); workAreaId.monitorId = { .deviceId = { .id = ZonedWindowProperties::MultiMonitorName, .instanceId = ZonedWindowProperties::MultiMonitorInstance } }; - AddWorkArea(nullptr, workAreaId); + AddWorkArea(nullptr, workAreaId, updateWindowPositions); } else { @@ -782,7 +780,7 @@ void FancyZones::UpdateWorkAreas() noexcept workAreaId.virtualDesktopId = VirtualDesktop::instance().GetCurrentVirtualDesktopId(); workAreaId.monitorId = monitor; - AddWorkArea(monitor.monitor, workAreaId); + AddWorkArea(monitor.monitor, workAreaId, updateWindowPositions); } } } @@ -1117,19 +1115,18 @@ void FancyZones::SettingsUpdate(SettingId id) } } -void FancyZones::OnEditorExitEvent() noexcept -{ - // Collect information about changes in zone layout after editor exited. - UpdateZoneSets(); -} - -void FancyZones::UpdateZoneSets() noexcept +void FancyZones::UpdateActiveLayouts() noexcept { for (const auto& [_, workArea] : m_workAreaHandler.GetAllWorkAreas()) { if (workArea) { workArea->UpdateActiveZoneSet(); + + if (FancyZonesSettings::settings().zoneSetChange_moveWindows) + { + workArea->UpdateWindowPositions(); + } } } } @@ -1197,7 +1194,7 @@ void FancyZones::ApplyQuickLayout(int key) noexcept { AppliedLayouts::instance().ApplyLayout(workArea->UniqueId(), layout.value()); AppliedLayouts::instance().SaveData(); - UpdateZoneSets(); + UpdateActiveLayouts(); FlashZones(); } } diff --git a/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.cpp b/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.cpp index 45ab955d76..75cc6b5fa4 100644 --- a/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.cpp +++ b/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.cpp @@ -69,6 +69,11 @@ void LayoutAssignedWindows::Dismiss(HWND window) FancyZonesWindowProperties::SetTabSortKeyWithinZone(window, std::nullopt); } +std::map LayoutAssignedWindows::SnappedWindows() const noexcept +{ + return m_windowIndexSet; +} + ZoneIndexSet LayoutAssignedWindows::GetZoneIndexSetFromWindow(HWND window) const noexcept { auto it = m_windowIndexSet.find(window); diff --git a/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.h b/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.h index ae7c3d4fd2..64377e36b1 100644 --- a/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.h +++ b/src/modules/fancyzones/FancyZonesLib/LayoutAssignedWindows.h @@ -19,6 +19,7 @@ public : void Extend(HWND window, const ZoneIndexSet& zones); void Dismiss(HWND window); + std::map SnappedWindows() const noexcept; ZoneIndexSet GetZoneIndexSetFromWindow(HWND window) const noexcept; bool IsZoneEmpty(ZoneIndex zoneIndex) const noexcept; diff --git a/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp b/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp index ab71fbc796..d418adffb7 100644 --- a/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp +++ b/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp @@ -144,8 +144,11 @@ void WorkArea::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& ind if (updatePosition) { const auto rect = m_layout->GetCombinedZonesRect(indexSet); - const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window); - FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect); + if (rect.bottom - rect.top > 0 && rect.right - rect.left > 0) + { + const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window); + FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect); + } } SnapWindow(window, indexSet); @@ -351,9 +354,7 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) const auto adjustedRect = FancyZonesWindowUtils::AdjustRectForSizeWindowToRect(window, rect, m_window); FancyZonesWindowUtils::SizeWindowToRect(window, adjustedRect); - m_layoutWindows->Extend(window, resultIndexSet); - - SnapWindow(window, resultIndexSet); + SnapWindow(window, resultIndexSet, true); return true; } @@ -361,15 +362,22 @@ bool WorkArea::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) return false; } -void WorkArea::SnapWindow(HWND window, const ZoneIndexSet& zones) +void WorkArea::SnapWindow(HWND window, const ZoneIndexSet& zones, bool extend) { if (!m_layoutWindows || !m_layout) { return; } - m_layoutWindows->Assign(window, zones); - + if (extend) + { + m_layoutWindows->Extend(window, zones); + } + else + { + m_layoutWindows->Assign(window, zones); + } + auto guidStr = FancyZonesUtils::GuidToString(m_layout->Id()); if (guidStr.has_value()) { @@ -462,6 +470,20 @@ void WorkArea::UpdateActiveZoneSet() } } +void WorkArea::UpdateWindowPositions() +{ + if (!m_layoutWindows) + { + return; + } + + const auto& snappedWindows = m_layoutWindows->SnappedWindows(); + for (const auto& [window, zones] : snappedWindows) + { + MoveWindowIntoZoneByIndexSet(window, zones, true); + } +} + void WorkArea::CycleWindows(HWND window, bool reverse) { if (m_layoutWindows) @@ -507,8 +529,7 @@ void WorkArea::InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId) void WorkArea::InitSnappedWindows() { - static bool updatePositionOnceOnStartFlag = true; - Logger::info(L"Init work area windows, update positions = {}", updatePositionOnceOnStartFlag); + Logger::info(L"Init work area windows"); for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop()) { @@ -520,19 +541,17 @@ void WorkArea::InitSnappedWindows() if (!m_uniqueId.monitorId.monitor) // one work area across monitors { - MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag); + MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, false); } else { const auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL); if (monitor && m_uniqueId.monitorId.monitor == monitor) { - MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositionOnceOnStartFlag); + MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, false); } } } - - updatePositionOnceOnStartFlag = false; } void WorkArea::CalculateZoneSet() diff --git a/src/modules/fancyzones/FancyZonesLib/WorkArea.h b/src/modules/fancyzones/FancyZonesLib/WorkArea.h index a273b31675..ae0f4f1a5b 100644 --- a/src/modules/fancyzones/FancyZonesLib/WorkArea.h +++ b/src/modules/fancyzones/FancyZonesLib/WorkArea.h @@ -51,10 +51,11 @@ public: bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle); bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode); - void SnapWindow(HWND window, const ZoneIndexSet& zones); + void SnapWindow(HWND window, const ZoneIndexSet& zones, bool extend = false); void UnsnapWindow(HWND window); void UpdateActiveZoneSet(); + void UpdateWindowPositions(); void ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow = nullptr); void HideZonesOverlay();