I'm apparently not the only one who wants to know (How can I change modifier keys in "System Preferences > Keyboard > Modifier Keys..."). I've tried watching the System Preferences app with dtruss, but that doesn't seem to be possible on 10.10.3 (which is what I'm on right now), and I'm not even sure that that would be at all useful if System Preferences is just getting settings from cfprefsd. Watching cfprefsd with dtruss doesn't seem to catch the relevant file access.
Does anyone know of an API to get this information? Something in gestalt perhaps?
Ok - answering my own question. I threw together a little program that uses kqueues to watch file system changes. I watched my file system for modifications when I changed the setting in System Preferences, and I saw:
'/Users/ted/Library/Preferences/ByHost/.GlobalPreferences.3F1C...9C34.plist.V1Ut9hp' kevent: ident=44, filter=KQ_FILTER_VNODE, flags=KQ_EV_ADD|KQ_EV_CLEAR, fflags=KQ_NOTE_WRITE|KQ_NOTE_CHILD|KQ_NOTE_PDATAMASK
So the setting is in ~/Library/Preferences/ByHost/.GlobalPreferences.<UUID>.plist
. I'm not sure what the UUID is - something do to with OpenDirectory? (UPDATE: apparently this UUID is an identifier for your machine).
Anyways, in .GlobalPreferences.<UUID>.plist
, we see entries like:
<key>com.apple.keyboard.modifiermapping.1452-610-0</key>
<array>
<dict>
<key>HIDKeyboardModifierMappingDst</key>
<integer>2</integer>
<key>HIDKeyboardModifierMappingSrc</key>
<integer>0</integer>
</dict>
</array>
1452:610 is the decimal VID:PID for the USB keyboard/trackpad combo in my 2012 Macbook Pro, and any other keyboard that's been plugged in to my computer and has had modifier settings remapped will have a similar entry. 0
seems to be the Caps Lock key, 2
and 10
seem to be left and right CTRL, 3
and 11
seem to be left and right Option, and 4
and 12
seem to be left and right Command.
So from the above, you can see that I have my Caps Lock key mapped to left CTRL.
It looks like the settings in .GlobalPreferences.<UUID>.plist
are a part of your standard user defaults. So you can get at these settings easily enough just by doing
[[NSUserDefaults standardUserDefaults] objectForKey:@"com.apple.keyboard.modifiermapping-1452-610-0"];
For anyone else stumbling across this, I was looking for a way to put this in my .dotfiles when setting up new machines. All I wanted was to remap caps-lock to escape.
In Sierra 10.12 it seems the solution on this post became invalid. The documented way from Apple works for me using 10.14.6 Mojave (*with a caveat)
Since Sierra 10.12, see: TN2450
# Remap caps-lock to escape
hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x700000029}]}'
plutil
Interestingly the solution is still correct about this file updating and saving information concerning keymapping when the user goes through the GUI to change modifier keys. However updating the keymapping info here doesn't seem to affect anything anymore.
This example uses the plutil
command which is the preferred way to update plists as defaults write
is deprecated according to the man page See filepath.
Also, see comparisons between the two commands and the library PlistBuddy.
#!/usr/bin/env bash
# Quit System Preferences so it doesn't muck with your settings
osascript -e 'tell application "System Preferences" to quit'
# Get your machine's UUID
__UUID__=$(
ioreg -ad2 -c IOPlatformExpertDevice | xmllint --xpath \
'//key[.="IOPlatformUUID"]/following-sibling::*[1]/text()' -
)
# Replace all contents of the array for the caps lock key/value pair.
plutil -replace "com\.apple\.keyboard\.modifiermapping\.1452-636-0" \
-json '[{
"HIDKeyboardModifierMappingDst": 30064771113,
"HIDKeyboardModifierMappingSrc": 30064771129
}]' \
~/Library/Preferences/ByHost/.GlobalPreferences.${__UUID__}.plist
# Pretty print file
plutil -p ~/Library/Preferences/ByHost/.GlobalPreferences.${__UUID__}.plist
hidutil
The new solution is much less verbose AND doesn't rely on filepath args or giving arguments types for the not very well documented plutil
command.
You can see this Stack Exchange post for another explanation.
This technical doc TN2450 describes the strategies for handling this with hidutil
or Xcode.
#!/usr/bin/env bash
# Quit System Preferences so it doesn't muck with your settings
osascript -e 'tell application "System Preferences" to quit'
# Remap caps-lock to escape
hidutil property --set '{
"UserKeyMapping":[{
"HIDKeyboardModifierMappingSrc":0x700000039,
"HIDKeyboardModifierMappingDst":0x700000029
}]
}'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With