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
---
.../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; }