[FancyZones] Fix window resize on layout change (#23829)

This commit is contained in:
Seraphima Zykova 2023-02-06 17:15:19 +01:00 committed by GitHub
parent 840b8d73b1
commit 7e008af00a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 43 deletions

View File

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

View File

@ -69,6 +69,11 @@ void LayoutAssignedWindows::Dismiss(HWND window)
FancyZonesWindowProperties::SetTabSortKeyWithinZone(window, std::nullopt);
}
std::map<HWND, ZoneIndexSet> LayoutAssignedWindows::SnappedWindows() const noexcept
{
return m_windowIndexSet;
}
ZoneIndexSet LayoutAssignedWindows::GetZoneIndexSetFromWindow(HWND window) const noexcept
{
auto it = m_windowIndexSet.find(window);

View File

@ -19,6 +19,7 @@ public :
void Extend(HWND window, const ZoneIndexSet& zones);
void Dismiss(HWND window);
std::map<HWND, ZoneIndexSet> SnappedWindows() const noexcept;
ZoneIndexSet GetZoneIndexSetFromWindow(HWND window) const noexcept;
bool IsZoneEmpty(ZoneIndex zoneIndex) const noexcept;

View File

@ -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,14 +362,21 @@ 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()

View File

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