[Settings] Defer shortcut editor construction until first open #50532

Open
niels9001 opened 1:34pm on September 11, 2026 wants to merge 518 Ξ” into microsoft/powertoys main from
niels9001-deferred-shortcut-editors
Diff Delta:
518
Classified as:  General

niels9001's Description of Work

Summary of the Pull Request

Defer the shared Settings shortcut editor's ShortcutDialogContentControl and ContentDialog until the user first opens the editor. Displaying or updating a shortcut summary, including repeated Loaded/Unloaded cycles, no longer constructs the hidden editor.

PR Checklist


  • [ ] Closes: N/A - scoped follow-up to the Settings app performance audit.
    <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) -->

  • [x] Communication: Requested as an independent draft PR in the Settings audit-fix batch.

  • [x] Tests: Added 10 lifecycle/state cases; all pass together with 42 existing related viewmodel tests.

  • [x] Localization: No new end-user-facing strings; existing localized editor strings are reused.

  • [x] Dev docs: N/A - no public interface or developer workflow changes.

  • [x] New binaries: N/A - no new binaries.



  • [ ] Documentation updated: N/A - no user-facing configuration changes.

Detailed Description of the Pull Request / Additional comments

src/settings-ui/Settings.UI/SettingsXAML/Controls/ShortcutControl/ShortcutControl.xaml.cs:


  • Creates both editor objects in one idempotent EnsureEditor method, invoked by the first-open preparation path.

  • Primes current shortcut keys, conflict state, AltGr warning, XamlRoot, theme and the current save candidate on every open. Summary updates only touch editor content if it already exists.

  • Applies the latest AllowDisable description when the deferred content is created.

  • Gives editor-owned handlers the same lifetime as the reusable dialog, preserving Learn More after reload. The previous Unloaded path removed its handler permanently.

  • Reattaches hotkey property notifications and refreshes conflict state after reload. Reset and Clear use the existing HotkeySettings setter so replacement settings keep the same notification wiring.

  • Detaches window activation from the exact subscribed window; unload/dispose hides an existing dialog, deactivates capture and disposes the hook without creating editor UI.

src/settings-ui/Settings.UI.UnitTests/Controls/ShortcutControlTests.cs adds in-process XAML lifecycle/state coverage using the existing MSTest project. It does not instantiate the Settings application, connect to Runner, display a window, or use real-user settings.

src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj stages the existing Windows App SDK as self-contained and unpackaged for that in-process XAML host. It disables generation of the duplicate UndockedRegFreeWinRT initializer; the fixture explicitly runs the referenced Settings module's existing initializer before starting WinUI. No new package, warning suppression, project, output path, or platform/RID changes are introduced. The existing x64/ARM64 runtime-identifier selection is retained. The mixed test invocation below covers compatibility with existing non-UI tests; ARM64 build/runtime and CI artifact staging were not exercised locally.

Deferral mechanism: x:Load="False" supersedes x:DeferLoadStrategy="Lazy" and additionally supports unloading. Both apply to XAML-created elements, not these C# constructors. Moving this dialog to markup would also abandon the existing dark-theme/XAML-island workaround. Resolving deferred names/content immediately from ordinary setters would defeat markup deferral. This change therefore uses actual C# lazy construction and keeps XAML unchanged; it does not assume deferral automatically improves whole-page latency.

Performance scope: The prior diagnostic Release A/B at bb656da414 avoided eight hidden editor bodies on Advanced Paste and reduced the measured XAML initialization interval from 86.84 ms to 54.66 ms. That was a diagnostic experiment, not a measurement of this production patch, and did not establish a whole-page first-render improvement. This PR makes no end-to-end speedup claim.

Risk/scope: The shared control affects all Settings shortcut editors, so first-open, reopen and virtualization lifecycle behavior are the principal risks. Existing keyboard capture, accessibility filtering and modifier/AltGr handling are retained. No changes to Advanced Paste provider dialogs, Home rows, settings/IPC schemas, GPO, elevation, installers or dependencies.

Validation Steps Performed


  • Built Settings and the existing unit-test project in x64 Release through the affected graph:
    tools\build\build.ps1 -Platform x64 -Configuration Release -Path src\settings-ui\Settings.UI.UnitTests /m:2 (exit 0).

  • Restored missing fresh-worktree dependencies through the same script using /t:Restore /p:RestorePackagesConfig=true /p:RestoreRepositoryPath=<worktree>\packages, plus a targeted restore of src\settings-ui\Settings.UI.XamlIndexBuilder. No full-product build was required.

  • Rebuilt the final test-host changes against the already-built product:
    tools\build\build.ps1 -Platform x64 -Configuration Release -Path src\settings-ui\Settings.UI.UnitTests /m:2 /p:BuildProjectReferences=false (exit 0).

  • Ran the existing MSTest executable:
    Release\x64\tests\SettingsTests\net10.0-windows10.0.26100.0\Settings.UI.UnitTests.exe --filter "FullyQualifiedName~ShortcutControlTests|FullyQualifiedName~ViewModelTests.ShortcutGuide|FullyQualifiedName~ViewModelTests.FancyZones" --report-trx
    52 passed, 0 failed, 0 skipped. This includes 10 new cases for no construction while displaying/reloading summaries, latest state/description/theme on first open and reuse, empty/missing hotkeys, handler lifetime, modifier/AltGr capture logic, cancel/reopen/save, and Reset/Clear replacement subscriptions.

  • Reviewed the patch and verified no editor construction occurs in the constructor, summary setters or Loaded/Unloaded paths.


  • Limits: These tests drive actual WinUI controls and their lifecycle/input handlers in-process, not a visible modal dialog. They do not establish physical keyboard-hook, UIA/screen-reader, real XamlRoot/window migration, interactive Learn More navigation, Runner IPC, or end-to-end performance results. Installed Settings/Runner processes and real-user settings were not modified. ARM64 and the full Settings unit/UI suites were not run.

3 total changed files
(1 file ignored)
Loading changes...
Loading changes...
PR terminus reached:
PR review complete, one step closer to shipping πŸš€