I'm experimenting with some low(ish) level macOS coding for fun and curiosity.
I've been able to create a commandline app that can conditionally also launch a GUI with a window or two. (I'm sure other GUI app functionality is missing too.)
But despite having the regular macOS windows I can't alt-tab to the app when it's in GUI mode. I'm unable to find any discussion on what is needed for this.
Must I call some Foundation/AppKit APIs? Pass some flags when opening my windows? Add something to my Info.plist
? If it's the last option, is there also a way to programmatically do all/most of what the Info.plist
does declaratively?
(Additional info: My app is extremely minimal, consisting of just one .swift
file and one XCode project file. No resource files or Info.plist
or anything else.)
I found the solution thanks to this question.
You can set the app's "activation policy" to "regular" before launching the GUI:
NSApplication.shared.setActivationPolicy(.regular)
NSApplication.shared.run()
As well as working with Alt+Tab the app will now appear in the dock, will have a (default, empty) menu, respects Command+` to cycle through its windows, and it gets a default app icon that looks a bit like the Terminal or Console icon but with exec
written in its top left corner.
An undesirable side-effect is that debug info for the GUI is now output to the terminal. I'll have to look into how to prevent that:
1 HIToolbox 0x00000001902e05c8 _ZN15MenuBarInstance22EnsureAutoShowObserverEv + 120
2 HIToolbox 0x00000001902e0188 _ZN15MenuBarInstance14EnableAutoShowEv + 60
3 HIToolbox 0x0000000190283310 SetMenuBarObscured + 372
4 HIToolbox 0x0000000190282ee8 _ZN13HIApplication15HandleActivatedEP14OpaqueEventRefhP15OpaqueWindowPtrh + 172
5 HIToolbox 0x000000019027cfcc _ZN13HIApplication13EventObserverEjP14OpaqueEventRefPv + 296
6 HIToolbox 0x0000000190243cd0 _NotifyEventLoopObservers + 176
7 HIToolbox 0x000000019027c96c AcquireEventFromQueue + 432
8 HIToolbox 0x000000019026be0c ReceiveNextEventCommon + 712
9 HIToolbox 0x000000019026bb2c _BlockUntilNextEventMatchingListInModeWithFilter + 72
10 AppKit 0x0000000189e18424 _DPSNextEvent + 632
11 AppKit 0x0000000189e175b4 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 728
12 AppKit 0x0000000189e0b9e4 -[NSApplication run] + 464
13 macos-cond-gui-2 0x0000000104cd0764 main + 2148
14 dyld 0x000000018678fe50 start + 2544