I am building a Cocoa Mac application that runs in the background but has a main window.
To make it run in the background I've set "Application is background only" to "YES".
I built a system tray:
If you close the main window, you can re-open it by clicking "open".
I have however some issues with the layering of windows:
When I start the application, the main window opens however it appears in the background, behind any other windows or applications I have open at the time.
Clicking on "open" doesn't bring the window to the foreground. It opens it correctly if it was closed, however it stays behind any windows.
Clicking on preferences or about has the same issue. It opens the correct window but it appears behind any other windows.
On my main window there is a textfield. I can click on it, the cursor blinks as if I am ready to type. But when I type it actually types in some other background window! For example if I have TextWrangler open in the background, it will type there instead of the textfield...
Here is my code for handling the "open":
- (IBAction)show:(id)sender {
[NSApp activateIgnoringOtherApps:YES];
[window makeKeyAndOrderFront:sender];
}
Note that IF I set "Application is background only" to "NO" (which means I have a dock icon appearing), then clicking on "open" brings the window to the foreground as expected. And typing in the textfield works as expected.
Instead of background only, I think you want Application is agent (UIElement) set to YES. Background only is for application not intended to be visible for users.
Background only (LSBackgroundOnly YES) is intended for faceless background applications, Accessory (LSUIElement YES) is intended for background applications with a UI and status menu (menu extra/accessory menu/etc. - the name changes...).
An accessory will not appear in the dock, have a standard menu bar, or appear in the Finder's Force Quit dialog. It can be "active" and can have the key window.
Though it does not have a standard menu bar bizarrely (maybe a bug) if a MainMenu is declared in the XIB then it will respond to key shortcuts when it is active. To avoid this make sure you have no MainMenu or use [NSApp setMainMenu:nil] when you wish to disable the shortcuts.
The whole background/accessory/application/active/etc. area is not exactly well-defined, be prepared for "fun"...
Related
NSWindow which is run as modal(runModalForWindow)from a launch agent which has NSUIElement set to 1( no dock icon or menu bar) is not accessible, Accessibility inspector is not displaying info for this window or button from that window.
We need this window to be accessible to automate it through AXElements,
Can we set some properties of Window or button to make it accessible( as per documentation they should be accessible). Are there any properties that we need to set, since this is launched from an agent without menu bar or dock item.
Thanks,
swetha
The alert was shown from awakeFromNib which was causing issue, after moving the alert display code to applicationDidFinishLaunching, the alert is properly accessible through AXElements.
I have an Objective-C application with a main window and a small progress window with a stack view to show the current progress.
If the application is put in the background by activating any other application and then clicking on the Dock icon, both the Main and secondary windows is brought to the front and shown.
But, if I just click one of the windows when in the background, only that window is activated and brought to the front, the other stays in the back.
I want to implement so that when I click on the main window it does the same thing as clicking on the Dock icon, it should show both windows on top with the Main window activated.
But if I click on the progress window, I don't want the main window to be brought to the front.
I haven't been able to find a way to do this, how should I go about achieving this?
You can detect the window being clicked with the window delegate's -windowDidBecomeKey: or -becomeKeyWindow, or the app delegate's -didBecomeActive:.
Then depending on your exact needs, you can use [NSApp activateIgnoringOtherApps:] or [[NSRunningApplication currentApplication] activateWithOptions:] (and possibly NSApplicationActivateAllWindows).
I've created a simple Cocoa-Application in XCode 4.6 with an NSPanel instead of the default NSWindow. When I enable the Non-Activating
option and start the application everything works fine:
The panel is displayed in front of everything else and when
the mouse cursor hovers over the panel's edges it changes from a normal
arrow-cursor to the appropriate resize-cursor, so the user knows that he can resize
the panel.
This works fine as longs as I don't click on any other application
as for example Safari or Finder.
From the moment I once give focus to another application,
I can click on and hover over my panel as much as I want, the
cursor style will not change anymore - it always stays an arrow and it's not possible to return to the normal behavior.
The panel stays selectable and in the front, you still can move and resize it,
but the mouse cursor stays an arrow all the time. You then cannot even change it
manually using something like: [[NSCursor crosshairCursor] set].
So I need to find a way to create a NSPanel that keeps the normal
automatic-change-cursorstyle-when-hovering-over-panel-edges-behaviour
even when you give focus to another application.
I have already tried to use an customized NSPanel-class,
where I have overwritten the canBecomeKeyWindow and
canBecomeMainWindow methods, so that they return YES
but even when I make my Panel KeyWindow and MainWindow...
[myPanel makeKeyAndOrderFront:self];
[myPanel makeMainWindow];
...it doesn't solve the cursor issue.
Would be great if someone could help me here :)
PS.: the Base SDK and the Deployment Target are set to 10.8 in my project
So I found out that the described issue has nothing to to with the panel's window-state. It really doesn't matter if it is set to key or to main, instead the cursor-problem (stays arrow all the time)is related to the application's activation state.
Everything works fine as long as the application that owns the panel is active but if you click on another application my application is deactivated and does not get activated again - even if you click on the panel - because the "non-activating"-option is enabled.
The problem is that i need the "non activating"-option because I am creating a status-bar-screen-capturing app that should be displayed and operate in front of everything else but without deactivating any running application. I could solve the cursor problem by
[NSApp activateIgnoringOtherApps];
but then taking a screenshot of a fullscreen video running in Safari would deactivate Safari and minimize the video, which I don't want.
I don’t think it’s possible through normal APIs to change the cursor when your app isn’t active. I’m pretty sure the window system doesn’t allow it: it’d be a violation of the boundaries between apps—if you try to set a cursor from the background, and the foreground app also tries to set a cursor, who would win?
Of course the system can do it (like when you take a screenshot with ⌘⇧4), because that’s in the window system itself.
I have a custom NSPanel: http://cl.ly/K8SY
I have it set to NSPopUpMenuWindowLevel, the level at which I want it to stay as. An example is the spotlight menu, when you click on it any other focus in the windows in the background remains yet you can still type into the search field.
I open it with:
[window orderFront:nil]
but this doesn't focus on the window as well as the background.
Is it possible to achieve this? If so, how?
You need to use the -[NSWindow makeKeyAndOrderFront:] call instead.
NOTE: keyboard focus can only be directed at one view in one window. Cocoa's notion of mainWindow and keyWindow can be different windows, but its only the first responder within the keyWindow that accepts keyboard input.
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.