Show NSWindow as dropdown from NSStatusItem? - objective-c

How can I show an NSWindow when clicking on an NSStatusItem, such that it shows over other applications when appearing, but without causing them to lose active status?
I have seen MAAttachedWindow, and it is neat but it does not show on top of other applications unless its own application is active.

I would check out this excellent tutorial and sample project:
Cocoa Popup window in the Status bar
That example shows how to "attach" a window to a status bar item, but you could position the window wherever you want. Basically, if you define your app as a LSUIElement you can display floating utility windows despite your app never activating or showing a dock icon, and other apps still remain key.

if you use MAAttachedWindow, you can set the winow level as NSStatusWindowLevel. Then it will show on top of other application.

Related

Detect if menu bar is hidden or visible

Is there a way in Cocoa to receive a notification (or something similar) when the menu bar becomes hidden or visible? I tried looking around and have not found any information on this topic.
Thanks
I solved this by using Carbon's menu event handlers.
I registered for events kEventMenuBarHidden and kEventMenuBarShown under the class kEventClassMenu.
Optionally watch out for (Cocoa) notifications for an object of class NSStatusBarWindow and notifications like
NSWindowDidChangeOcclusionStateNotification
NSWindowWillCloseNotification
to get notified when the menu bar showing or hiding.
If you only need the current state of the menu bar, another approach is to use the visibleFrame property of NSScreen:
The returned rectangle is always based on the current user-interface settings and does not include the area currently occupied by the dock and menu bar.
However, this won't be sufficient by itself if you need to be notified of menu bar visibility changes.
I believe the correct approach to this is to use Key-Value Observing (KVO) to observe the presentationOptions or currentSystemPresentationOptions property of the application object (NSApp or [NSApplication sharedApplication]). When that changes, check its value to see if it includes NSApplicationPresentationHideMenuBar or NSApplicationPresentationAutoHideMenuBar. If it does, then the menu is hidden (or hides when the cursor is not near the top of the main screen.
The difference between presentationOptions and currentSystemPresentationOptions is whether you're interested in whether the calling app has hidden its menu bar or whether the active app (which may be another app) has hidden its menu bar. The latter indicates whether the user can see any menu bar.

How to create a NSWindow like iTunes mini player (always on top but get no focus!)

I have a borderless window with a webview in it, which is always on top.
I want to create a NSWindow which is:
Always on top
Does not take the focus from the current foreground app
Does enable user mouse interaction (without forcing the user to switch focus to it - aka "click on it twice")
The problem I have atm is that to interact with the window (e.g. see hover effect, or click a link in the webview), the user has to click the window (which gives it focus) and only then the hover effect shows.
How can I make a window like iTunes mini player which doesn't take the focus from the current app - but also interacts with mouse? (see screenshots below)
Thanks!!
To receive mouseEntered:, mouseMoved: and mouseExited: events even when your app is not active, you must add a tracking area to some view in your window and set the tracking area's properties accordingly.
Take a look at NSTrackingArea.
You'll probably want to add a tracking area with the options NSTrackingActiveAlways and NSTrackingMouseEnteredAndExited.

Re-create Cocoa application menubar

I'm making a statusbar application and load a new xib containing the main window for the application when clicking on a statusbar menu item. However, in the process I deleted the application menu bar. I don't see a way to hook up the NSMenu object I created in the interface builder.
The window loads just fine, and the status bar icon is still present, but when I make the main window the key window, the application menu bar doesn't change, it just shows the previous app that was active.
I have followed the instructions/suggestions here and here, but neither of them work. Is there some other step I've missed?
Thanks!
The behavior you're describing is normal for background applications. If you don't have an icon in the Dock, you don't get your own menubar, even if you have a window in the foreground.

Cocoa Application with Menubar but no Dock Icon / switch menu

This is yet one more of those "how to switch from running with a dock icon to running without one" questions with a twist.. I don't want the dock icon but I do want a menu bar when the application is at the front. Is that possible?
Running an application with LSUIElement set to 1 in the plist will launch the application without a dock icon, not showing up in the command-tab switch list and without a menu.
You can switch from that mode to the "normal" mode with all three switched on via SetSystemModeUI from 10.2 onwards and via NSApplication setApplicationActivationPolicy since 10.6, but crucially there is no way back to the previous mode (go figure).
So one way around this would be to launch with LSUIElement = 1 and then activate the menu bar when the application gets the focus and deactivate it on the application losing the focus.. alas I can't find a way of doing that.
Can anybody help?
Best regards,
Frank
I too was looking for a solution, but it turned out to be quite simple:
In the project file Info.plist need to add the key
"Application is agent (UIElement)" = YES
Unfortunately, this is not possible. You can only transform the process type in one direction (from a background app to a foreground app) and not the other way.

NSBorderlessWindowMask Window wont show NSPanels if not front most window

I have a window that is set with NSBorderlessWindowMask, and also kCGDesktopWindowLevel. When a NSPanel is supposed to appear from say the selection of a Dock Icon menu or a Status Bar Item menu, the NSPanel will not display if the application is not the front most window.
So this program at this time only has a Status Menu Item (think how QuickSilver is implemented) and when I choose Preferences from my menu it is set to show the Preferences Panel by using Makekeyandorderfront, however unless you have just launched the application and done nothing else, when you select Preferences nothing happens.
I have found that when I choose my menu item for Sparkle's Check for Updates, that the check for update panel will appear and then my preference panel which I told to open will appear.
So it seems like makekeyandorderfront is not really bringing it to the front, perhaps.
Does anyone know how to fix this?
Should I call something besides makekeyandorderfront, or maybe something in conjunction with it?
Thanks in advance
Panels are designed by default to work this way. They're designed as auxiliary windows for your application and always disappear when the application deactivates. You will probably also run into issues with the panel becoming key... but to cure your disappearing panel issue, send this message to your panel:
[panelObject setHidesOnDeactivate:NO];
You should probably be using actual NSWindow objects here instead of NSPanel objects, but since I don't know much about how your application works, you'll have to look into that yourself. For more information on the difference between panels and windows, please review the documentation here: Window Programming Guide