Jay Taylor's notes

back to listing index

iOS and OS X Development: Cocoa Popup window in the Status bar

[web search]
Original source (blog.shpakovski.com)
Tags: programming examples macOS cocoa menu-bar status-bar blog.shpakovski.com
Clipped on: 2020-03-31

Developer or Designer? I have some nice Projects.
Maybe you have apps in the App Store? Try NativeConnect.

July 5, 2011

Cocoa Popup window in the Status bar

My CodeBox app for Mac OS X has got an embedded helper app named CodeBar. It is a small utility resided in the system status bar. In this blog post, I'm going to share an open-source project demonstrating how to implement a custom status icon with a popup window. I hope it will be useful for those who are new to Cocoa and want to make their own utility living in the status bar.

First, we have to allocate a new NSStatusItem to place it into the menu bar. This task is managed by the controller class named MenubarController. To make status item more flexible, we use a custom StatusItemView to display its contents in the menu bar. The demo project provides the simplest implementation that draws a Star icon in that view. You can have even more advanced icon by adding handling of drag & drop or any other feature supported by regular views.

Next, we need a customized window to display it as a popover. In the demo project, this window is a panel managed by the PanelController class. It loads the panel component from NIB and manages its live cycle. Also, it configures popover appearance by removing title bar and standard window background.

Finally, once we have menu bar icon and popover, it is time to connect them. The top level controller class ApplicationDelegate is watching for clicks in the menu bar and passes them to the panel controller. Then, after panel controller is closed, application delegate asks menu bar icon to remove a blue highlight.

Popup project on GitHub has got all source files that you need to build a demo app in Xcode 4.

P. S. In Lion, Apple is adding a new class for popovers like in iOS. So, after OS X 10.7 is released, you would better to rely on native Cocoa classes where it is possible. In other cases, the Popup project should still be usable.

Update: What a shame. It looks like implementation using NSPopover requires a lot of hacks. Please find more information here.

46 comments:

  1. Image (Asset 1/1) alt=
    Great post.

    Reply
  2. @Anonymous Could you please be more specific? What do you mean by “window move”? Thanks.

    Reply
  3. Nice example. But can you tell me please, what does

    void *kContextActivePanel = &kContextActivePanel;

    do?

    Reply
  4. void *kContextActivePanel = &kContextActivePanel is another way to make a unique constant identifier kContextActivePanel for using in the key value observing.

    Something like void *kContextActivePanel = @"ActivePanelContext" would work too.

    Reply
  5. I'm wondering if there's any way you'd update your code to use the new NSPopOver class? (And, ARC/xcode 4.2 would be nice too ;) )

    Reply
    Replies
    1. Maybe someday, when I have time :)

    2. Please do that :) If I try to code this it always won't work :(

    3. Or can you please make a video tutorial?
      I think when you show us how to do that, it's easier to understand what we have to do.

    4. Please update for using ARC.

      Also,

      How can you add text next to the image in the menu bar?

    5. I understand the problem of time, but a step-by-step video tutorial with explanations would be a tremendous help for beginners!

  6. Vadim,

    I test your code, but I notice that when you open the panel, and don't click outside the window (panel), and click in other icon on the menubar, the panel don't close.

    Do you know how to fix this?

    Thanks.

    Reply
    Replies
    1. Thanks for the heads up, I have just fixed it!

    2. Without being annoying, on the first click the panel still does not close if you click on another icon from the menubar.

      After you click out of the menu bar for a first time, it works correctly every time than, but before that ​​the panel remains open, following a screenshot:

      http://img826.imageshack.us/img826/8528/popupx.png

    3. That's because you run the app from Xcode. Try to launch it from Finder.

    4. You are right. I did not know this, thanks.

  7. Please show us how it works

    Reply
  8. I have tried this in my own app, on Lion it all works fine.
    However, there is an error, when the PanelController is calling it's window.
    It seems to be a zombie. I use ARC btw.
    I have no idea why this happens, when I convert the PanelProject right here to ARC, it works flawlessly.
    Can anyone help me out?

    Reply
    Replies
    1. Please create a new issue on the GitHub and describe step-by-step how to reproduce it. Thanks in advance!

  9. Maybe you can advise how to include resize in your "popup" ? I founded solution to set window stylemask to NSResizableWindowMask, but i still can't hide title bar.(

    Reply
    Replies
    1. I believe you cannot use a resizing behavior of a window because it is handled by the theme frame which requires a title bar. Sorry.

    2. i did it) with custom resize rect and mouse event.

    3. Congratulations, it must have been quite a tricky task :)

  10. anonymous june 16: it would be nice if you could share how you did the windows resize.

    Vadim: thanks for sharing a great tutorial.

    Reply
  11. For anyone using MonoMac, I've written a port here: http://dan.clarke.name/2012/08/cocoa-popup-window-in-the-status-bar-monomac-port/

    Many thanks to Vadim for the initial solution!

    Reply
  12. Hey guys, this is an awesome template and I have been using it in two of my projects now!

    Just wanted to know, if i want display the app on left click, and I want to display a menu on right click, what do I do?

    Reply
    Replies
    1. Thanks for the feedback! I would try to override mouseDown: in StatusItemView.m and send different actions depending on the pressed mouse button. Sorry for the late reply :)

  13. Im trying to run it on MAC OS X 10.6 with Xcode 4
    Although it is working fine on MAC OS 10.8 but having problem when I use it on MAC OS X 10.6. It's not running.. ?

    Reply
    Replies
    1. I have no 10.6 installed to test. Could you please be more specific? What kind of problem do you have exactly? Sorry for inconvenience.

  14. Awesome stuff! It's great that you are still maintaining it after 2 years now! Kudos!

    Reply
  15. hi, your project helped me a lot in understanding how things are working!

    I'm trying to understand how to close the panel only by clicking on status bar icon?
    My app opens some "choose file" dialogs, so i have to click each time to reopen the panel..

    hints?

    Reply
  16. This is a great example of exactly what I was looking for. However, there was a question awhile back that asked something I wanted to know also:

    "How can you add text next to the image in the menu bar?"

    Can you please respond to this?

    Thanks!

    Reply
  17. Wasn't sure how to thank you for this, so I bought CodeBox. This can be my first snippet to save, thank you, thank you, thank you :)

    Reply
  18. Its a great code, however can you customize it load webview?

    Reply
  19. Hi Vadim, how did you manage keeping the view acting like a float? I’m talking about the behavior in mission control, where it fades out when you enter mission control. other examples for popups (with NSPopover) all have that bug...
    BTW I'm a fan of codebox and pngcompressor!
    thx a lot for your great work...

    Reply
    Replies
    1. Hi Seb, thanks a lot for your support. I am not sure what you mean by “float”. Maybe Utility window style is what you need? Sorry for the late reply.

  20. This look beatiful! Has it yet - or du you have any plans to rewrite this in Swift?

    Reply
    Replies
    1. Thanks for the feedback!
      No, sorry :) If you ever do this, please let me know, I would add the link to the article.

  21. Really great project!
    Thanks!
    But a few comments in code would be really helpful, to understand everything...

    Reply

Comment as:

Subscribe to: Post Comments (Atom)
Copyright © 2014 Shpakovski. Simple theme. Powered by Blogger.