How do I make a tray-icon-only C# application in MonoMac (no dock icon)?

Viewed 2626

I am trying to create an application that will have a tray icon only, and not appear in the taskbar. (similar to Dropbox) I need to create both Windows and Mac version of the application, so I tried using MonoMac to create the Mac front-end.

What is the best way to create a tray-only application in MonoMac?

All the resources I have found say to do one of two things:

  • Add <key>LSUIElement</key><string>1</string> to the Info.plist file.
  • Add the following code to the FinishedLaunching event in the AppDelegate class: NSApplication.SharedApplication.ActivationPolicy = NSApplicationActivationPolicy.Accessory;

I have tried all combinations of these two, but it seems that as soon as I try to instantiate a C# System.Timers.Timer, the icon reappears in the dock at the bottom of the screen. Am I missing something about how OSX handles background applications?

What am I doing wrong? Is there a better way to make a background application that has an upper tray icon but no bottom dock icon in OSX?

(This is very similar to this SO question, but that question was from a couple years ago and was never fully answered, so I'm hoping there might be a more complete answer out there.)


Here's the code I have so far:

public partial class AppDelegate : NSApplicationDelegate
{
    MyServiceObject currentServiceObject;

    public AppDelegate () { }

    public override void FinishedLaunching (NSObject notification)
    {
        // Construct menu that will be displayed when tray icon is clicked
        var notifyMenu = new NSMenu();
        var exitMenuItem = new NSMenuItem("Quit My Application", 
            (a,b) => { System.Environment.Exit(0); }); // Just add 'Quit' command
        notifyMenu.AddItem(exitMenuItem);

        // Display tray icon in upper-right-hand corner of the screen
        var sItem = NSStatusBar.SystemStatusBar.CreateStatusItem(30);
        sItem.Menu = notifyMenu;
        sItem.Image = NSImage.FromStream(System.IO.File.OpenRead(
            NSBundle.MainBundle.ResourcePath + @"/notify-icon.icns"));
        sItem.HighlightMode = true;

        // Remove the system tray icon from upper-right hand corner of the screen
        // (works without adjusting the LSUIElement setting in Info.plist)
        NSApplication.SharedApplication.ActivationPolicy = 
            NSApplicationActivationPolicy.Accessory;

        // Start running the program -- If I comment out then no dock icon appears
        currentServiceObject = new MyServiceObject();
    }
}
2 Answers
Related