Create OS X MenuBar app?

Is it possible to create an app in Xojo that runs as an app in the menu bar? If so, how is that done?

Take a look at GitHub - macoslib/macoslib: MacOSLib - a set of classes to use OS X specific functions in Real Studio / Xojo applications and leverage the NSStatusItem example. You will need to then research hiding the application icon from the Dock when running

Check NSStatusItemMBS class in our MBS Xojo Plugins.
A few example projects are included.

Christian, - these look close, but I don’t want to see the app running in the dock. I just want it only showing in the menu bar.

The modern way to do that is with NSApplication activationPolicy which can be achieved with MBS or declares.

Thanks, Tim.

Was in the process of digging it up for you! Found it :slight_smile:

NSApplicationMBS.activationPolicy = NSApplicationMBS.NSApplicationActivationPolicyAccessory

3 Likes

Or you set info.plist entry for NSUIElement and value YES.

I had once a realbasic or studio demo app that did it, but I can’t find it. sorry.

I’m not sure where I got it (I don’t have a documented source) but I’m under the impression we’re not supposed to use that Info.plist key and that Apple prefers the activation policy method.

The activation policy also has the upside that you can use it to enable/disable dock icon at a whim for a preferences option.

Is that different than LSUIElement?

Probably the same thing in two name spaces :slight_smile:

Apple and their efficiency… :roll_eyes:

The instructions provided here are awesome! Thank you @Christian_Schmitz and @Tim_Parnell.

One final thing - is there a way to tell OS X to bring the window for the app to the front when shown? Right now I can show the window but since the app is not in the dock, the window ends up being hidden behind any other open windows…

use an global floating window.

Or bring app to front with App.FrontmostMBS = true

1 Like

Is that a shortcut for NSApplicationMBS.sharedApplication.activateIgnoringOtherApps(true)?

1 Like

Well, different APIs doing the same work.

I knew you would have a solution for that, Christian!

1 Like

You can do it with a simple declare. Make a new method and put this inside:

declare function NSClassFromString lib "Cocoa" ( inName as CFStringRef ) as Ptr
declare function sharedApplication lib "Cocoa" selector "sharedApplication" ( classRef as Ptr ) as Ptr
Dim myApp as Ptr =  sharedApplication( NSClassFromString( "NSApplication" ) )
declare sub activateIgnoringOtherApps lib "Cocoa" selector "activateIgnoringOtherApps:" ( appRef as Ptr, flag as boolean )
activateIgnoringOtherApps( myApp, True )

Then just call the method anytime you want to bring your app to the front. Works on all versions of macOS I’ve tested from 10.10 through Big Sur.

Thank you, Perry. I ended up making my window a Global Floating Window and that does what I want. The real purpose of this app is to send OS X Calendar Event data over an IPC Connection to a Xojo Web app that runs in a shell created by the desktop app. So the window is just used to verify information mainly if something isn’t working right. 99.9% of the time it will never be used…