menu bar popover doesn't display when in fullscreen

I have an app that includes a view controller for a menu bar menu. The menu displays fine until another app is in fullscreen mode, such as fullscreen safari or mail. In this case, clicking the menu bar icon does nothing and the popover menu does not display. What do I need to do in order to make this work over a full screen app?

I've figured out that if I set the key

<key>LSUIElement</key> <true/>


in the info.plist, then the status bar menu popover functions as expected. Except that now, my app has no dock icon and no normal menubar. This is a standard app with a menu bar option. I don't want to lose app functionality in order to gain menu bar functionality. It would be nice to have both. Does anyone know of a way to make this work?

Or maybe I need to create another app just for the menu bar and then have my main app launch the second app. In this case, how does the menu bar app access the classes and variables from the main app?

I've found that

NSApp.setActivationPolicy(NSApplicationActivationPolicy.accessory)

or

NSApp.setActivationPolicy(NSApplicationActivationPolicy.regular)


works to toggle the popover functionality when in full screen. I have tried enabling and disabling this mode right when the popover is toggled, but it doesn't seem to work.

I've been reading about App Groups and shared user defaults. I haven't been able to make this work yet. But my current idea is to write an entirely separate app just for the menubar menu. Then include the compiled app in the main app. And somehow have this menu be able to access the user defaults from the main app. This seems kind of like a horrible hack way to get a menubar to work. But, judging by the responses here, nobody actually knows how to do this and so I guess I have a really pioneering idea to include a status bar item in my otherwise convential application. I will post updates if I figure it out.

Running a status item from a separate app with

LSUIElement
set is a pretty standard thing to do. I have two of these status items sitting in my menu bar right now.

Apple has even added specific infrastructure (

SMLoginItemSetEnabled
) to make it possible for these status item apps to run regardless of whether your main app is running. The AppSandboxLoginItemXPCDemo shows how to set this up (although it doesn’t actually do the status item thing).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks pointing me in the right direction. The example you have provided does not work for me, however. In my attempts, entering any question, or even just yes or no in the Demo box results in:

>>> no

Failed to query oracle: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named XYZABC1234.com.example.iDecideHelper was invalidated." UserInfo={NSDebugDescription=The connection to service named XYZABC1234.com.example.iDecideHelper was invalidated.}

Failed to query oracle: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named XYZABC1234.com.example.iDecideHelper was invalidated." …

Note that the message above contains a dummy Team ID, XYZABC1234. You’ll have to change that to your Team ID. The sample’s read me explains how to do this.

I literally did this yesterday while helping a developer as part of my Real Job™ (answering DTS tech support incidents). As part of that I wrote up some notes on the common gotchas here. They’re pasted in below.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Here’s some hints on how to bring up an XPC login item:

  • Start by getting the AppSandboxLoginItemXPCDemo sample working. This will yield vital experience in getting the details right, and a known baseline by which to measure your ongoing work.

  • Add a “Disable” menu command to AppSandboxLoginItemXPCDemo that calls

    SMLoginItemSetEnabled(…, false)
    . This makes it easier to reset your system back to a known state.
  • Test the XPC login item on a fresh machine. There’s a strong dependency between these login items and Launch Services, and the Launch Services database on your development machine can get very confused as you build, debug and delete different versions of your product.

    Note I test stuff like this in a virtual machine. I install the machine afresh and then take a snapshot. Then for each build of my app I restore from that snapshot before running my test. That way I can be confident that test N hasn’t messed up test N+1.

  • Test with the app in

    /Applications
    , which makes it easier for Launch Services to find it.
menu bar popover doesn't display when in fullscreen
 
 
Q