Using a PC keyboard with a Macintosh - key mapping

Yes, you can do some of this through the OS X / macOS built-in Control Panel (Keyboard -> Modifier Keys... and swap the Command and Option keys), but that doesn’t address the Windows keyboard “menu” key or things like media keys. For that we need to remap the keys using Karabiner (13.x for Catalina or Big Sur; 12.x for Sierra through Catalina; 11.x for El Capitan, 10.x for Mavericks through El Capitan; if you’re still using a “cat” operating system, you might be SOL).

I’m preparing for a “build” of a full-size Glorious Modular Mechanical Keyboard (GMMK) I’m going to swap to Kailh Box Pale Blue switches (though I was tempted by the speed with which I could get Kailh Box Jade switches; I like them well enough in another keyboard I’m using them in). (I don’t really consider swapping one hot switch for another “building” a keyboard; I wish I had the time and wallet to dive as deep into this stuff as the folks who’ve built some of the amazing creations I’ve lusted after on r/MechanicalKeyboards.)

As far as I’m aware, the GMMK (as opposed to the recently announced GMMK Pro) does not support QMK/VIA for remapping keys in the keyboard itself (article). Hence this exploration.

I did a trial run with a Razer BlackWidow Tournament Stealth Edition keyboard I had handy, which looks like this:

Compare with the Keychron K8 I usually use with this workstation, which ships with a “Mac” layout:


Launching Karabiner-Elements (v12.10.0), it seems I can easily map most of these the way I want them, but the “menu” key, although an option in the interface, doesn’t work:


Running the Karabiner Event Viewer (installed alongside Karabiner-Elements), I see that this key is being registered as the “application” key:


Selecting “application” instead of “menu” solved it.

(If you want do do an even deeper dive into what your keyboard is doing, check out Key Codes (versions supporting operating systems as far back as Leopard, 10.5).

Edit: There is apparently a way to do something similar with Apple’s own utilities (hdiutil, made persistent with launchd); I’ll explore that soon.

Alternate Method

Using hdiutil to remap keys

This way uses “native” software provided by Apple in the base operating system, and should work on any Mac operating system from Sierra on.

Technical Note TN2450 walks through the details, and excerpts the key codes from the USB HID Usage Tables document, version 1.12 (starting on page 52). (The USB Group document also lists all the codes for the media keys, etc., which Apple did not excerpt into the Technical Note.)

Repeating the example above, I’m going to map:
  • Keyboard LeftAlt (0xE2) to Keyboard Left GUI (a/k/a the Command ⌘ key) (0xE3)
  • Keyboard Keyboard Left GUI (0xE3) to LeftAlt (0xE2)
  • Keyboard RightAlt (0xE6) to Keyboard Right GUI (0xE7)
  • Keyboard Application key (0x65) to Keyboard Right Alt (0xE6)
(I don’t see an easy way to map the Fn key - it can sometimes be done in the control panel, but I’d love to keep all the tweaks in one place, and I haven’t yet found a way to do that here.)

This is done by passing a JSON structure to hdiutil, with the keys you want to map and the values to map them to, like so (this is a simple shell script, it’s cleaner and easier to read than cramming it all onto the command line):

#!/usr/bin/env bash

  

hidutil property --set '{                                               

        "UserKeyMapping":[                                              

                {                                                       

                        "HIDKeyboardModifierMappingSrc":0x7000000E2,    

                        "HIDKeyboardModifierMappingDst":0x7000000E3     

                },                                                      

                {                                                       

                        "HIDKeyboardModifierMappingSrc":0x7000000E3,    

                        "HIDKeyboardModifierMappingDst":0x7000000E2     

                },                                                      

                {                                                       

                        "HIDKeyboardModifierMappingSrc":0x7000000E6,    

                        "HIDKeyboardModifierMappingDst":0x7000000E7     

                },                                                      

                {                                                       

                        "HIDKeyboardModifierMappingSrc":0x700000065,    

                        "HIDKeyboardModifierMappingDst":0x7000000E6     

                }                                                       

        ]                                                               

}'

Make persistent with LaunchAgent

To set these values permanently across reboots, build a LaunchAgent plist file and place it in, e.g., ~/Library/LaunchAgents/com.blogspot.flying-geek.keymap.plist:

<?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.local.KeyRemapping</string>

    <key>ProgramArguments</key>

    <array>

        <string>/usr/bin/hidutil</string>

        <string>property</string>

        <string>--set</string>

        <string>{"UserKeyMapping":[

                {

                        "HIDKeyboardModifierMappingSrc":0x7000000E2,

                        "HIDKeyboardModifierMappingDst":0x7000000E3

                },                             

                {                    

                        "HIDKeyboardModifierMappingSrc":0x7000000E3,

                        "HIDKeyboardModifierMappingDst":0x7000000E2

                },

                {

                        "HIDKeyboardModifierMappingSrc":0x7000000E6,

                        "HIDKeyboardModifierMappingDst":0x7000000E7

                },               

                {     

                        "HIDKeyboardModifierMappingSrc":0x700000065,

                        "HIDKeyboardModifierMappingDst":0x7000000E6

                }                                      

        ]}</string>

    </array>

    <key>RunAtLoad</key>

    <true/>

</dict>

</plist>

Notes:

  1. I’m not aware at this time of any way to make the mapping specific to a particular keyboard; remapped keys will be remapped no matter which keyboard you’re using (i.e., the built-in keyboard on a MacBook or the external Wintel board you’ve hooked up). So you’ll have just swapped Cmd and Option on the built in keyboard. You can alias an “unmap” command (see note 2 below), or just go into the Keyboard control panel’s Modifier Keys screen and swap them back for the internal keyboard. (Though admittedly that’s all kind of a kludge...)
  2. If you really bork things, you can wipe out all the remapping you’ve done by running this command in the terminal: hidutil property --set '{"UserKeyMapping":[]}'
  3. You can check the state of any keymaps (e.g., after a reboot, to see if the LaunchAgent setup above worked) using the following command (void or a set of empty parantheses () indicates no keys are remapped): hidutil property --get "UserKeyMapping"

Comments