Making NSBordlessWindow key and active when main application window is not active - osx-mavericks

I have a custom NSBorderlessWindowMask window in my application that I show when user taps a certain hot key.
This window has a `NSTextField, that has to become first responder when the window shows up.
This window is not a main window, but it can take focus from the main window.
This what I do to show it and make it key:
[self.myCustomWindow makeKeyAndOrderFront:sender];
and then to set the first responder
[self.myTextField becomeFirstResponder];
Everything works as expected when the application is a frontmost application,
but if it's not, the window appears, but doesn't become key and i have to click it to become active.
I override in my CustomWindow class:
- (BOOL)canBecomeKeyWindow {
return YES;
}
What might be the problem?
Thanks!

According to the Cocoa Event Handling Guide, only the frontmost application can have main and key window status:
When an application is displaying both a main window and a key window,
the responder chains of both windows can be involved in an action
message. As explained in “Window Layering and Types of Windows”, the
main window is the frontmost document or application window. Often
main windows also have key status, meaning they are the current focus
of user input. But a main window can have a secondary window or panel
associated with it, such as the Find panel or a Info window showing
details of a selection in the document window. When this secondary
window is the focus of user input, then it is the key window.
I don't see any way around this.
EDIT: Also from the Window Programming Guide:
Since the key window belongs to the active application, its
highlighted title bar has the secondary effect of helping to show
which application is currently active. The key window is the most
prominently marked window in the active application, making it “key”
in a second sense: it’s the main focus of the user’s attention on the
screen.

Related

Pushing a window into focus

I'm developing a small menubar application and I want to display the settings window when the corresponding NSMenuItem is pressed.
I currently have the following IBAction assigned to the menu item:
#IBAction func settingsButtonPressed(sender: NSMenuItem) {
settingsView.makeKeyAndOrderFront(sender)
}
This displays the window, but doesn't push it into focus, so it's displayed behind the currently active window, which is not the behaviour I'm looking for.
I had a suspicion that this might have been due to the fact that the Application is agent target property is set to YES, but this actually has no effect on the outcome.
Could there be anything to be done with the window in the XIB file?
Probably your app is not the active app. It should work to call [NSApp activateIgnoringOtherApps:YES] in addition to making the window key and ordering it front.

Return focus to previous app's window after makeKeyAndOrderFront

I have a status bar menu app - it doesn't run in the Dock (UIElement is YES).
After a user-defined period, it brings one of its window to the front (using makeKeyAndOrderFront). An NSTimer is set up to get rid of it after a few seconds - I close the window and hide the app with:
[NSApp hide];
My question is, how can I bring the previous app's window back to the front? It's visible but not the front/focus window.
EDIT: If it helps to clarify what I'm trying to do, when you invoke the application Dash with the keyboard shortcut and then dismiss it, the app that was previously front, returns to the front.
I was overthinking - as a user, it's possible to hide an app, which automatically restores focus to the window in the app next in line. That's all I had to do in code:
[NSApp hide:nil];
To play nicely with full-screen apps, I also have to close the window in my app, even though it's been hidden - otherwise, when my app's window is next shown, OS X jumps to the Space where my window was last seen, a jarring experience.
[self.theWindow close];

NSWindow, how not to be part of a screenshot?

My Cocoa app displays a transparent window on the screen, but when the user tries to take a screenshot using Mac OS X's built-in screen capture key with the option of selecting full windows (Command-Shift-4, then Space Bar), my window gets highlighted as part of the possible windows to capture.
How can I tell my Window or App not to allow this? My Window already refuses to be the Main Window or Key Window through -canBecomeKeyWindow and -canBecomeMainWindow both returning NO, but this still happens.
The Window is also at the NSModalPanelWindowLevel and NSScreenSaverWindowLevel does the same thing.
Notice that every window is eligible for screenshots, even the desktop, dock and menu bar, which are special windows. You can even take a screenshot of the Exposé overlay window itself. This leads me to believe that there is no way to do this.
I suppose you could hook the Command+Shift+4 key event and hide the window, but that key combo is user-definable, so it is subject to change.

Accept mouse clicks without activating the application?

I am working on a utility application that controls other running applications. On certain input event my application displays a window, user can pick some operation from the window, the window disappears and control returns to the previous app. My problem is that clicking in my app’s window activates my application, thus removing focus from the previous application’s window. I can re-activate the previous application when my window closes, but I’d rather keep the original application activated all the time. Is that possible?
It's quite easy to to, just make your window an instance of NSPanel (a subclass of NSWindow), and set it as non-activating in Xcode/IB (or create it programatically, with NSNonactivatingPanelMask in the style mask).
One idea would be: while your app is running, try to keept track of the active window in the system.
After you activate your app and click the command button, restore the previous active window.
This is only an idea, I don't know how to do it on mac.

NSWindow delegate (windowShouldClose)

In one of my first Cocoa applications I have just a single window with 2 NSTextField instances - for user text input and of output of text processing.
If my user clicks on the red x on the top left, the window closes but the application is still running and icon stays in the dock - the normal Mac behavior.
When the user double-clicks on the icon in dock or on the desktop, this does not reopen the window - apparently also normal Mac behavior, but confusing to the user.
To get the app back into a running state, the user has to force Quit from the main menu or the context menu, and restart the app by clicking on one of the icons.
I searched Apple doc and forums, and it seemed that the following should prevent the closing of the window (my first preference : hide the widow so it can be reopened later) :
add a delegate to NSApp
delegate implements -applicationShouldHandleReopen which calls [mainWindow makeKeyAndOrderFront:self]; and returns TRUE
delegate implements -windowShouldClose which returns FALSE
However, although -windowShouldClose is called, the window closes.
What am I missing here?
As an alternative (my second preference), I added to the delegate
-applicationShouldTerminateAfterLastWindowClosed which returns YES
This works, i.e. the application closes when the used clicks on the red x,
and the user can restart the app later without further ado.
Clarifications and pointers to specific doc and working code examples would be appreciated.
Rudi
"When the user double-clicks on the icon in dock or on the desktop, this does not reopen the window - apparently also normal Mac behavior, but confusing to the user."
If you want the window to re-open in that case, implement applicationShouldHandleReopen:hasVisibleWindows:. There's nothing un-Mac-like about opening a window when the user clicks the dock icon after closing all the windows; lots of apps do it and the delegate exists specifically to support that behavior.
First of all, your "alternative" behavior of terminating the app on window close is probably the preferred approach for your situation. Users may be confused when they can't close the window.
If you really want to prevent the window from being closed, why not just disable the close control on the window in IB?

Resources