A robust, gaming-compatible key remapping tool for Windows 11 (also works on Windows 10).
Version 2.3 | Built by Li Fan, 2025
π₯ Download: Grab KeyRemapper.exe from the
latest release β a single file, no
Python needed. Windows will show a SmartScreen warning the first time β
here's why, and what to click.
Runs as a normal user. Administrator rights are only needed if you want it to affect windows that themselves run elevated (some games, Task Manager, etc.).
Created out of frustration at being unable to disable or remap keys within a particular game.
- Scrollbars only appear when there is something to scroll β every panel hides its scrollbar while the content fits
- Reset everything to defaults β one button in Settings clears all rules, the Copilot action and every setting, and removes the logon entry
- Nothing is blocked out of the box. A stale development config meant
/could arrive pre-blocked; a fresh install now starts completely empty - Rewritten Help/About β leads with what the app does, with the project link and a β Donate button at the end
- Give the Copilot key back its old job: one click turns it into Right Alt, Windows, Menu β€ or Right Ctrl β whichever key your laptop sacrificed for it
- Per-app profiles: scope any mapping or block to a single executable, so
F1can mean one thing in your game and nothing anywhere else - Tap vs hold (dual-role keys): CapsLock can send Escape when tapped and act as Ctrl when held
- Pause hotkey: suspend every mapping without stopping the remapper, from a hotkey or the tray
- Mouse side buttons (
mouse3/mouse4/mouse5) usable as sources - Run at logon and start hidden in the tray, with a new Settings tab
- Edit mappings in place (double-click a row) with conflict warnings before you overwrite
- π― Detect now uses the low-level hook, so Win, F13-F24 and Copilot combinations are detectable instead of "type it manually"
- 58 unit tests covering the rule engine, including the Copilot chord and the mouse hook
- Copilot Key tab: detect what your laptop's Copilot key actually sends, then disable it, send different keys, or launch any program, file or website β see Copilot Key
- Modifier combinations now work:
ctrl+/shift+/alt+/win+combos are matched by modifier family, so the left/right key the hardware reports no longer matters. (Previously any combination involving a modifier silently never fired.) - Config and log moved to
%APPDATA%\KeyRemapper\so settings survive updates and work from a one-file.exe. An existingkey_remap_config.jsonnext to the app is migrated once. - Hook runs on its own thread: a busy or blocked UI can no longer stall your keyboard, and the text-mode menu works properly.
- Media & browser keys available as remap targets (
playpause,mute,calculator, β¦). - Real logging again β every action goes to
%APPDATA%\KeyRemapper\key_remapper.log.
- Extended Function Keys (F13-F24): Full support for extended function keys including F13-F24
- Interactive Key Detection: π― Detect buttons to capture key presses in real-time
- Auto-Save: All changes are automatically saved - no need to manually save config
- Improved Key Capture: Better handling of modifier keys and combinations
- Modern GUI: Clean, dark-themed interface built with customtkinter
- Gaming Compatible: Uses low-level Windows hooks (
SetWindowsHookEx) that work with most games and applications - Key Combinations: Remap single keys to key combinations (e.g.,
F1βCtrl+S,F2βCtrl+Shift+S) - Key Blocking: Completely disable specific keys to prevent accidental presses during gaming (e.g., block
/key) - Copilot Key Control: Detect and repurpose the dedicated Copilot key found on 2024+ laptops
- Per-App Profiles: Limit any rule to a single executable
- Dual-Role Keys: One key that taps one thing and holds another
- Pause Hotkey: Suspend everything without stopping the remapper
- Mouse Side Buttons:
mouse3/mouse4/mouse5as remap sources - Interactive Key Detection: Click π― Detect buttons to capture key presses automatically
- System Tray: Minimize to system tray while remapper runs in the background
- Standalone Executable: Build a single
.exefile - no Python installation required - Auto-Save Configuration: Changes are saved automatically to JSON file
- Toggle Mappings: Enable/disable individual mappings or blocked keys without removing them
- Logging: All actions logged to
%APPDATA%\KeyRemapper\key_remapper.logfor troubleshooting
- Windows 10 or Windows 11
- Python 3.8 or higher
- Windows 10 or Windows 11
Administrator privileges are optional. Elevate only if you need the remapper to reach windows that run elevated themselves.
- Download
KeyRemapper.exefrom the latest release - Double-click it. See the SmartScreen note below for the first-run warning.
- Clone or download this repository
- Install dependencies:
pip install -r requirements.txt - Run the GUI:
python key_remapper_gui.py
- Install dependencies:
pip install -r requirements.txt - Run the build script:
python build.py
- Find the executable at
dist/KeyRemapper.exe - Double-click to run
The first time you run the downloaded .exe, Windows shows a blue box:
Windows protected your PC Microsoft Defender SmartScreen prevented an unrecognised app from starting.
To run it anyway: click "More info", then "Run anyway".
The executable is not code-signed. A signing certificate costs money per year, and this is a free hobby project. SmartScreen flags every unsigned executable that it hasn't seen downloaded many times before β it is a statement about the certificate and download count, not about whether anything is wrong with the file. The warning fades for everyone as more people download a given release.
Some browsers also block the download itself for the same reason. In Edge or Chrome, choose Keep β Keep anyway in the downloads bar.
Fair. You have three options, in order of paranoia:
-
Verify the checksum β confirm your download is byte-for-byte the file published here:
Get-FileHash .\KeyRemapper.exe -Algorithm SHA256
Release SHA-256 v2.3.0 883f407b5b61655076cc8e57d2bb50c1d2f74ba9e837bf16b2dfc09e34e4eff9v2.2.0 44e158dd07c9a9b9d6c1ca109fbe19b2d546778de95515fb5bf35c52805b48a0This proves the file wasn't tampered with in transit. It does not prove the code is trustworthy β for that, see below.
-
Read the source β it's all in this repository, about 2,000 lines of Python, and the
.exeis justbuild.pyrunning PyInstaller over it. -
Build it yourself β Option 3 above. Then no download, no warning, no trust required.
A key remapper is, by construction, indistinguishable from a keylogger to a scanner: it installs
a global WH_KEYBOARD_LL hook and therefore sees every keystroke you type. That is the whole
mechanism β there is no way to remap keys without it. So here is exactly what it does with them:
- Your typing is never recorded. Keystrokes are matched against your rules in memory and
then forgotten. There is no logging in the key-handling path
(
_handle_key_event) apart from an error handler. - One exception, and it's one you trigger: when you press π― Detect, the key code you
deliberately capture is written to the log so the feature can be debugged β e.g.
Chord captured: ('shift', 'win') + 0x86. Nothing else you type ever reaches the log. - The log otherwise records actions only β "added mapping", "remapper started" β plus the rules you configure, which you wrote yourself.
- No network connections. No telemetry, no update check, no sockets anywhere in the source. The only outbound action is opening a URL or launching a program you assigned to the Copilot key, which hands off to your normal browser or shell.
- It writes to two places:
%APPDATA%\KeyRemapper\(config + log), and β only if you tick "Launch when I sign in" β oneKeyRemappervalue underHKCU\Software\Microsoft\Windows\CurrentVersion\Run. Unticking it removes the value.
Every one of these is checkable in key_remapper.py; grep for logger.,
winreg, and webbrowser and you'll find the lot.
python key_remapper_gui.pyIf a specific game ignores your remaps, that game is probably running elevated β start the remapper as administrator in that case.
The Copilot key on modern Windows laptops is not a new scan code. The keyboard firmware
emits a hidden chord β on virtually every OEM that chord is Left Shift + Left Win + F23.
That is why simply "blocking F23" does nothing useful, and why releasing the key can pop the
Start menu.
Open the Copilot Key tab and:
| Step | What it does |
|---|---|
| π― Detect | Swallows all input until you press the Copilot key, then records the exact chord your machine sends (handles the rare win+c / bare-F23 keyboards) |
| Do nothing | Kills the key entirely, including the Start-menu side effect |
| Send other key(s) | Turn it into any key or combination β ctrl+shift+p, playpause, f13, β¦ |
| Launch a program or file | Point it at an .exe, document, folder or shell command |
| Open a website | Any URL, opened in your default browser |
| Pass through | Leave the key alone |
Most laptops made room for the Copilot key by dropping a key you were already using. One click puts it back:
| Button | Result |
|---|---|
| Right Alt | The Copilot key behaves as ralt (AltGr on international layouts) |
| Windows | Acts as a Windows key |
| Menu β€ | The context-menu key that most Copilot keyboards replaced |
| Right Ctrl | Acts as rctrl |
Modifier targets are held for as long as the firmware holds the chord, so Copilot+another key
works on keyboards that keep the chord down. Most send a single burst, which lands as a tap β
exactly what you want for Menu and Windows.
Other quick presets: Disable it, Screenshot (win+shift+s), Play/Pause, File Explorer.
Apply saves immediately; the remapper must be started (βΆ Start) for the key to take effect.
Windows 11 24H2 can also remap this key from Settings, but only to signed, MSIX-packaged apps. This tab works with anything on your machine.
Under the hood, when the chord fires the remapper injects an unassigned virtual key so that
releasing the still-held Windows key does not open the Start menu, virtually releases the
held modifiers, and only then performs your action β so Shift/Win never leak into the
keys it sends.
Leave Only in this app empty and a rule applies everywhere. Fill in an executable name
(game.exe β a full path is fine, it gets reduced to the file name) and the rule only fires
while that window has focus. An app-specific rule beats a global one for the same key, so you
can have a global default and a per-game override.
The foreground executable is only looked up when at least one app-scoped rule exists, and the answer is cached briefly β the hook stays fast.
Fill in When held instead and a key gets two jobs:
| Source | Target | When held | Result |
|---|---|---|---|
capslock |
escape |
ctrl |
Tap for Escape, hold for Ctrl β the classic Vim setup |
space |
space |
shift |
Space bar doubles as Shift |
The hold role activates as soon as you press another key while holding it, or after the tap vs hold threshold (Settings tab, 250 ms by default). Hold roles need a single source key, not a combination.
Set one in the Settings tab (e.g. ctrl+alt+f12) to suspend every mapping without
releasing the hook β useful when a remap is fighting with an app. The status turns amber, the
tray icon turns orange, and anything currently held down is released rather than left stuck.
The tray menu has Pause / Resume too.
mouse3 (middle), mouse4 and mouse5 (the side buttons) can be used as sources for
mappings and blocks β e.g. mouse4 β ctrl+c. Left and right click are deliberately not
remappable, and mouse buttons cannot be a target. The mouse hook is only installed when a
rule actually needs it.
Key Mappings:
- Add mapping - Create a new key remap
- Remove mapping - Delete an existing remap
- List mappings - View all configured remaps
- Toggle mapping - Enable/disable a mapping
Block Keys (Gaming): 5. Block a key - Completely disable a key (useful for gaming) 6. Unblock a key - Re-enable a blocked key 7. List blocked keys - View all blocked keys 8. Toggle blocked key - Enable/disable a key block
Copilot Key: 9. Configure the Copilot key - Detect it and choose what it should do
Control:
- S - Start remapper (activate all mappings and blocks)
- X - Stop remapper (deactivate all)
- P - Pause/resume without releasing the hook
- W - Save configuration to
key_remap_config.json - L - Load configuration from config file
- K - Show available keys
- 0 - Exit
Keys can be specified as:
- Single keys:
a,f1,escape,space - Combinations:
ctrl+a,shift+f1,ctrl+shift+escape,win+shift+f23
π‘ Tip: Use the π― Detect buttons in the GUI to automatically capture key presses!
| Category | Keys |
|---|---|
| Letters | a - z |
| Numbers | 0 - 9 |
| Function | f1 - f12 |
| Extended Function | f13 - f24 (includes Copilot key: win+shift+f23) |
| Modifiers | ctrl, lctrl, rctrl, shift, lshift, rshift, alt, lalt, ralt, win, lwin, rwin |
| Navigation | up, down, left, right, home, end, pageup, pagedown |
| Special | escape, tab, capslock, space, enter, backspace, delete, insert, apps |
| Numpad | num0 - num9, numplus, numminus, nummultiply, numdivide |
| Media | playpause, nexttrack, prevtrack, mediastop, mute, volumeup, volumedown, calculator, mail |
| Browser | browserback, browserforward, browserrefresh, browserhome, browsersearch |
| Mouse (source only) | mouse3 / middleclick, mouse4, mouse5 |
| Punctuation | semicolon, comma, period, slash, backslash, quote, grave, lbracket, rbracket |
Modifiers are matched by family: a mapping written as ctrl+a fires for either Ctrl key.
Left/right distinctions still work when the modifier is the key being remapped (e.g. ralt β ctrl).
| Source | Target | Description |
|---|---|---|
capslock |
escape |
Caps Lock acts as Escape (popular for Vim users) |
ctrl+j |
down |
Ctrl+J acts as Down arrow |
f1 |
ctrl+s |
F1 saves the document |
ralt |
ctrl |
Right Alt acts as Control |
| Key | Use Case |
|---|---|
/ |
Prevent accidentally opening chat in games |
win |
Prevent Windows key from minimizing your game |
alt+tab |
Prevent accidental window switching |
escape |
Prevent accidental pause menu in some games |
win+shift+f23 |
The raw Copilot chord β prefer the Copilot Key tab, which also suppresses the Start menu |
Everything is saved to %APPDATA%\KeyRemapper\key_remap_config.json:
{
"version": 4,
"mappings": [
{
"source": "CAPSLOCK",
"target": "ESCAPE",
"hold": "CTRL",
"app": "",
"enabled": true,
"description": "Caps Lock to Escape"
}
],
"blocked_keys": [
{
"key": "/",
"app": "game.exe",
"enabled": true,
"description": "Block slash key during gaming"
}
],
"copilot": {
"enabled": true,
"modifiers": ["shift", "win"],
"key": "f23",
"mode": "keys",
"value": "ralt",
"description": "Copilot key"
},
"settings": {
"toggle_hotkey": "ctrl+alt+f12",
"tap_timeout_ms": 250,
"run_at_startup": false,
"start_minimized": false,
"start_on_launch": false
}
}Copilot mode is one of disable, keys, launch, url or passthrough. Older config
files load unchanged β missing sections fall back to defaults.
python -m unittest discover -s tests58 tests drive the rule engine directly (no real hooks, no keyboard input needed), covering remaps, blocks, per-app scoping, dual-role keys, the pause hotkey, the Copilot chord, the mouse hook and config round-tripping.
Click More info β Run anyway. The executable is not code-signed, so SmartScreen flags it β see Windows SmartScreen warning for why, how to verify the download's checksum, and how to build it yourself instead.
Expect the occasional false positive: the app installs a global keyboard hook, which is the same API a keylogger uses, and PyInstaller one-file executables are themselves a common heuristic trigger. The SmartScreen section documents exactly what the app does with your keystrokes and where it writes. Building from source avoids the packed-executable heuristic entirely.
- If the game runs elevated, run the remapper as administrator too
- Some anti-cheat systems block keyboard hooks - this is by design for security
- Check that the remapper status shows "ACTIVE"
- Verify your mapping is enabled (not disabled)
- Check
%APPDATA%\KeyRemapper\key_remapper.logfor error messages
- Use π― Detect on the Copilot Key tab β your keyboard may send a different chord
- Make sure the remapper is started, and that the tab does not say "pass through"
- Check
%APPDATA%\KeyRemapper\key_remapper.logfor error details - Ensure you're using Python 3.8 or higher
- Make sure you're on Windows (not Linux/Mac)
- Uses
SetWindowsHookExwithWH_KEYBOARD_LLfor low-level keyboard interception - The hook is installed and pumped on a dedicated thread, so UI work can never stall input
- Injects replacement keys using
SendInputAPI - Marks injected events (
dwExtraInfo) to prevent infinite loops - Combinations are matched as (modifier families, main key) signatures
- Slow actions (launching apps, opening URLs) run on a worker thread β a low-level hook that
takes longer than
LowLevelHooksTimeoutis silently removed by Windows - Thread-safe design with proper locking
- Windows only (uses Windows-specific APIs)
- Some games with kernel-level anti-cheat may not work
- Cannot remap mouse buttons (keyboard only)
- Cannot remap keys used by Windows itself (e.g., Ctrl+Alt+Del)
Built by Li Fan, 2025. If Key Remapper saved you some frustration, you're very welcome to buy me a coffee β β there's also a Donate button in the app's βΉοΈ About dialog.
Bug reports and feature requests are welcome on the issue tracker.
MIT License - Feel free to use and modify as needed.