7

I like that Chrome asks you to hold "Cmd-Q" to quit. Is there a way to do this for every app on a Mac?

  • 1
    When you say "Is there a way to do this for every app on a Mac?", are you referring to individual apps one at a time, or all running apps all at once? – user3439894 Jan 19 at 23:52
  • As opposed to the normal cmd+Q that happens instantly with all other apps? Are you asking about causing other apps to have the same delay as Chrome? – bjbk Jan 20 at 1:14
  • 1
    You may find this useful : apple.stackexchange.com/q/340508/237687 – Solar Mike Jan 20 at 7:34
  • Not at all sure about this, so posting as a comment, not an answer: If you're willing to invest some time in learning to use Hammerspoon, it might be possible for you to let hammerspoon catch all cmd-Q keypresses and having it ask the foreground application to quit if the key is pressed for a certain amount of time. Caveat: You must learn a bit of Lua programming first, unless you can convince some seasoned hammerspoon user to write the code for you. (Not me, sorry.) – Harald Hanche-Olsen Jan 20 at 16:38
  • @HaraldHanche-Olsen I will bounty an answer that explains Hammerspoon. Even if it’s not a complete answer, that tool needs people to share how powerful it is. I haven’t invested time to learn it, but I’ll invest reputation to those that can or have +1 – bmike Jan 20 at 18:33
7
+50

You can do this by installing and running Hammerspoon, then including the following Lua code in the Hammerspoon configuration file (.hammerspoon/init.lua):

-- config: number of seconds to hold Command-Q to quit application
cmdQDelay = 2

cmdQTimer = nil
cmdQAlert = nil

function cmdQCleanup()
  hs.alert.closeSpecific(cmdQAlert)
  cmdQTimer = nil
  cmdQAlert = nil
end

function stopCmdQ()
  if cmdQTimer then
    cmdQTimer:stop()
    cmdQCleanup()
    hs.alert("quit canceled",0.5)
  end
end

function startCmdQ()
  local app = hs.application.frontmostApplication()
  cmdQTimer = hs.timer.doAfter(cmdQDelay, function() app:kill(); cmdQCleanup() end)
  cmdQAlert = hs.alert("hold to quit " .. app:name(), true)
end

cmdQ = hs.hotkey.bind({"cmd"},"q",startCmdQ,stopCmdQ)

Change the value of cmdQDelay to fit your preference.

A brief explanation:

The final line tells Hammerspoon to intercept any presses of Command-Q. It will run the lua function named startCmdQ when the key is pressed, and stopCmdQ when it is released.

startCmdQ takes a note of the foreground app, then starts a timer. If the timer times out, the function given as argument to the timer is called. It kills the app (really, asks it to quit) and cleans up after the action.

stopCmdQ stops the timer if it is still running, so the application is not quit after all. It too cleans up afterwards.

The action is accompanied by alerts to let you know what is going on.

Edit: Once this is installed and active, you can turn it off by running cmdQ:disable() in the hammerspoon console. Turn it back on with cmdQ:enable(). And if you want to excempt some apps from the delay treatment, you can add a test for those apps in the startCmdQ function, opting to run app:kill() immediately instead of starting the timer.

Edit the second: A word of caution. This will let you quit the Finder. Don't panic, though. The easiest way to relaunch Finder is to click on its icon in the Dock. Or you can use Spotlight: Open it via the magnifying glass icon in the menu bar or its keyboard shortcut and type “Finder.app”, then return. (You will only need to type a few letters, as Spotlight will fill in the rest for you). You can also relaunch Finder by running the command hs.application.open("Finder") in the hammerspoon console, or open -a Finder in a Terminal window, if you happen to have Terminal running.

  • I got inspired by this question, and have added the above code to my own Hammerspoon config, as I do tend to hit command-Q once in a while without intending to. Time will show if I want to keep it or not. – Harald Hanche-Olsen Jan 26 at 20:15
  • @user3439894 Oh, right! Thanks for pointing that out. I am not a heavy Dock user myself, usually relying on quicksilver for my application launching needs, so I just didn't think of it. – Harald Hanche-Olsen Feb 3 at 14:13
3

If you want this behavior because you are afraid you'll accidentally press ⌘Q while trying to press something similar (usually ⌘W or perhaps ⌘Tab), then you can remap the ⌘Q shortcut to a similar but harder-to-press shortcut, let's say to ⌥⌘Q.

To do this, you'll need either 1) a way to remap ⌘Q to ⌥⌘Q, or 2) block ⌘Q and set ⌥⌘Q to quit apps.

Method 1: remap ⌘Q to ⌥⌘Q

Method 1a: Using System Preferences

  1. Go to System Preferences > Keyboard > Shortcuts > App Shortcuts
  2. For each app individually you want to do this in, create a shortcut which has trigger ⌥⌘Q and action Quit x where x is the name of the app. For example, for Safari I'd write "Quit Safari" (without quotes). Note that if this isn't working you might need to check what the name of the app is in the menu bar item.

Method 1b: Using Karabiner Elements or something similar

This should remove the limitation of manually having to set the shortcut for all apps. This is likely possible with the powerful tool Karabiner Elements but unfortunately I'm not fluent enough in it to say how.

As mentioned by Harald Hanche-Olsen in the comments, Hammerspoon may also let you do this, although you will need to look into it a bit more.

Method 2: block ⌘Q and set ⌥⌘Q to quit

The only reason I'm including a third-party app here is that it should be possible to do with using BTT globally, but due to a bug (?) you'll need to do this individually for all apps.

  1. Download and install BetterTouchTool (paid but has a 45-day trial)
  2. Create a global keyboard shortcut with ⌘Q set to do nothing
  3. Create a global keyboard shortcut with ⌘Q set to the action Menu Bar Item, and set this as the description: x;Quit x where x is the name of the app. Again note you might need to check what it actually says in the app you want to do this for.

I was hoping you could globally do this by using a wildcard in step 3 for the the first-level menu bar item, which would eliminate the need to explicitly type the app name in. In this case, you could use *;Quit * as the description. However, this doesn't seem to be possible for some reason.

  • This is the best you can do with Apple’s current human interface guidelines and SDK. You can change shortcuts, you can’t change the timing when they trigger. Today, shortcut activation is instant. When a valid press is recognized is when the action fires and not before or after then. – bmike Jan 20 at 18:29
  • I’m dismissing flags on this as not an answer. Even though it doesn’t directly answer the question, it is an excellent post on a workaround that will solve a practical question and relates to changing quit behavior. – bmike Jan 20 at 18:31
  • I suggest you contact the author of Karabiner Elements. KE already has use two command+s presses for one press. May not be too hard to enhance. – historystamp Jan 21 at 3:05
1

No, there is no way to coax all other applications into the hold-cmd-Q-for-couple-of-seconds-to-quit behavior.

Apple controls the apple apps and the SDK and they don’t implement this.

At best you could get a bunch of third party developers that like this idiom to all implement it.

  • Firefox asks for confirmation if you have multiple tabs open... – Solar Mike Jan 20 at 7:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .