Posted on

During my transition to the US ANSI keyboard layout, one of my main frustrations with pretty much every MacBook was the INT(ISO) keyboard layout (it's hard to come by MacBooks with US ANSI keyboards here in the Western edge of Europe).

The problem with these layouts is that even if you select the US ANSI layout in the operating system, the first key of the second row of keys, the one right before the number one key, will always be § and not ~.

Partial view of a Mac keyboard showing the section key location
The section symbol key on an ISO mac keyboard

Luckily there's a fix for this that does not involve using third-party software like Karabiner-Elements or Kanata, which feels overkill just to remap a single key.

I found this article that explains the why and how in great detail. The command hidutil, introduced in macOS Sierra, can change the mapping of the key, but for this to work in recent macOS versions you have to assign Input Monitoring permissions to the terminal app you use to run the command (Ghostty in my case).

The problem is that the new mapping created by hidutil won't persist between logins or OS restarts, so to restore the mapping you will need to run the command after each login.

The article suggests running hidutil directly from a LaunchAgent, but that did not work for me because of Input Monitoring permissions. What did work was using a LaunchAgent to run a shell script on login with bash, then adding bash to the list of applications allowed to do Input Monitoring:

First, create the shell script that will run hidutil and save it in your preferred folder. I will use ~/bin/remap-section-key.sh:

#!/bin/bash

hidutil property \
  --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc": 0x700000064,"HIDKeyboardModifierMappingDst":0x700000035}]}'

Make sure the script is executable by running:

chmod +x ~/bin/remap-section-key.sh

For reference:

  • 0x700000064 is the key code for §
  • 0x700000035 is the key code for ~.

Now, to make the script run on login, create the following plist file and save it to ~/Library/LaunchAgents/com.local.KeyRemapping.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>/bin/bash</string>
        <string>/Users/YOUR_USERNAME/bin/remap-section-key.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Don't forget to replace the YOUR_USERNAME with your actual username on the machine. We have to specify here the full path to the file because launchd does not expand ~/ or any other shell variables.

Finally, you need to grant Input Monitoring permissions to bash:

  1. Go to System Settings > Privacy & Security > Input Monitoring
  2. Click the + button and add bash from /bin/bash

Without these permissions, hidutil won't be able to remap the key when run by launchd.

And that's it! You should now have the key remapped and persisting between logins.