Skip to content

Instantly share code, notes, and snippets.

@bennlee
Created November 19, 2021 05:39
Show Gist options
  • Save bennlee/0f5bc8dc15a53b2cc1c81cd92363bf18 to your computer and use it in GitHub Desktop.
Save bennlee/0f5bc8dc15a53b2cc1c81cd92363bf18 to your computer and use it in GitHub Desktop.
How to remapping keys on macOS without thirdparty applications.

How to remapping keys on macOS without thirdparty applications.

You could remapping keys via the macOS embedded command line tool hidutil.


Key IDs Table
Usage Usage ID (hex) Usage Usage ID (hex) Usage Usage ID (hex) Usage Usage ID (hex)
Keyboard a and A 0x700000004 Keyboard 5 and % 0x700000022 Keyboard F7 0x700000040 Keypad 6 and Right Arrow 0x70000005E
Keyboard b and B 0x700000005 Keyboard 6 and ^ 0x700000023 Keyboard F8 0x700000041 Keypad 7 and Home 0x70000005F
Keyboard c and C 0x700000006 Keyboard 7 and & 0x700000024 Keyboard F9 0x700000042 Keypad 8 and Up Arrow 0x700000060
Keyboard d and D 0x700000007 Keyboard 8 and * 0x700000025 Keyboard F10 0x700000043 Keypad 9 and Page Up 0x700000061
Keyboard e and E 0x700000008 Keyboard 9 and ( 0x700000026 Keyboard F11 0x700000044 Keypad 0 and Insert 0x700000062
Keyboard f and F 0x700000009 Keyboard 0 and ) 0x700000027 Keyboard F12 0x700000045 Keypad . and Delete 0x700000063
Keyboard g and G 0x70000000A Keyboard Return (Enter) 0x700000028 Keyboard Print Screen 0x700000046 Keyboard Non-US \ and | 0x700000064
Keyboard h and H 0x70000000B Keyboard Escape 0x700000029 Keyboard Scroll Lock 0x700000047 Keyboard Application 0x700000065
Keyboard i and I 0x70000000C Keyboard Delete (Backspace) 0x70000002A Keyboard Pause 0x700000048 Keyboard Power 0x700000066
Keyboard j and J 0x70000000D Keyboard Tab 0x70000002B Keyboard Insert 0x700000049 Keypad = 0x700000067
Keyboard k and K 0x70000000E Keyboard Spacebar 0x70000002C Keyboard Home 0x70000004A Keyboard F13 0x700000068
Keyboard l and L 0x70000000F Keyboard - and _ 0x70000002D Keyboard Page Up 0x70000004B Keyboard F14 0x700000069
Keyboard m and M 0x700000010 Keyboard = and + 0x70000002E Keyboard Delete Forward 0x70000004C Keyboard F15 0x70000006A
Keyboard n and N 0x700000011 Keyboard [ and { 0x70000002F Keyboard End 0x70000004D Keyboard F16 0x70000006B
Keyboard o and O 0x700000012 Keyboard ] and } 0x700000030 Keyboard Page Down 0x70000004E Keyboard F17 0x70000006C
Keyboard p and P 0x700000013 Keyboard \ and | 0x700000031 Keyboard Right Arrow 0x70000004F Keyboard F18 0x70000006D
Keyboard q and Q 0x700000014 Keyboard Non-US # and ~ 0x700000032 Keyboard Left Arrow 0x700000050 Keyboard F19 0x70000006E
Keyboard r and R 0x700000015 Keyboard ; and : 0x700000033 Keyboard Down Arrow 0x700000051 Keyboard F20 0x70000006F
Keyboard s and S 0x700000016 Keyboard ' and " 0x700000034 Keyboard Up Arrow 0x700000052 Keyboard F21 0x700000070
Keyboard t and T 0x700000017 Keyboard Grave Accent and Tilde 0x700000035 Keypad Num Lock and Clear 0x700000053 Keyboard F22 0x700000071
Keyboard u and U 0x700000018 Keyboard , and "<" 0x700000036 Keypad / 0x700000054 Keyboard F23 0x700000072
Keyboard v and V 0x700000019 Keyboard . and ">" 0x700000037 Keypad * 0x700000055 Keyboard F24 0x700000073
Keyboard w and W 0x70000001A Keyboard / and ? 0x700000038 Keypad - 0x700000056 Keyboard Left Control 0x7000000E0
Keyboard x and X 0x70000001B Keyboard Caps Lock 0x700000039 Keypad + 0x700000057 Keyboard Left Shift 0x7000000E1
Keyboard y and Y 0x70000001C Keyboard F1 0x70000003A Keypad Enter 0x700000058 Keyboard Left Alt 0x7000000E2
Keyboard z and Z 0x70000001D Keyboard F2 0x70000003B Keypad 1 and End 0x700000059 Keyboard Left GUI 0x7000000E3
Keyboard 1 and ! 0x70000001E Keyboard F3 0x70000003C Keypad 2 and Down Arrow 0x70000005A Keyboard Right Control 0x7000000E4
Keyboard 2 and @ 0x70000001F Keyboard F4 0x70000003D Keypad 3 and Page Down 0x70000005B Keyboard Right Shift 0x7000000E5
Keyboard 3 and # 0x700000020 Keyboard F5 0x70000003E Keypad 4 and Left Arrow 0x70000005C Keyboard Right Alt 0x7000000E6
Keyboard 4 and $ 0x700000021 Keyboard F6 0x70000003F Keypad 5 0x70000005D Keyboard Right GUI 0x7000000E7

Remapping keys

If you want to remap the key 'CapsLock(0x700000039)' to 'F18(0x70000006D)'. type below in terminal

$ hidutil property --set '{"UserKeyMapping":[
  {
    "HIDKeyboardModifierMappingSrc": 0x700000039, # source key
    "HIDKeyboardModifierMappingDst": 0x70000006D  # destination key
  }
]}'

Checking remapped keys

$ hidutil property --get "UserKeyMapping"
# If there is no remapped key, you will receive (null).

How to persist remapping keys

Above way will be undone whenever you reboot your Mac, so one way to persist the remapping is to run the hidutil command every time your Mac boots. For that, we can rely on Launch Agents.

Create a file named ~/Library/LaunchAgents/com.example.KeyRemapping.plist, that makes macOS run the hidutil tool every time it starts up.

<!--
  Put this file in ~/Library/LaunchAgents/com.example.KeyRemapping.plist to
  automatically remap your keys when macOS starts.
-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.KeyRemapping</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/hidutil</string>
        <string>property</string>
        <string>--set</string>
        <string>{"UserKeyMapping":[
          {
            "HIDKeyboardModifierMappingSrc": 0x700000039,
            "HIDKeyboardModifierMappingDst": 0x70000006D
          }
        ]}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

References

@igor-makarov
Copy link

@tv21 same here! Let me know if you figure out what causes it.

@bennlee
Copy link
Author

bennlee commented Jan 29, 2024

@tv21 @igor-makarov
Oh, I think there's a bug in those versions. I've found similar reports on apple. 🥲
It might be fixed with the Sonoma 14.3 update.

@alienator88
Copy link

On newer versions of macOS(I think Sonoma and up) you have to use sudo with the hidutil command.
To persist across reboots, I had to do the following before it started working correctly:

  1. Put the plist file in /Library/LaunchDaemons instead of ~/Library/LaunchAgents
  2. Give the plist correct permissions and ownership:
sudo chown root:wheel /Library/LaunchDaemons/com.alienator88.capsLock.plist
sudo chmod 644 /Library/LaunchDaemons/com.alienator88.capsLock.plist
  1. Start the daemon:
    sudo launchctl bootstrap system /Library/LaunchDaemons/com.alienator88.capsLock.plist
  2. Reboot to test

@juliocastrodev
Copy link

@alienator88 thanks a lot! It worked :)

@MatthewWilliams46
Copy link

Does anybody know how I could remap a key to a key combination using a similar system or better open an application

@igor-makarov
Copy link

Note for those who moved to macOS Sierra: You may need to add hidutil to the list of allowed apps under System Settings > Privacy & Security > Input Monitoring.

@LuckyDuke23
Copy link

Just in case somebody cares....I have written a script with the help of https://hidutil-generator.netlify.app and then put this script into an automator app which runs on start up. By this I can use a wired USB Windows keyboard on my iMac in a same comfortable way like I did with the original Apple keyboard earlier.

@PickupMode
Copy link

PickupMode commented Jan 18, 2025

Thanks for this page, I won't use Karabiner (external tools, allows rights ...)

Works on Mini M4 Sequoia 15.2 with this :

  1. Create the .plist file desired and put into /Library/LaunchDaemons/
  2. Use your command in this order
    2a. sudo chown root:wheel /Library/LaunchDaemons/com.KeyRemapping.plist
    2b. sudo chmod 644 /Library/LaunchDaemons/com.KeyRemapping.plist
    2c. sudo launchctl bootstrap system /Library/LaunchDaemons/com.KeyRemapping.plist
  3. Check it's work hidutil property --get "UserKeyMapping"

I've map cause using Logitech mxkeys and I replace right FN/OPTION by OPTION/CTRL (like vanilla apple keyboard)

EDIT : map FN key don't work, even in System setting > Keyboard > Keyboard shortcut > Modification keys !

@alienator88
Copy link

For anyone that doesn't want to do all this manually anymore, I built a native swift app for remapping all the keys. Clicking Save will save the changes for the current session and also save/update the plist file as a launch daemon.
It needs accessibility permission to perform hidutil changes on the fly via the IOKit.hid API.
It will also ask to install a helper tool on launch so it can perform the launch daemon changes without asking for password every single time.

image
image
https://github.com/alienator88/PearHID
It's the first version/beta right now, so might have a bug or two, but would love it if anybody is willing to test it out.

@th0r
Copy link

th0r commented Apr 24, 2025

@alienator88 thats a lot for this tool, man! Really appreciate my saved time!

@alienator88
Copy link

You're welcome! Thanks for testing it out :)

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