close
Skip to content

[Keyboard Manager] Toggle module hotkey/shortcut#42472

Merged
niels9001 merged 14 commits into
microsoft:mainfrom
weikequ:keyboard-manager-toggle-shortcut
Feb 12, 2026
Merged

[Keyboard Manager] Toggle module hotkey/shortcut#42472
niels9001 merged 14 commits into
microsoft:mainfrom
weikequ:keyboard-manager-toggle-shortcut

Conversation

@weikequ

@weikequ weikequ commented Oct 17, 2025

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

Adds a keyboard shortcut to be able to toggle the Keyboard Manager module on and off.

PR Checklist

Detailed Description of the Pull Request / Additional comments

Modeled the changes and addition of a global shortcut using the Color Picker module.

Notes:

  • This uses KeyboardManagerSettings and the associated .json settings file. I don't think there's anything else in this module that uses this.
  • The default key binding for this is winkey + shift + k
  • I've had to update the KeyboardManagerViewModel to extend PageViewModelBase as opposed to Observable to get it to work. But I will say that there were some things in here that I didn't fully dig into, so let me know if there's any potential things I'm missing.
  • I'm not too sure how to update the Settings UI after a hotkey is pressed (pressing the hotkey currently will not show the module being toggled off) - can't find a good way to refresh the settings ui after enabling/disabling the module. Any pointers here would be appreciated!

Validation Steps Performed

  • Manually validated the following items:
    • Using the default shortcut (winkey + shift + k)
    • Changing the shortcut
    • Ensuring the change is persistent

Media

Screen.Recording.2025-10-21.173753.mp4

@weikequ

weikequ commented Oct 17, 2025

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@weikequ weikequ marked this pull request as ready for review October 23, 2025 21:13
@mike-mgt

Copy link
Copy Markdown

Thanks for posting this as a PR. I was going to install your release, but I'll wait for this to be merged to prod.

@niels9001

Copy link
Copy Markdown
Collaborator

@weikequ we want to get this in for the next release. Would you mind resolving the remaining conflicts so that we can get this reviewed and merged in :)?

@weikequ

weikequ commented Dec 11, 2025

Copy link
Copy Markdown
Contributor Author

@weikequ we want to get this in for the next release. Would you mind resolving the remaining conflicts so that we can get this reviewed and merged in :)?

Awesome to hear. Just pushed a fix to resolve the merge conflicts. Let me know if there's anything else you need on my end. Thanks!

@lei9444

lei9444 commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Copilot AI 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.

Pull request overview

This PR adds a keyboard shortcut feature to toggle the Keyboard Manager module on and off, addressing issue #4879. The implementation follows the pattern used in the Color Picker module, with a default hotkey of Win+Shift+K.

Key changes:

  • Adds toggle hotkey infrastructure to Keyboard Manager with configurable shortcut
  • Extends KeyboardManagerViewModel to inherit from PageViewModelBase for hotkey support
  • Implements hotkey parsing and toggle functionality in the C++ module DLL

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs Refactors ViewModel to extend PageViewModelBase and implements GetAllHotkeySettings() method to expose the toggle shortcut configuration
src/settings-ui/Settings.UI/Strings/en-us/Resources.resw Adds localized strings for the toggle shortcut UI header and description
src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml Adds ShortcutControl UI element for configuring the toggle shortcut
src/settings-ui/Settings.UI/SerializationContext/SourceGenerationContextContext.cs Registers KeyboardManagerSettings for JSON serialization context
src/settings-ui/Settings.UI.Library/KeyboardManagerSettings.cs Implements GetAllHotkeyAccessors() method to provide access to the toggle shortcut setting
src/settings-ui/Settings.UI.Library/KeyboardManagerProperties.cs Adds ToggleShortcut property with default value (Win+Shift+K)
src/modules/keyboardmanager/dll/dllmain.cpp Implements hotkey parsing, storage, and toggle handler that enables/disables the module with toast notifications
src/modules/keyboardmanager/dll/KeyboardManager.vcxproj Adds project reference to the notifications library for toast support

Comment on lines +285 to +290
notifications::show_toast(L"Keyboard Manager Disabled", L"");
}
else
{
enable();
notifications::show_toast(L"Keyboard Manager Enabled", L"");

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

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

The notification strings "Keyboard Manager Disabled" and "Keyboard Manager Enabled" are hardcoded and not localized. These should use GET_RESOURCE_STRING with appropriate resource IDs defined in the Resources.resx file to support internationalization, similar to how app_name uses GET_RESOURCE_STRING(IDS_KEYBOARDMANAGER) on line 51.

Suggested change
notifications::show_toast(L"Keyboard Manager Disabled", L"");
}
else
{
enable();
notifications::show_toast(L"Keyboard Manager Enabled", L"");
notifications::show_toast(GET_RESOURCE_STRING(IDS_KEYBOARDMANAGER_DISABLED), L"");
}
else
{
enable();
notifications::show_toast(GET_RESOURCE_STRING(IDS_KEYBOARDMANAGER_ENABLED), L"");

Copilot uses AI. Check for mistakes.
Comment thread src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml Outdated
Comment thread src/modules/keyboardmanager/dll/dllmain.cpp
@lei9444

lei9444 commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@yeelam-gordon

Copy link
Copy Markdown
Contributor

@weikequ and @niels9001 , should we consider another existing pattern in PowerToys?
Like below screenshot.
image

  1. Disable the module in specific scenarios (e.g., GameMode).
  2. Disable the module for specific apps.
    This pattern is more feasible because it can be configured to disable the module in specific situations, rather than requiring people to remember to use a hotkey.

@lei9444

lei9444 commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

Hi @weikequ @niels9001,
directly toggling the whole module feels a bit odd.
Should we follow a similar approach to Mouse Utilities — use a shortcut to enable/disable the functionality, e.g. stop listening to keyboard events, instead of turning the entire module on and off?

@mike-mgt

mike-mgt commented Jan 6, 2026

Copy link
Copy Markdown

Hi @weikequ @niels9001, directly toggling the whole module feels a bit odd. Should we follow a similar approach to Mouse Utilities — use a shortcut to enable/disable the functionality, e.g. stop listening to keyboard events, instead of turning the entire module on and off?

Nope. The module itself is problematic when it is on in certain scenarios. If you're suggesting an additional setting, great, but this is a much-needed feature.

@mike-mgt

mike-mgt commented Jan 6, 2026

Copy link
Copy Markdown

@weikequ and @niels9001 , should we consider another existing pattern in PowerToys? Like below screenshot. image

  1. Disable the module in specific scenarios (e.g., GameMode).
  2. Disable the module for specific apps.
    This pattern is more feasible because it can be configured to disable the module in specific situations, rather than requiring people to remember to use a hotkey.

I do like this as an option, but I think it should also be added as an extra setting on top of the proposed one here by @weikequ.

@lei9444

lei9444 commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

Hi @weikequ @niels9001, directly toggling the whole module feels a bit odd. Should we follow a similar approach to Mouse Utilities — use a shortcut to enable/disable the functionality, e.g. stop listening to keyboard events, instead of turning the entire module on and off?

Nope. The module itself is problematic when it is on in certain scenarios. If you're suggesting an additional setting, great, but this is a much-needed feature.

Thanks @mike-mgt for the comments.
My suggestion is like this: the shortcut will activate (enable) and deactivate (disable) the module, but it will not change the module’s settings state shown in Settings.

So it behaves like this:
When the module is enabled in Settings, we can toggle the module active/inactive via the shortcut:
image

When the module is disabled in Settings, the shortcut does nothing:
image

This way, our implementation stays consistent with others.
Does this approach satisfy your requirements?

// Process the hotkey event
virtual bool on_hotkey(size_t /*hotkeyId*/) override
{
if (m_enabled)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We currently only use notifications to communicate updates and other 'critical' things as we know users don't like to get too many notifications.

Since enabling/disabling KMB is a deliberate action by the user, notifications seem excessive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When I was testing it, it was really helpful to know when the action was successful, hence the notification. Having the user press a hotkey and receive no feedback is unintuitive imo , as it makes them question if anything happened. I still prefer somehow letting the user know when it has succeeded, do you have any other thoughts on how we might be able to do it without using the notification system?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for sprinkling some good US @weikequ. Being notified of a successful activation is essential. I use SoundSwitch and I love seeing the notification that clearly states whether the input has switched or there's been an error.

@niels9001 niels9001 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Great work! See comment about notifications.

And to @lei9444 's comment; we should follow the activation behavior that other utilities are using so we are in line. This would also set us up for success on the longer term as we are planning a UI revamp of the KBM editor :)!

@weikequ

weikequ commented Jan 6, 2026

Copy link
Copy Markdown
Contributor Author
1. Disable the module in specific scenarios (e.g., GameMode).
2. Disable the module for specific apps.

I think it would be hard to capture all scenarios/apps where this would help the user, and using a specific keyboard press helps solidify user intent on performing this action. Though for my own purposes, this does work as well (maybe a blacklist to select from a list of processes?).

The other option is to have no shortcut by default, that way, it is opt-in only for those who need it.

@vanzue

vanzue commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Copilot AI 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.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Comment thread src/modules/keyboardmanager/dll/dllmain.cpp Outdated
<value>Toggle shortcut</value>
</data>
<data name="KeyboardManager_Toggle_Shortcut.Description" xml:space="preserve">
<value>Use a shortcut to toggle this module on or off (note that the Settings UI will not update)</value>

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

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

The description text mentions that "the Settings UI will not update" when the hotkey is pressed. This is a user-facing limitation that should ideally be addressed. Consider implementing a mechanism to notify the Settings UI of the state change, similar to how GeneralSettings.Enabled is updated in other toggle scenarios. This could involve sending an IPC message back to the Settings UI or implementing a polling/refresh mechanism.

Suggested change
<value>Use a shortcut to toggle this module on or off (note that the Settings UI will not update)</value>
<value>Use a shortcut to toggle this module on or off from anywhere</value>

Copilot uses AI. Check for mistakes.
Comment on lines +338 to +365
// Process the hotkey event
virtual bool on_hotkey(size_t /*hotkeyId*/) override
{
if (!m_enabled)
{
return false;
}

constexpr ULONGLONG hotkeyToggleDebounceMs = 500;
const auto now = GetTickCount64();
if (now - m_lastHotkeyToggleTime < hotkeyToggleDebounceMs)
{
return true;
}
m_lastHotkeyToggleTime = now;

refresh_process_state();
if (m_active)
{
stop_engine();
}
else
{
start_engine();
}

return true;
}

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

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

When toggling the engine via hotkey, no telemetry is sent, unlike the enable/disable methods which call Trace::EnableKeyboardManager. Consider whether telemetry should be tracked for hotkey toggles to understand user behavior, or document why it's intentionally omitted (e.g., to avoid spam from frequent toggling).

Copilot uses AI. Check for mistakes.
Comment on lines +190 to +202
public HotkeySettings ToggleShortcut
{
get => Settings.Properties.ToggleShortcut;
set
{
if (Settings.Properties.ToggleShortcut != value)
{
Settings.Properties.ToggleShortcut = value ?? Settings.Properties.DefaultToggleShortcut;
OnPropertyChanged(nameof(ToggleShortcut));
NotifySettingsChanged();
}
}
}

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

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

Consider adding unit tests for the new toggle shortcut functionality, similar to the tests in ViewModelTests/ColorPicker.cs that verify the ActivationShortcut property. Tests should verify that the ToggleShortcut property is correctly initialized, persisted, and updated. This aligns with the PR checklist item for tests that is currently unchecked.

Copilot uses AI. Check for mistakes.
vanzue and others added 2 commits February 11, 2026 23:15
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@vanzue

vanzue commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@vanzue

vanzue commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Addressed the comments:

  1. Hotkey toggle will not enable disable the entire module, use a slightly light weighted approach to start the engine/kill the engine process
  2. Removed the notification

@vanzue vanzue requested a review from niels9001 February 11, 2026 16:17
@niels9001 niels9001 merged commit f88a490 into microsoft:main Feb 12, 2026
11 checks passed
@zateutsch zateutsch added this to the PowerToys 0.98 milestone Mar 4, 2026
@zateutsch zateutsch added the Product-Keyboard Shortcut Manager Issues regarding Keyboard Shortcut Manager label Mar 5, 2026
@jefflord

Copy link
Copy Markdown
Contributor

Wow, so long over due and it's brilliant.

Couple if nits:

  • Tab Order: The tab order is inconsistent. When a shortcut has focus, pressing Tab again focuses on nothing (likely hidden elements) rather than moving to the next visible control.
  • Menu Options: The "..." (meatballs) menu should include an "Edit" option.
  • Broken Icon: The "folder-with-arrow" icon currently has no associated action.
  • Chord Regressions: Double-key chords (e.g., CTRL+6, 6) no longer work. The UI prevents the second part of the chord from being entered (see Image 1)
  • Chord Timing: The timeout for entering the second character of a chord is far too short. Unlike standard chord entries that often have no strict "allotted time," this screen resets too quickly. If a timeout is necessary, please add a hint when "Allow chords" is checked: "Enter the second part of the chord within 1 second, or the input will reset."
  • UI Guidance: There should be a label below the shortcut display saying: "Click or focus here to enter a shortcut."
  • Keyboard Accessibility: "Esc" should not be a valid shortcut key. Instead, pressing "Esc" should blur the input and disable shortcut entry. Currently, it's impossible to navigate or configure the shortcut settings using only the keyboard.
  • Dropdown Redundancy: Why is "Trigger" a dropdown menu if it only contains one option?

Image 1: Double same number chords
image

Again I will say, OMG this is great. I have personally waited for this for a long time.

@weikequ

weikequ commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Not too sure what happened between my changes and what was merged, but I'm using the .98 release and the keyboard manager gets randomly disabled (through the shortcut, the UI is still showing it's on) when I run certain apps. Not too sure what the cause is though. Will update if I find more information.

@mike-mgt

mike-mgt commented Apr 2, 2026

Copy link
Copy Markdown

Just curious @weikequ, did your original contribution support UI syncing? I noticed the comment in the changelog saying that the UI would not reflect the toggling via keyboard shortcut. I also noticed some extra commits and conversations regarding changing the behaviour of the trigger to be more in line with other toggles. Not sure what happened there, but I'm noticing issues as well. I am staying in .98.0 to avoid the feature removal.

Not too sure what happened between my changes and what was merged, but I'm using the .98 release and the keyboard manager gets randomly disabled (through the shortcut, the UI is still showing it's on) when I run certain apps. Not too sure what the cause is though. Will update if I find more information.

@weikequ

weikequ commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Just curious @weikequ, did your original contribution support UI syncing? I noticed the comment in the changelog saying that the UI would not reflect the toggling via keyboard shortcut. I also noticed some extra commits and conversations regarding changing the behaviour of the trigger to be more in line with other toggles. Not sure what happened there, but I'm noticing issues as well. I am staying in .98.0 to avoid the feature removal.

I asked about the UI issues when I first created the PR but it seemed like no-one had any ideas, so no, it was never implemented. The extra commits I have no idea, sorry. If you can add the issues you're having here and steps to reproduce it, I can try to take a look at it along with my issues

@mike-mgt

mike-mgt commented May 6, 2026

Copy link
Copy Markdown

Hi @weikequ just wondering if you know anything about the feature. It seems like it's been removed without any reporting of bringing it back. I saw this issue and related PR #46821 #46530 but no sign of it coming back. I do see more changes made to the overall module. I'd love to sideload your changes, if you were to create a new PR that includes the April 29 improvements (there's some good stuff there https://github.com/microsoft/PowerToys/releases/tag/v0.99.1). Cheers!

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

Labels

In for .98 Product-Keyboard Shortcut Manager Issues regarding Keyboard Shortcut Manager

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[KBM] Add a hotkey key to turn it on/off

9 participants