Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There has to be a way to disable the Caps Lock key programatically #310

Closed
kevinSuttle opened this issue Dec 17, 2013 · 28 comments

Comments

Projects
None yet
7 participants
@kevinSuttle
Copy link
Contributor

commented Dec 17, 2013

Right?

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 17, 2013

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 17, 2013

Bam.

defaults read ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist com.apple.keyboard.modifiermapping.1452-610-0 
(
        {
        HIDKeyboardModifierMappingDst = "-1";
        HIDKeyboardModifierMappingSrc = 0;
    }
)
❯ defaults read-type ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist com.apple.keyboard.modifiermapping.1452-610-0
Type is array
@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 17, 2013

Got it, but it's writing to a string. Not sure of the syntax to write to a number/integer in an array format.

defaults write ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist com.apple.keyboard.modifiermapping.1452-610-0 -array '{"HIDKeyboardModifierMappingDst" = 0; "HIDKeyboardModifierMappingSrc" = -1;}'
@pengwynn

This comment has been minimized.

Copy link

commented Dec 17, 2013

CAPS is prime home row real estate to waste. I've remapped mine to CTRL+ESC for tmux+vim and haven't looked back. @kevinSuttle seen https://github.com/jasonrudolph/keyboard ?

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

@pengwynn Yeah, I know all about it, but my muscle memory just isn't mapped to use the key at all.

I'm just happy that I was finally able to figure out how to do this from the command line. Haven't seen anyone do that yet.

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

I can certainly appreciate the time and approach, but I'm just not there yet I don't think. http://stevelosh.com/blog/2012/10/a-modern-space-cadet/

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

@mathiasbynens I'm sure you could probably do this with PlistBuddy also.

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

Got it.

# Disable the CAPS LOCK key
/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.1452-610-0 array" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add :com.apple.keyboard.modifiermapping.1452-610-0: dict" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.1452-610-0:0:HIDKeyboardModifierMappingDst integer -1" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.1452-610-0:0:HIDKeyboardModifierMappingSrc integer 0" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

@mathiasbynens

This comment has been minimized.

Copy link
Owner

commented Dec 18, 2013

Is the 1452-610-0 the same for all OS X versions / users / environments?

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Dec 18, 2013

That's what I'm wondering. Can you backup your file and test, or more safely, just check the value?

@oxyc

This comment has been minimized.

Copy link

commented Jun 19, 2015

For reference, the value is 1452-626-0 on my 12" macbook (2015). So it does change.

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Jun 19, 2015

Who knows?

@Tatsh

This comment has been minimized.

Copy link

commented Jun 19, 2015

I would think the value is not predictable. Maybe not even model specific really, but it looks like the 1452 portion is always the same. @oxyc how did you find that value for your machine?

I have a few machines I can try: 2013 Mac Pro, Mid-2012 MacBook Pro, Mid-2014 MacBook Pro, unkown-2012 (might be 2013) MacBook Air.

Looking at ~/Library/Preferences/ByHost/.GlobalPreferences/*.plist and I actually have two. I wonder if one if left over from upgrading to Yosemite.

@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Jun 20, 2015

Seems like you can regex it to 1452-(3 integers)-0. Interesting.

@Tatsh

This comment has been minimized.

Copy link

commented Jun 20, 2015

I changed the Modifier key for Caps Lock in Settings and did not get a change in the ~/Library/Preferences/ByHost/.GlobalPreferences/*.plist path. There is only one on this machine (a never-upgraded Mac Pro).

The domain/default pair of (/Users/tatsh/Library/Preferences/ByHost/.GlobalPreferences.4598E8F9-CC91-5ACE-980E-03EDA8EAE871.plist, com.apple.keyboard) does not exist
@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Jun 20, 2015

Did that file exist before you ran the command?
Also, did you use the proper data type? kevinSuttle/macOS-Defaults@c36d81f

@Tatsh

This comment has been minimized.

Copy link

commented Jun 20, 2015

The file did not exist before I changed the setting in Settings.

I did not run the PlistBuddy commands because I was/am assuming that the key will appear if I change the setting via GUI. And because I do not know if that code is the right one for this system. I am trying to find out the correct code (the 1452- identifier).

@mathiasbynens

This comment has been minimized.

Copy link
Owner

commented Jun 20, 2015

I wonder if the same thing can be done using a custom .keylayout file.

@oxyc

This comment has been minimized.

Copy link

commented Jun 25, 2015

Found a way. Do you want to include it in your repo @mathiasbynens? I can send a PR

VENDORID="$(ioreg -n IOHIDKeyboard -r | awk '$2 == "\"VendorID\"" { print $4 }')"
PRODUCTID="$(ioreg -n IOHIDKeyboard -r | awk '$2 == "\"ProductID\"" { print $4 }')"

/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${VENDORID}-${PRODUCTID}-0 array" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add :com.apple.keyboard.modifiermapping.${VENDORID}-${PRODUCTID}-0: dict" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${VENDORID}-${PRODUCTID}-0:0:HIDKeyboardModifierMappingDst integer -1" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
/usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${VENDORID}-${PRODUCTID}-0:0:HIDKeyboardModifierMappingSrc integer 0" ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist
@Tatsh

This comment has been minimized.

Copy link

commented Jun 25, 2015

So those two values are vendor ID product ID. Good to know.

@oxyc Maybe delete entries before adding new ones? This is just in case the old entries are not necessary anymore.

Also I do not see a case where you handle if two keyboards appear under IOHIDKeyboard with ioreg. This could easily be the case where someone uses an external USB or Bluetooth keyboard with an external monitor on a MacBook, and therefore there are now two. I am assuming in that case your ioreg filtering would get back two or more lines instead of one.

@Tatsh

This comment has been minimized.

Copy link

commented Jun 25, 2015

In my .osx I am hard-coding to keyboards I have already instead of doing a dynamic check. Das keyboard model S is 1241-8211.

@oxyc

This comment has been minimized.

Copy link

commented Jun 25, 2015

Yes, as I don't use multiple keyboards I left it as this. @mathiasbynens hasn't really expressed interest so I thought to ask before making a more robust version.

@Tatsh

This comment has been minimized.

Copy link

commented Jun 25, 2015

Also just to note, I am pretty sure that upgrades or updates in general could cause a new plist to be generated in that path. Even on my Mac Pro that came with Yosemite I have two files there. If you just use the expansion ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist then you have two or more and PlistBuddy complains.

This is what I have due to the aforementioned. I know it probably does not matter to || continue on failure of the first attempt to write (and possibly this could mean other things), but I do not think the case of having an empty array will be very common. Could || continue on each line (but maybe not the lines that change the values).

###############################################################################
# Disable caps lock                                                           #
###############################################################################
# Delete old entries first
# Normally these do not have an entry for com.apple.keyboard.modifiermapping.*
# Sometimes there is more than one (maybe caused by upgrade?)
old_ifs="$IFS"
export IFS=$'\n'
for plist in ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist; do
    keys=$(/usr/libexec/PlistBuddy -c 'Print' "$plist" | egrep 'com\.apple\.keyboard\.modifiermapping.[0-9]' | awk '{ print $1 }')
    for key in "$keys"; do
        /usr/libexec/PlistBuddy -c "Delete ${key}" "$plist" >/dev/null 2>&1
    done
done
export IFS="$old_ifs"

# Keyboards, VID-PID; get from ioreg -n IOHIDKeyboard -r (USB only?)
das="1241-8211"
mbp2012="1452-610"

for pair in $das $mbp2012; do
    for plist in ~/Library/Preferences/ByHost/.GlobalPreferences.*.plist; do
        # If first one fails, then the entry is assumed to exist
        /usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${pair}-0 array" "$plist" >/dev/null 2>&1 || continue
        /usr/libexec/PlistBuddy -c "Add :com.apple.keyboard.modifiermapping.${pair}-0: dict" "$plist"
        /usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${pair}-0:0:HIDKeyboardModifierMappingDst integer -1" "$plist"
        /usr/libexec/PlistBuddy -c "Add com.apple.keyboard.modifiermapping.${pair}-0:0:HIDKeyboardModifierMappingSrc integer 0" "$plist"
    done
done
unset das mbp2012
@martinlindhe

This comment has been minimized.

Copy link

commented Jan 15, 2017

Hi, found this while attempting the same. Sorry for resurrecting an old issue, but this method using PlistBuddy no longer works on macOS 10.10+ because they started caching the plist preferences. the "defaults" command has been updated to work with the new caching system, but the PlistBuddy tool sadly, has not. However as mentioned earlier in this issue, it does not seem to be possible to instruct defaults into creating the proper structure. One last resort is using a python script, that speaks with the proprer API's, looks like this:

not updated to solve this particular issue, just a copy&paste:

#!/usr/bin/python
import CoreFoundation 

ManagedPlugInPolicies = {

# Always Allow Sharepoint plugin
    "com.microsoft.sharepoint.browserplugin": { 
        "PlugInFirstVisitPolicy": "PlugInPolicyAllowNoSecurityRestrictions", 
    }} 

CoreFoundation.CFPreferencesSetAppValue("ManagedPlugInPolicies", ManagedPlugInPolicies,  "com.apple.Safari") 
CoreFoundation.CFPreferencesAppSynchronize("com.apple.Safari")

Source: https://macmule.com/2014/02/07/mavericks-preference-caching/

I also investigated using AppleScript to reconfigure the settings, but doing so in an automated manner blocks you at execution error: System Events got an error: osascript is not allowed assistive access. which is even more hazzle to configure than just disabling caps in the settings.
One can come around this by manipulating sqlite database, but the table needed was recently changed (a column added) so it is not a "stable" solution either. Also you must add access for the terminal app you are invoking the osascript command from. For reference, using iTerm:

find app bundle id:

/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' /Applications/iTerm.app/Contents/Info.plist
com.googlecode.iterm2

give it access:

sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT INTO access VALUES('kTCCServiceAccessibility','com.googlecode.iterm2',0,1,1,NULL,0);" 

I am now dusting of my python since it seems to be the last possible solution.

@martinlindhe

This comment has been minimized.

Copy link

commented Jan 15, 2017

Update: I ragequit. While the python solution worked and created a integer 0, the -1 in this snippet turned into a string. Same issue as with 'defaults' command.

Here is what I came up with, if someone wants to take this deeper. Use system python interpreter to find CoreFoundation

/usr/bin/python -c '

import CoreFoundation

POL = [{
    "HIDKeyboardModifierMappingSrc": 0,
    "HIDKeyboardModifierMappingDst": -1,
}]

CoreFoundation.CFPreferencesSetAppValue("modifiermapping.1452-567-0", POL, "com.apple.keyboard")
CoreFoundation.CFPreferencesAppSynchronize("com.apple.keyboard")
'

and here is an osascript:

osascript -e '
tell application "System Preferences"
    reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell    
tell application "System Events" to tell window 1 of process "System Preferences"
    click button "Modifier Keys…" of tab group 1
    tell sheet 1
        tell pop up button 1
            click
            click menu item "No Action" of menu 1
        end tell
        click button "OK"
    end tell
end tell    
quit application "System Preferences"
'
@sj26

This comment has been minimized.

Copy link

commented Aug 21, 2017

defaults with plist syntax won't respect the integer type, it will only save values as strings. But you can use the XML syntax. Here's what I'm using now:

VENDORID="$(ioreg -n IOHIDKeyboard -r | awk '$2 == "\"VendorID\"" { print $4 }')"
PRODUCTID="$(ioreg -n IOHIDKeyboard -r | awk '$2 == "\"ProductID\"" { print $4 }')"
defaults -currentHost write -globalDomain \
  "com.apple.keyboard.modifiermapping.${VENDORID}-${PRODUCTID}-0" \
  "<array><dict><key>HIDKeyboardModifierMappingSrc</key><integer>0</integer><key>HIDKeyboardModifierMappingDst</key><integer>-1</integer></dict></array>"
@kevinSuttle

This comment has been minimized.

Copy link
Contributor Author

commented Aug 22, 2017

Sierra has changed this, and you can now change the behavior of ESC in system preferences, so it should be in there somewhere.

@naggie naggie referenced this issue Oct 9, 2018

Open

mac defaults/config #122

0 of 11 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.