Holding up the ⌘+Q

Something that’s been bugging me for a while now is reaching for Command+W to close an open Finder window or a tab in Firefox, and hitting that blasted Q key by accident. Well, no more, I decided!

For the uninitiated, hitting Command+Q on a Mac keyboard quits the current application – as far as I’m aware – without exception. Some applications will give you a warning that you are about to quit and you may lose unsaved data. Since Firefox introduced built-in session management so that it will fire up just as you left it, it no longer seems to warn you when you quit. Looking at about:config in one of my Firefox tabs shows browser.warnOnQuit set to true. Firefox will warn me when I try to close a window with multiple tabs open in it, but it doesn’t warn my when I hit Command+Q.

So, in trying to fix this little problem, I discovered a few ways to create helpful keyboard shortcuts and tame some not-so-useful ones.

Custom keyboard shortcuts in OS X

You can set custom keyboard shortcuts for various aspects of OS X and any of your installed applications in System Preferences – it’s under Keyboard & Mouse, and then the Keyboard Shortcuts tab.

  1. Hit the + (plus) button to begin adding a new shortcut.
  2. Select an application to customise, or let it affect all applications.
  3. Type in the Menu Title, which is the text as it appears in the menu item you’re wanting to customise. You can just switch to the application in question to check it.
  4. Hit the Keyboard Shortcut box and then do the desired key stoke you want to use for that menu item.

Now, I knew about this before and have set a couple of my own shortcuts previously. Here’s a couple of examples from my preferences:

  • In Safari, Shift+Command+S is set to Disable Styles from Safari’s Develop menu.
  • In Thunderbird, Option+Command+V is set to Paste Without Formatting.

So, it was a bit annoying to find the same didn’t work when trying to fix my premature evacuation woes in Firefox. You seem to be able to assign keyboard shortcuts to Firefox menu items, but if you set Command+Q to a menu item other than Quit, it still quits the application. You can also try setting a different shortcut to Quit (I tried Option+Command+Q), but still no joy.

Taming Firefox keyboard shortcuts with Keyconfig

There’s an extension for Firefox called Keyconfig, which remained unusable with Firefox 3 for a while. I read that the latest build now works, so I tried it, and — hey presto! — it installed. Alas, it wouldn’t override Command+Q for me. However, it did help me fix up some keyboard conflicts caused by various add-ons.

Once Keyconfig is installed, you can go to Keyconfig… under the Tools menu to see all the keyboard shortcuts that Firefox uses. Any shortcuts that are assigned to more than one action are highlighted for you. This is great for tracking down and fixing keyboard conflicts caused by some cheeky little add-on hijacking the shortcuts you’ve grown to know and love. (Yay, Shift+Command+F now opens Web Developer‘s Display Element Information tool again, instead of opening up the settings for Foxmarks!)

So, I began to assume that Command+Q is engrained into the application somewhere, possibly at the Cocoa level.

Hacking key bindings with brute force

With the help of this OS X hint and a little poking around (thanks Sean), running this in Terminal has worked for me:

defaults write org.mozilla.firefox NSUserKeyEquivalents '{"Quit Firefox"="@~Q";}'

This tells Firefox (the org.mozilla.firefox package) to use Option+Command+Q as the shortcut (keyboard equivalent) for the Quit Firefox menu item.

As with the System Preferences method above, you need to address the menu item using the text as it appears in the menu, so "Quit Firefox". To my knowledge, this technique will only work with Firefox 3, as that release was built using Cocoa.

You can customise the shortcut where my code has @~Q by using these characters to represent the desired keys:

@
Command
$
Shift
~
Option
^
Control

Apparently, you can set these keyboard equivalents globally, but I decided not to do this. If you want to target a specific application in the way I have, the following may help you find out its package name:

  1. Fire up Terminal and type ps -ax | grep firefox, but replace “firefox” with the application you’re looking for. This should help you to figure out the application’s process name. For example, Firefox’s process name is “firefox-bin”.
  2. Now fire up Script Editor and run the AppleScript tell application "System Events" to get bundle identifier of application process "firefox-bin", replacing “firefox-bin” with your target application’s process name. That code goes in the top pane of Script Editor. Then hit Run.
  3. You should see the package name appear in the output pane below the script, e.g. org.mozilla.firefox.

So, as another example, running ps -ax | grep twhirl in Terminal tells me that the process name I want for Twhirl is in fact “twhirl”. Running the AppleScript tell application "System Events" to get bundle identifier of application process "twhirl" gives me the package name de.makesoft.twhirl.[SOMEHASH].

Save your head, your desk, the world!

That’s all for now. I hope this stops a few people from banging their heads on their desks!