diff --git a/src/modules/fancyzones/lib/Settings.h b/src/modules/fancyzones/lib/Settings.h index ef085e1221..da0026f137 100644 --- a/src/modules/fancyzones/lib/Settings.h +++ b/src/modules/fancyzones/lib/Settings.h @@ -20,7 +20,8 @@ struct Settings Smallest = 0, Largest = 1, Positional = 2, - EnumElements = 3, // number of elements in the enum, not counting this + ClosestCenter = 3, + EnumElements = 4, // number of elements in the enum, not counting this }; // The values specified here are the defaults. diff --git a/src/modules/fancyzones/lib/ZoneSet.cpp b/src/modules/fancyzones/lib/ZoneSet.cpp index 1f4dd7376a..324d6a5807 100644 --- a/src/modules/fancyzones/lib/ZoneSet.cpp +++ b/src/modules/fancyzones/lib/ZoneSet.cpp @@ -20,6 +20,7 @@ using namespace FancyZonesUtils; namespace { constexpr int C_MULTIPLIER = 10000; + constexpr int OVERLAPPING_CENTERS_SENSITIVITY = 75; // PriorityGrid layout is unique for zoneCount <= 11. For zoneCount > 11 PriorityGrid is same as Grid FancyZonesDataTypes::GridLayoutInfo predefinedPriorityGridLayouts[11] = { @@ -255,6 +256,28 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept return max(rect.bottom - rect.top, 0) * max(rect.right - rect.left, 0); }; + auto getCenter = [](auto zone) { + RECT rect = zone->GetZoneRect(); + return POINT{ (rect.right + rect.left) / 2, (rect.top + rect.bottom) / 2 }; + }; + auto pointDifference = [](POINT pt1, POINT pt2) { + return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y); + }; + auto distanceFromCenter = [&](auto zone) { + POINT center = getCenter(zone); + return pointDifference(center, pt); + }; + auto closerToCenter = [&](auto zone1, auto zone2) { + if (pointDifference(getCenter(zone1), getCenter(zone2)) > OVERLAPPING_CENTERS_SENSITIVITY) + { + return distanceFromCenter(zone1) < distanceFromCenter(zone2); + } + else + { + return zoneArea(zone1) < zoneArea(zone2); + }; + }; + try { using Algorithm = Settings::OverlappingZonesAlgorithm; @@ -267,6 +290,8 @@ ZoneSet::ZonesFromPoint(POINT pt) const noexcept return ZoneSelectPriority(capturedZones, [&](auto zone1, auto zone2) { return zoneArea(zone1) > zoneArea(zone2); }); case Algorithm::Positional: return ZoneSelectSubregion(capturedZones, pt); + case Algorithm::ClosestCenter: + return ZoneSelectPriority(capturedZones, closerToCenter); } } catch (std::out_of_range) diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index 8a6757843a..a021a1bd6a 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -957,6 +957,9 @@ Editor + + Activate the zone whose center is closest to the cursor + Activate the largest zone by area diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml index a72cec9508..a42baf17c5 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/FancyZonesPage.xaml @@ -134,6 +134,7 @@ +