Often, showing a simple menu in your status bar application is not sufficient enough. This short tutorial explains how you can show your own window right below of your status item. Inspired was this blog post by the following question on StackOverflow.
- For the basic setup of your status bar application you should have a look at our previous blog post How to create a Mac OS X status bar application.
- Instead of adding a NSMenu control to the status item, we want to call our own action. Therefore we set the target and action property of NSStatusItem . In this case the target will be the app delegate itself.
// Code for creating status item ... // Setting target and action [self.statusItem setTarget:self]; [self.statusItem setAction:@selector(statusItemAction:)];
- Now add your custom action method statusItemAction: to your app delegate.
- (void) statusItemAction:(id) sender { }
- Prepare the window you want to show below your status item. The best way to do this is to create a new NSWindowController subclass including a xib file. Customize your window as you like and add a new propertyto your app delegate for your window controller.
@property(strong, nonatomic) StatusWindowController *windowController;
- The next things I will summarize up a little bit. You need to get the frame of your status item, create your window controller, get the window reference, calculate the window position and finally displaying the window. This is shown in the following code snippet of the statusItemAction: method.
- (void) statusItemAction:(id) sender { // Get the frame and origin of the control of the current event // (= our NSStatusItem) CGRect eventFrame = [[[NSApp currentEvent] window] frame]; CGPoint eventOrigin = eventFrame.origin; CGSize eventSize = eventFrame.size; // Create a window controller from your xib file // and get the window reference if(self.windowController == nil) self.windowController = [[StatusWindowController alloc] initWithWindowNibName:@"StatusWindow"]; NSWindow *window = [self.windowController window]; // Calculate the position of the window to // place it centered below of the status item CGRect windowFrame = window.frame; CGSize windowSize = windowFrame.size; CGPoint windowTopLeftPosition = CGPointMake(eventOrigin.x + eventSize.width/2.f - windowSize.width/2.f, eventOrigin.y - 20); // Set position of the window and display it [window setFrameTopLeftPoint:windowTopLeftPosition]; [window makeKeyAndOrderFront:self]; // Show your window in front of all other apps [NSApp activateIgnoringOtherApps:YES]; }
That’s it. Run your application and click the status item. The window should appear right below and centered to your status item.
Leave a Reply