Ignoring Command-Q in LSUIElement app (macOS, SwiftUI)?

I've got this LSUIElement app (no menu bar/dock icon). It puts up a window in certain circumstances to give the user control, but otherwise just runs in the background.

Today I noticed that with its window frontmost, you can type Command-Q and it will quit.

Is there a way to suppress that? I have explicit controls for quitting the app, but normally the user wants it to run in the background always, and I don't want it to be so easy to accidentally quit.

Answered by JetForMe in 774607022

I found a solution. It turns out that SwiftUI is creating its standard suite of menus (which I argue is incorrect for an LSUIElement app). So to my app’s SwiftUI main Window, I add the following modifier:

		.commands
		{
			CommandGroup(replacing: .appTermination)
			{
			}
		}

This removes the Quit menu item altogether. It might be better to call NSMenu.removeAllItems() in my app delegate, but from what I read online, SwiftUI will restore the menus, and so you have to observe NSApp.mainMenu for changes.

Once again, Apple has offered very narrow use-case solutions in SwiftUI, without more generalized support.

If you implement applicationShouldTerminate in an application delegate, you should be able to decline to quit.

Accepted Answer

I found a solution. It turns out that SwiftUI is creating its standard suite of menus (which I argue is incorrect for an LSUIElement app). So to my app’s SwiftUI main Window, I add the following modifier:

		.commands
		{
			CommandGroup(replacing: .appTermination)
			{
			}
		}

This removes the Quit menu item altogether. It might be better to call NSMenu.removeAllItems() in my app delegate, but from what I read online, SwiftUI will restore the menus, and so you have to observe NSApp.mainMenu for changes.

Once again, Apple has offered very narrow use-case solutions in SwiftUI, without more generalized support.

Ignoring Command-Q in LSUIElement app (macOS, SwiftUI)?
 
 
Q