Search code examples
macosqtmenudock

How to disable the "Quit" menu item on an application's dock menu


I've written a macOS application with Qt. This application is a launch agent, meaning that it's launched by launchd, and always running in the background.

Normally, the application only has a menu bar icon, and it doesn't have any open windows or a dock icon. (i.e., the shared NSApplication instance's activationPolicy property is set to a value of NSApplicationActivationPolicyAccessory.)

However, there are a few menu items available in its menu bar item that open some windows.

When those windows are open, the app switches to not being background-only any longer, so it will have a dock icon and a menu bar (i.e., activationPolicy is changed to NSApplicationActivationPolicyRegular.).

With there being a dock icon, that means it's possible for the user to right-click it and open its menu, and that menu has its default menu item for quitting the application.

Since the app is a launch agent, and is intended to always be running, quitting it just causes launchd to relaunch the app.

I'd like to disable or remove this menu item if possible, or otherwise prevent the user from being able to quit the app in this manner.

How do I accomplish this either with:

  • Pure Qt functions
  • macOS specific functions.

I should add that because this is a Qt application, I can't use the same method as outlined here because I don't have access to the application's delegate.

I would need to use another approach. (For example, it may be possible to swizzle methods on Qt's application delegate, though if there's a cleaner way to accomplish this than I'd much rather do that.)


Solution

  • I've found that it's not possible to remove the "Quit" menu item from an application's dock menu, or any of the other standard menu items there, as they are created and handled by the dock itself.

    It is possible to stop an application from quitting when the user quits the application via the Dock.

    In a Qt application, the method is to subclass QApplication and override its bool event(QEvent *) method. The overridden method should check for events of type QEvent::Close, call the ignore() method on the event, and then return true.

    Note: this will stop the application from quitting via all other conventional methods as well.

    It is also possible to tell when the app is being quit via the dock, at least when using Apple's native API.

    See: Is there any way to know when the user has tried to quit an application via its Dock icon?

    By using Objective-C method swizzling, it's possible to override the applicationShouldTerminate: method of Qt's application delegate and prevent a Qt app from being quit by the dock.