Added more in-depth check for zone determination when dragging around

the screen. Previously, it would iterate through the zones in the order
they were added and find the first one that fit the description. While
this works in most cases, if a user wants to have overlapping zones, it
is better to iterate through all of them and find the zone that the user
expects. There are cases where a zone is completely inaccessible on drag
because of the current code. To resolve this, the zone search will look
for the smallest zone possible. The reason I chose this solution is
because this guarantees that zones are at least reachable since if a
zone was bigger than another zone, then there must be a part of it
that is exposed, therefore reachable itself. Note: this solution is for
the scenario between two zones. More than that is not guaranteed. But I
feel like this covers enough scenarios to warrant its addition.

Example:
  ----------------
  - Zone1        -
  -  ----------  -
  -  - Zone2  -  -
  -  -        -  -
  -  ----------  -
  ----------------

Previously, zone2 was inaccessible since it would iterate through 1 then
2. But 1 would always be seen first when dragging a window. With this
fix it zone2 will be accessible.
This commit is contained in:
ebbyd3 2019-09-23 16:48:51 -05:00 committed by Enrico Giordani
parent 50dae8a37b
commit af67f7782c

View File

@ -77,17 +77,33 @@ IFACEMETHODIMP ZoneSet::RemoveZone(winrt::com_ptr<IZone> zone) noexcept
IFACEMETHODIMP_(winrt::com_ptr<IZone>) ZoneSet::ZoneFromPoint(POINT pt) noexcept
{
winrt::com_ptr<IZone> smallestKnownZone = nullptr;
for (auto iter = m_zones.begin(); iter != m_zones.end(); iter++)
{
if (winrt::com_ptr<IZone> zone = iter->try_as<IZone>())
{
if (PtInRect(&zone->GetZoneRect(), pt))
RECT* newZoneRect = &zone->GetZoneRect();
if (PtInRect(newZoneRect, pt))
{
return zone;
if(smallestKnownZone == nullptr)
{
smallestKnownZone = zone;
}
else
{
RECT* r = &smallestKnownZone->GetZoneRect();
int knownZoneArea = (r->right-r->left)*(r->bottom-r->top);
int newZoneArea = (newZoneRect->right-newZoneRect->left)*(newZoneRect->bottom-newZoneRect->top);
if(newZoneArea<knownZoneArea)
smallestKnownZone = zone;
}
}
}
}
return nullptr;
return smallestKnownZone;
}
IFACEMETHODIMP_(winrt::com_ptr<IZone>) ZoneSet::ZoneFromWindow(HWND window) noexcept
@ -382,4 +398,4 @@ void ZoneSet::GenerateFocusZones(MONITORINFO const& mi) noexcept
winrt::com_ptr<IZoneSet> MakeZoneSet(ZoneSetConfig const& config) noexcept
{
return winrt::make_self<ZoneSet>(config);
}
}