feat: Add Microsoft DSC FancyZonesLayouts resource #50545

Open
Gijsreyn opened 10:13pm on September 12, 2026 wants to merge 1 commit into microsoft/powertoys main from
gh-50544/main/add-fancyzones-layout-resource
Diff Delta:
0
About 0 Diff Delta/hour
Classified as:  Feature Add

Gijsreyn's Description of Work

Summary of the Pull Request

Adds a new DSC v3 resource, layouts (Microsoft.PowerToys/FancyZonesLayouts), to PowerToys.DSC.exe that makes FancyZones layouts deployable via dsc.exe and winget configure. Until now, DSC only controlled the FancyZones settings (activation, appearance, behavior) β€” the layouts themselves could only be created through the FancyZones editor.

The resource manages the four portable layout files FancyZones keeps next to its settings: custom layouts, layout templates, quick layout hotkeys and default layouts. Layouts are authored with friendly, camel-cased property names, and layout identifiers may be given with or without braces:

resources:

- name: Deploy FancyZones layouts
type: Microsoft.PowerToys/FancyZonesLayouts
properties:
layouts:
custom:
- uuid: "{5C4F1A20-9B3E-4C7D-8E2F-1A2B3C4D5E6F}"
name: Two columns 70/30
grid:
rows: 1
columns: 2
rowsPercentage: [10000]
columnsPercentage: [7000, 3000]
cellChildMap: [[0, 1]]
- uuid: "{8F0B6D3E-2C41-4A5B-9D7E-0F1A2B3C4D5E}"
name: Reference window
canvas:
refWidth: 1920
refHeight: 1080
zones:
- { x: 0, y: 0, width: 1280, height: 1080 }
- { x: 1280, y: 0, width: 640, height: 1080 }
templates:
- { type: priority-grid, zoneCount: 3 }
hotkeys:
- { key: 1, layoutId: "{5C4F1A20-9B3E-4C7D-8E2F-1A2B3C4D5E6F}" }
defaults:
horizontal: { type: custom, uuid: "{5C4F1A20-9B3E-4C7D-8E2F-1A2B3C4D5E6F}" }
vertical: { type: rows, zoneCount: 2 }

The resource supports get/set/test/export/schema/manifest. Every section is optional: a section that is present replaces the whole layout file it maps to (declarative desired state), a section that is omitted is left unmanaged, so a configuration can, for example, assign hotkeys without touching the layouts created in the editor. Files are written through the same serialization context the FancyZones editor uses, so DSC-written files are indistinguishable from editor-written ones, and a running FancyZones instance picks them up immediately through its existing file watchers (no restart required).

PR Checklist


  • [x] Closes: #50544

  • [ ] Communication: I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected

  • [x] Tests: Added/updated and all pass (47 new tests in PowerToys.DSC.UnitTests: command tests, end-to-end get/set/test/export tests against a temporary data folder, and converter unit tests; the full DSC suite passes with 179 tests)

  • [x] Localization: All end-user-facing strings can be localized (new strings InvalidLayoutsError and LayoutsWarning added to PowerToys.DSC Resources.resx; the generated DSC manifest description is deliberately not localized, matching the existing settings and profile resources)

  • [x] Dev docs: Added/updated (doc/dsc/layouts-resource.md, doc/dsc/overview.md, doc/dsc/modules/FancyZones.md, doc/devdocs/core/settings/dsc-configure.md)

  • [ ] New binaries: Added on the required places β€” n/a: no new binaries; the resource lives in the existing PowerToys.DSC.exe. PowerToys.DSC.csproj gains a project reference to FancyZonesEditorCommon, whose PowerToys.FancyZonesEditorCommon.dll already ships in the installation root as a dependency of the FancyZones CLI. The additional generated manifest (microsoft.powertoys.FancyZones.layouts.dsc.resource.json) is picked up automatically by the installer's unfiltered DSCModules\ component glob (generateAllFileComponents.ps1)


    • [ ] JSON for signing for new binaries β€” n/a

    • [ ] WXS for installer for new binaries and localization folder β€” n/a

    • [ ] YML for CI pipeline for new test projects β€” n/a: tests were added to the existing PowerToys.DSC.UnitTests project. The manifest generation scripts (.pipelines/generateDscManifests.ps1, tools/build/generate-dsc-manifests.ps1) and the post-build target in PowerToys.DSC.csproj now also generate the layouts manifest

    • [ ] YML for signed pipeline β€” n/a



  • [ ] Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx
    ## Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

54 total changed files
(4 files ignored)

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

This diff is too large to display at this time. You can review it on GitHub

You’ve reached the end of the pull request
The diff well is dry.