Skip to content

Commit

Permalink
[FancyZones]Maximize windows within zone support
Browse files Browse the repository at this point in the history
Added support for resizing maximized windows to keep them within zone boundaries.

Holding down Shift, "bypasses" this behaviour by resizing the window to fit across all zones in the window's current workarea.

The reason for this implementation is, if the maximized window is completely unmanaged by FancyZones, any subsequent "EVENT_OBJECT_LOCATIONCHANGE" events emitted by the window would cause FancyZones to seemingly spuriously resize the window to whichever zone is under the users's cursor.  This was learned the hard way.  : )
  • Loading branch information
peddamat committed May 26, 2022
1 parent 251ea6d commit 199a760
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/modules/fancyzones/FancyZones/FancyZonesApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,14 @@ void FancyZonesApp::InitHooks()
}
}

std::array<DWORD, 6> events_to_subscribe = {
std::array<DWORD, 7> events_to_subscribe = {
EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND,
EVENT_OBJECT_NAMECHANGE,
EVENT_OBJECT_UNCLOAKED,
EVENT_OBJECT_SHOW,
EVENT_OBJECT_CREATE
EVENT_OBJECT_CREATE,
EVENT_OBJECT_LOCATIONCHANGE
};
for (const auto event : events_to_subscribe)
{
Expand Down
29 changes: 29 additions & 0 deletions src/modules/fancyzones/FancyZonesLib/FancyZones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,35 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
MoveSizeUpdate(monitor, ptScreen);
}
}
else
{
// Handle "Maximize in Zone" events
auto hwnd = reinterpret_cast<HWND>(wparam);

if (FancyZonesWindowUtils::IsCandidateForZoning(hwnd) && FancyZonesWindowUtils::IsWindowMaximized(hwnd))
{
auto monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
auto workArea = m_workAreaHandler.GetWorkArea(hwnd, VirtualDesktop::instance().GetCurrentVirtualDesktopId());
const auto zoneSet = workArea->ZoneSet();

if (zoneSet)
{
// If Shift key is pressed...
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
// ... resize window to all zones in work area
auto zones = zoneSet->GetAllZones();
MoveWindowIntoZone(hwnd, workArea, zones);
}
else
{
// ... otherwise, resize window to zone the mouse cursor is in
auto zones = zoneSet->ZonesFromPoint(ptScreen);
MoveWindowIntoZone(hwnd, workArea, zones);
}
}
}
}
}
else if (message == WM_PRIV_WINDOWCREATED)
{
Expand Down
14 changes: 14 additions & 0 deletions src/modules/fancyzones/FancyZonesLib/ZoneSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct ZoneSet : winrt::implements<ZoneSet, IZoneSet>
Id() const noexcept { return m_config.Id; }
IFACEMETHODIMP_(FancyZonesDataTypes::ZoneSetLayoutType)
LayoutType() const noexcept { return m_config.LayoutType; }
IFACEMETHODIMP_(ZoneIndexSet) GetAllZones() const noexcept;
IFACEMETHODIMP_(ZoneIndexSet) ZonesFromPoint(POINT pt) const noexcept;
IFACEMETHODIMP_(ZoneIndexSet) GetZoneIndexSetFromWindow(HWND window) const noexcept;
IFACEMETHODIMP_(ZonesMap) GetZones()const noexcept override { return m_zones; }
Expand Down Expand Up @@ -80,6 +81,19 @@ struct ZoneSet : winrt::implements<ZoneSet, IZoneSet>
ZoneSetConfig m_config;
};

IFACEMETHODIMP_(ZoneIndexSet)
ZoneSet::GetAllZones() const noexcept
{
ZoneIndexSet capturedZones;
for (const auto& [zoneId, zone] : m_zones)
{
capturedZones.emplace_back(zoneId);
}

return capturedZones;
}


IFACEMETHODIMP_(ZoneIndexSet)
ZoneSet::ZonesFromPoint(POINT pt) const noexcept
{
Expand Down
6 changes: 6 additions & 0 deletions src/modules/fancyzones/FancyZonesLib/ZoneSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
* @returns Type of the zone layout. Layout type can be focus, columns, rows, grid, priority grid or custom.
*/
IFACEMETHOD_(FancyZonesDataTypes::ZoneSetLayoutType, LayoutType)() const = 0;
/**
* Get all zones contained within the ZoneSet.
*
* @returns Vector of indices, corresponding to the current set of zones contained within the ZoneSet's workarea.
*/
IFACEMETHOD_(ZoneIndexSet, GetAllZones)() const = 0;
/**
* Get zones from cursor coordinates.
*
Expand Down

0 comments on commit 199a760

Please sign in to comment.