Skip to content

Add DSC v3 profile resource to deploy key and shortcut remappings - #49427

Open
Gijs Reijn (Gijsreyn) wants to merge 14 commits into
microsoft:mainfrom
Gijsreyn:gh-38233/main/add-dsc-profile-resource
Open

Add DSC v3 profile resource to deploy key and shortcut remappings#49427
Gijs Reijn (Gijsreyn) wants to merge 14 commits into
microsoft:mainfrom
Gijsreyn:gh-38233/main/add-dsc-profile-resource

Conversation

@Gijsreyn

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

Adds a new DSC v3 resource, profile (Microsoft.PowerToys/KeyboardManagerProfile), to PowerToys.DSC.exe that makes Keyboard Manager key and shortcut remappings deployable via dsc.exe and winget configure. Until now, DSC only controlled whether Keyboard Manager is enabled — the actual remappings could only be created through the Keyboard Manager editor UI.

Remappings are authored with friendly, layout-invariant key names instead of raw virtual-key codes:

resources:
  - name: Deploy key remappings
    type: Microsoft.PowerToys/KeyboardManagerProfile
    properties:
      profile:
        keys:
          - { from: CapsLock, to: Esc }
          - { from: Insert, to: Disable }
        shortcuts:
          - { from: "Ctrl+Shift+A", to: "Ctrl+V" }
          - { from: "Win+O, K", toText: "chord-triggered text" }
          - { from: "Ctrl+Alt+N", to: "Ctrl+S", targetApp: "notepad.exe", exactMatch: true }

The resource supports get/set/test/export/schema/manifest, applies replace-whole-profile semantics (declarative desired state), writes the exact profile encoding the C++ editor produces, and signals a running Keyboard Manager engine to reload the remappings immediately, meaning no PowerToys restart is required.

PR Checklist

  • Closes: [KeyboardManager] [New-Feature] Keyboard Shortcuts deployable with DSC #38233
  • Closes: [KBM] Exporting and loading Key remap file / presets  #4452 (export/import of remapping configurations is covered by export + set)
  • 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 (new strings added to PowerToys.DSC Resources.resx; generated DSC manifest descriptions are deliberately not localized, matching the existing settings resource)
  • Dev docs: Added/updated (doc/dsc/profile-resource.md, doc/dsc/overview.md, doc/dsc/modules/KeyboardManager.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. The additional generated manifest (microsoft.powertoys.KeyboardManager.profile.dsc.resource.json) is picked up automatically by the installer's unfiltered DSCModules\ component glob (generateAllFileComponents.ps1)
  • 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

As remarked by AmirMS (@AmelBawa-msft) on the issue, rempapings don't live in settings.json. They're stored in a separate profile file: %LOCALAPPDATA%\Microsoft\PowerToys\Keyboard Manager\<activeConfiguration>.json. The only KBM properties that reference it in settings.json are marked [CmdConfigureIgnore] ((activeConfiguration, keyboardConfigurations).

The legacy PowerShell-based PowerToysConfigure (v2/winget 0.2 schema) path was deliberately not chosen. It drives settings through a scalar PowerToys.Settings.exe set <Module>.<Property> <value> protocol; nested lists only work through the special-cased setAdditional side-channel, which merges by a Name key into the module's settings.json and cannot target the separate profile file. Its Set() also would have killed, requiring a restart for PowerToys.

The style is also in friendly strings and not in HotkeySettings-stylish, as the shape couldn't express what remappings it needed.

@Gijsreyn
Gijs Reijn (Gijsreyn) requested a review from a team as a code owner July 21, 2026 00:41
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions github-actions Bot added Area-Localization issues regarding to Localization the application Product-Keyboard Manager labels Jul 21, 2026
Comment thread src/dsc/v3/PowerToys.DSC/DSCResources/ProfileResource.cs Outdated

[JsonPropertyName("runProgramStartInDir")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string RunProgramStartInDir { get; set; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the DSC implementation is currently depending on shared Keyboard Manager/UI code, I think it’s worth reconsidering this model change. The safer design may be for DSC to own its own storage/model types and translate to the shared library shape only where needed, rather than expanding the shared model for DSC-specific needs. I’m not a maintainer on this area, but my guess is the team may prefer keeping DSC-specific augmentation isolated from the shared library contract

@Gijsreyn

Copy link
Copy Markdown
Contributor Author

Muyuan Li (@MuyuanMS) - thanks for leaving a couple of comments. Are those all something you want me to fix?

Comment thread src/dsc/v3/PowerToys.DSC/Models/KeyboardManager/KbmShortcutParser.cs Outdated
Comment thread tools/build/generate-dsc-manifests.ps1

@MuyuanMS Muyuan Li (MuyuanMS) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One follow-up still needs an author decision in src/dsc/v3/PowerToys.DSC/Properties/Resources.resx: either localize the full validation diagnostics emitted for profile import/export problems, or narrow the user-facing checklist/resource text so it only promises the stable localized prefixes that are actually guaranteed today.

@MuyuanMS

Copy link
Copy Markdown
Contributor

Muyuan Li (@MuyuanMS) - thanks for leaving a couple of comments. Are those all something you want me to fix?

Apologies, I was trying to leverage gh api to make inline code suggestions but somehow messed up. Thanks for the quick response to let me know it failed. I've corrected it and now the comments should be valid

Gijs Reijn (Gijsreyn) and others added 11 commits August 6, 2026 16:49
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
@Gijsreyn

Copy link
Copy Markdown
Contributor Author

Muyuan Li (@MuyuanMS) - I took your suggestions, thanks a lot. I also updated the PowerShell script in the .pipelines directory and left a small comment in the code around localization.

Localizing them would add ~25 resource strings plus format-threading through the static converter/parser, while making errors harder to correlate with the document they describe.

This also follows the existing pattern in PowerToys.DSC: the settings resource already embeds raw English Exception.Message text inside its localized FailedToWriteManifests frame.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Localization issues regarding to Localization the application Product-Keyboard Manager

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[KeyboardManager] [New-Feature] Keyboard Shortcuts deployable with DSC [KBM] Exporting and loading Key remap file / presets

3 participants