Menulet (OS X equivalent of Windows "system tray")

I’m surprised that Xojo still doesn’t have a “menulet” Desktop application demo (the upper right hand corner near the clock) for their TrayItem/Status for OS X. Both Windows’ system tray and Linux’s status icon is covered but no “menulet” (what Apple calls the area).

Does anyone know how to implement this in Xojo, perhaps through Cocoa declares? I noticed that MBS had a NSMenuItem component, but for doing things natively through Cocoa would be ideal. Any seasoned Mac devs know? :slight_smile:

I know how much work it was to make NSStatusItem work right. So why not take the plugin instead of spending endless hours recreating it?

Searching NSStatusItem I found a hello world example here creatingitems.html which didn’t take long to translate…

[code]Window Window1

Constant Cocoa = “Cocoa.framework”

Property theItem As Ptr

//PushButton buttonAdd
Sub Action()
if theItem <> nil then return
soft declare function NSClassFromString lib Cocoa (aClassName as CFStringRef) as Ptr
soft declare function systemStatusBar lib Cocoa selector “systemStatusBar” (cls As Ptr) as Ptr
soft declare function statusItemWithLength lib Cocoa selector “statusItemWithLength:” (id As Ptr, length As Single) as Ptr
soft declare sub retain lib Cocoa selector “retain” (id as Ptr)
soft declare sub setTitle lib Cocoa selector “setTitle:” (id As Ptr, newTitle As CFStringRef)
soft declare sub setHighlightMode lib Cocoa selector “setHighlightMode:” (id As Ptr, flag As Boolean)

dim bar As Ptr = systemStatusBar(NSClassFromString("NSStatusBar"))

theItem = statusItemWithLength(bar, -1) //NSVariableStatusItemLength (-1)
retain(theItem)

setTitle(theItem, "xoji:)")
setHighlightMode(theItem, true)
'setMenu(theItem, ?)

End Sub

//Pushbutton buttonRemove
Sub Action()
if theItem = nil then return
soft declare sub release lib Cocoa selector “release” (instsRef as Ptr)

release(theItem)

theItem = nil

End Sub

End Window[/code]

Attaching something usable like a menu or view may take endless hours, especially if you can’t use handles from xojo and have to build all that too. But then MacOSLib can probably build that if it doesn’t even already have… ok, it looks like NSStatusBar and NSStatusItem were added to MacOSLib 7 days ago by vidalvanbergen…
https://github.com/macoslib/macoslib/blob/master/macoslib/Cocoa/NSStatusBar.rbbas
https://github.com/macoslib/macoslib/blob/master/macoslib/Cocoa/NSStatusItem.rbbas

There’s a Feedback request. Sign on if you support it. <https://xojo.com/issue/1792>

Please take a look at my fork of macoslib here .
It’s a little bit outdated since I no longer have time to maintain it, but here you will find a complete implementation of the NSStatusItem using Cocoa declares. I’m sure you can extract the NSStatusItem class and wire it to the official macoslib.

[quote=26826:@Massimo Valle]Please take a look at my fork of macoslib here .
It’s a little bit outdated since I no longer have time to maintain it, but here you will find a complete implementation of the NSStatusItem using Cocoa declares. I’m sure you can extract the NSStatusItem class and wire it to the official macoslib.[/quote]

Interestingly, while MacOS Lib already has the necessary classes it lacks an example.

Your example window, though, is a drop-in that works perfectly with the “stock” macoslib as of today. :slight_smile:

Massimo: I’ve posted a pull request to the main macoslib branch with your example, as it was useful to me and might be to others.

Great - Massimo’s example was useful to me too.

Whats the difference between Massimo’s code and the links I posted above to vidalvanbergen’s code?

Vidalvanbergen’s was adding Massimo’s code :slight_smile: Eduardo has now also posted a pull request to add Massimo’s example as well.

I see, thanks. I’ll learn to read version control threads someday :slight_smile:

Apologies for resurrecting this conversation, I have added MacOSLib and can create a NSStatusItem menu in my app. How do I get this to work without showing any application window? I want to just have the NSStatusItem menu showing and then show/hide modal dialog boxes and Windows in response to menu selections. If I set the App’s default Window to None the app runs and quits straight away. Is there a correct way to make this work?

If you want to PM me your email address, I will send you a template that I created to make NSStatusItem apps. It will do what you are looking for.

Thanks Gavin, Private Message sent.

I case it helps anyone else the mistake that I was making was to set self.AutoQuit = true :[ . Thanks to Gavin for the sample and therefore making it easy to spot my mistake.

Basically my goal would be to display a Xojo window in lieu of a pop-up menu. Though I can’t wrap my head on how to detect an initial click on the status bar icon itself. I’m thinking I might be able to detect the menu about to open, but still far from figuring this one out. Then the next question is positioning. All I have so far…

statusBar = NSStatusBar.SystemStatusBar()
statusItem = statusBar.CreateStatusItem(-1, AddressOf Hit)
statusItem.HighlightMode = True
Dim image As NSImage
statusItem.Image = myappicon
statusItem.ToolTip = “Click here to popup the control panel”

[quote=22923:@Will Shank]
Window Window1

Constant Cocoa = “Cocoa.framework”

Property theItem As Ptr

//PushButton buttonAdd
Sub Action()
if theItem <> nil then return
soft declare function NSClassFromString lib Cocoa (aClassName as CFStringRef) as Ptr
soft declare function systemStatusBar lib Cocoa selector “systemStatusBar” (cls As Ptr) as Ptr
soft declare function statusItemWithLength lib Cocoa selector “statusItemWithLength:” (id As Ptr, length As Single) as Ptr
soft declare sub retain lib Cocoa selector “retain” (id as Ptr)
soft declare sub setTitle lib Cocoa selector “setTitle:” (id As Ptr, newTitle As CFStringRef)
soft declare sub setHighlightMode lib Cocoa selector “setHighlightMode:” (id As Ptr, flag As Boolean)

dim bar As Ptr = systemStatusBar(NSClassFromString("NSStatusBar"))

theItem = statusItemWithLength(bar, -1) //NSVariableStatusItemLength (-1)
retain(theItem)

setTitle(theItem, "xoji:)")
setHighlightMode(theItem, true)
'setMenu(theItem, ?)

End Sub

//Pushbutton buttonRemove
Sub Action()
if theItem = nil then return
soft declare sub release lib Cocoa selector “release” (instsRef as Ptr)

release(theItem)

theItem = nil

End Sub

End Window [/quote]

Does anyone know how I can create MenuItems in this example?

Is there any update on this issue? IS the system tray on any os supported by Xojo?

You could try the examples coming with MBS Plugin…
http://www.monkeybreadsoftware.de/xojo/

The only plugin I found is windows only: http://www.monkeybreadsoftware.net/topic-windowssystemtray.shtml
Are you Christian aware about anything working on macOs too? Thank you for your answer