From fd88fa18d44d96d4090c8c3fe42c9ee98de86631 Mon Sep 17 00:00:00 2001 From: Kai Tao <69313318+vanzue@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:23:40 +0800 Subject: [PATCH] Fancyzones: Fix a custom layout not work in fancyzone and powertoys extension (#44661) ## Summary of the Pull Request 1. Fix a issue that fancyzone custom layouts be able to work 2. Fix monitor info build and the icon render ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed image --- .../FancyZones/FancyZonesMonitorListItem.cs | 13 +++++++++---- .../Helpers/FancyZonesMonitorDescriptor.cs | 8 ++++++-- .../Helpers/FancyZonesThumbnailRenderer.cs | 13 +++++++++++-- .../FancyZonesEditorCommon/Data/CustomLayouts.cs | 3 +++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Commands/FancyZones/FancyZonesMonitorListItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Commands/FancyZones/FancyZonesMonitorListItem.cs index 3675c45311..b8d6082ee4 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Commands/FancyZones/FancyZonesMonitorListItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Commands/FancyZones/FancyZonesMonitorListItem.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Globalization; using Microsoft.CommandPalette.Extensions; @@ -41,15 +42,19 @@ internal sealed partial class FancyZonesMonitorListItem : ListItem public static Details BuildMonitorDetails(FancyZonesMonitorDescriptor monitor) { var currentVirtualDesktop = FancyZonesVirtualDesktop.GetCurrentVirtualDesktopIdString(); + + // Calculate physical resolution from logical pixels and DPI + var scaleFactor = monitor.Data.Dpi > 0 ? monitor.Data.Dpi / 96.0 : 1.0; + var physicalWidth = (int)Math.Round(monitor.Data.MonitorWidth * scaleFactor); + var physicalHeight = (int)Math.Round(monitor.Data.MonitorHeight * scaleFactor); + var resolution = $"{physicalWidth}\u00D7{physicalHeight}"; + var tags = new List { DetailTag(Resources.FancyZones_Monitor, monitor.Data.Monitor), - DetailTag(Resources.FancyZones_Instance, monitor.Data.MonitorInstanceId), - DetailTag(Resources.FancyZones_Serial, monitor.Data.MonitorSerialNumber), DetailTag(Resources.FancyZones_Number, monitor.Data.MonitorNumber.ToString(CultureInfo.InvariantCulture)), DetailTag(Resources.FancyZones_VirtualDesktop, currentVirtualDesktop), - DetailTag(Resources.FancyZones_WorkArea, $"{monitor.Data.LeftCoordinate},{monitor.Data.TopCoordinate} {monitor.Data.WorkAreaWidth}\u00D7{monitor.Data.WorkAreaHeight}"), - DetailTag(Resources.FancyZones_Resolution, $"{monitor.Data.MonitorWidth}\u00D7{monitor.Data.MonitorHeight}"), + DetailTag(Resources.FancyZones_Resolution, resolution), DetailTag(Resources.FancyZones_DPI, monitor.Data.Dpi.ToString(CultureInfo.InvariantCulture)), }; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesMonitorDescriptor.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesMonitorDescriptor.cs index 4e3f7092a4..e0716f2a56 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesMonitorDescriptor.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesMonitorDescriptor.cs @@ -19,8 +19,12 @@ internal readonly record struct FancyZonesMonitorDescriptor( { get { - var size = $"{Data.MonitorWidth}×{Data.MonitorHeight}"; - var scaling = Data.Dpi > 0 ? string.Format(CultureInfo.InvariantCulture, "{0}%", (int)Math.Round(Data.Dpi * 100 / 96.0)) : "n/a"; + // MonitorWidth/Height are logical (DPI-scaled) pixels, calculate physical resolution + var scaleFactor = Data.Dpi > 0 ? Data.Dpi / 96.0 : 1.0; + var physicalWidth = (int)Math.Round(Data.MonitorWidth * scaleFactor); + var physicalHeight = (int)Math.Round(Data.MonitorHeight * scaleFactor); + var size = $"{physicalWidth}×{physicalHeight}"; + var scaling = Data.Dpi > 0 ? string.Format(CultureInfo.InvariantCulture, "{0}%", (int)Math.Round(scaleFactor * 100)) : "n/a"; return $"{size} \u2022 {scaling}"; } } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesThumbnailRenderer.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesThumbnailRenderer.cs index 579b4e2d0e..514693c26e 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesThumbnailRenderer.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/FancyZonesThumbnailRenderer.cs @@ -485,12 +485,21 @@ internal static class FancyZonesThumbnailRenderer private static List GetFocusRects(int zoneCount) { + // Focus layout parameters from FancyZonesEditor CanvasLayoutModel: + // - DefaultOffset = 100px from top-left (normalized: ~0.05 for typical screen) + // - OffsetShift = 50px per zone (normalized: ~0.025) + // - ZoneSizeMultiplier = 0.4 (zones are 40% of screen) zoneCount = Math.Clamp(zoneCount, 1, 8); var rects = new List(zoneCount); + + const float defaultOffset = 0.05f; // ~100px on 1920px screen + const float offsetShift = 0.025f; // ~50px on 1920px screen + const float zoneSize = 0.4f; // 40% of screen + for (var i = 0; i < zoneCount; i++) { - var offset = i * 0.06f; - rects.Add(new NormalizedRect(0.1f + offset, 0.1f + offset, 0.8f, 0.8f)); + var offset = i * offsetShift; + rects.Add(new NormalizedRect(defaultOffset + offset, defaultOffset + offset, zoneSize, zoneSize)); } return rects; diff --git a/src/modules/fancyzones/FancyZonesEditorCommon/Data/CustomLayouts.cs b/src/modules/fancyzones/FancyZonesEditorCommon/Data/CustomLayouts.cs index 75671e8ed8..4e3a2cc6bc 100644 --- a/src/modules/fancyzones/FancyZonesEditorCommon/Data/CustomLayouts.cs +++ b/src/modules/fancyzones/FancyZonesEditorCommon/Data/CustomLayouts.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Text.Json; +using System.Text.Json.Serialization; using static FancyZonesEditorCommon.Data.CustomLayouts; @@ -23,8 +24,10 @@ namespace FancyZonesEditorCommon.Data { public struct CanvasZoneWrapper { + [JsonPropertyName("X")] public int X { get; set; } + [JsonPropertyName("Y")] public int Y { get; set; } public int Width { get; set; }