Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, PHP, and whatever else I happen to feel like hacking at.

Disabling Quit and rewriting keyboard shortcuts

Jerry Stratton, September 30, 2005

This is an old tip with bits and pieces spread throughout the web. I’m going to try and put all of the useful information in one place. Ever since upgrading to Mac OS X 10.4, Safari has become much more reliable. This has resulted in my becoming lazy and writing articles within forms on Safari. I’m writing this article in Safari, for example.

Every once in a while, after looking up some information elsewhere on the web, I will go to close the window with CMD-W and accidentally hit CMD-Q as well. Last night I lost about five minutes of work. It isn’t much, but it is annoying as hell, so I finally decided to learn how to disable Quit in Safari. What I found was a means of disabling or remapping the keyboard equivalents in any Cocoa application.

Mac OS X is designed with a hierarchical system of preferences and options, moving from the individual user up to system-level options. Applications such as Safari generally set their own menu equivalents, but any user can override those equivalents for their own use.

Disabling Safari’s Quit key equivalent

Try typing this in the terminal:

  • defaults read com.apple.Safari NSUserKeyEquivalents

Unless you have already remapped your key equivalents, you should receive something like “The domain/default pair of (com.apple.Safari, NSUserKeyEquivalents) does not exist”.

Now, quit Safari and type:

  • defaults write com.apple.Safari NSUserKeyEquivalents -dict-add "Quit Safari" "@^Q"
  • defaults read com.apple.Safari NSUserKeyEquivalents

You should now see “{"Quit Safari" = "@^Q"; }”. The curly brackets indicate a list. We could easily add multiple changes to Safari’s key equivalents. The “Quit Safari” is what the menu item appears as under the menu. And “@^Q” is the new key equivalent. The next time you start Safari, you’ll need to type CMD-CTRL-Q to quit instead of CMD-Q.

Changing every application

If there is something you want to change in every application, you can change it in the “global domain” rather than in each application separately.

  • defaults read -globalDomain NSUserKeyEquivalents
  • defaults write -globalDomain NSUserKeyEquivalents -dict-add "Hide Others" "@$H"
  • defaults read -globalDomain NSUserKeyEquivalents

The defaults command

The command is “defaults”. This command lets you read and write the defaults for many appilcation and system defaults. Most changes will take effect the next time you start an application. It is best to make changes while an application is closed, to keep it from overwriting your changes when it saves its own preferences the next time it quits.

  • defaults action domain key value

You can “read” or “write” the defaults for a domain (and I recommend always reading before writing).

The domain is likely to be the same as the name of the com file (without the .plist extension) in your Library/Preferences folder. You can find this name by typing:

  • ls ~/Library/Preferences/com.* | grep -i "application name"

For example,

  • ls ~/Library/Preferences/com.* | grep -i "Notes"
  • /Users/jerry/Library/Preferences/com.rws.Notes.plist

The domain for the Notes application is “com.rws.Notes”.

After the domain we specify the key that we are changing or adding to. The only key we’re using in this article is NSUserKeyEquivalents. Every key has a value, and for NSUserKeyEquivalents the value is a dictionary of key equivalents. A dictionary is a list of keys and values. Above, we gave a value of “@^Q" to the key named “Quit Safari”. A dictionary can have several key-value pairs, allowing us in this case to specify more than one custom key equivalent.

There is more than one way to modify a dictionary, but the easiest is probably with dict and dict-add.

dict-addAdd the next pair or pairs to the list
dictReplace the current list with the next pair or pairs

You can specify as many key-value pairs as you wish after -dict or -dict-add. There is unfortunately no -dict-remove. If you want to remove an item from the list, you will need to first read the current list and then write it back without the item you want removed.

If you want to disable a menu item completely, specify "nil" as the value in the key value pair.

If you want to remove the entire list, you can use “delete” instead of “write”:

  • defaults delete com.apple.Safari NSUserKeyEquivalents

Use “man defaults” to find out more about the defaults command in Mac OS X.

Key Equivalents

Your key equivalents must begin with a special key: command, option, shift, or control. Further, for the keystroke to work, one of the special characters must be the command key. That is, if you specify “^Q” as your key equivalent, “^Q” will show up in the menu but CTRL-Q will not work to quit your application.

Key equivalents can have one to four special keys, but may only have one non-special key.

CharacterSpecial Key
@Command (Apple)CMD
~OptionOPT
$ShiftSHIFT
^ControlCTRL
November 18, 2007: Safari 3’s smart window close

I just installed the latest Mac OS X 10.4 update, which installs Safari 3. I’ve also re-enabled quit, because Safari 3 is a lot smarter about closing windows and quitting. If I attempt to quit, or close a window, when I’ve got unsaved text in a window, it warns me first. And if I attempt to quit when I have multiple tabs open, it warns me about that. Those were the reasons I disabled the command key for quitting.

  1. <- Importing Vinyl
  2. JavaScript Tutorial ->