Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa/Objective-C - Child window with text input without main window becoming inactive

I have a need to spawn a window that will hover just above my main window in a cocoa application. I want this main window to allow the user to enter some text in an input box. All is well until the text input box actually gains focus. The main window becomes "deactivated." This window is borderless and is a slightly custom shape -- its more like a hover card than anything else, I suppose.

Basically, I'd like this thing to work almost exactly like Spotlight (Apple + Space) -- you can enter text, but this is such an an ancillary operation that in the context of the greater UX, you don't want the jarring effect of the main window graying out (becoming inactive). You'll notice when you have some application open and in-focus, spotlight will not cause the window of that application to become inactive.

This problem arises because text input seems to REQUIRE that the child window become the key window (it will not let you place the cursor in the text input field). When it becomes key, the main window becomes inactive.

So far I've tried:

  • Subclassing NSWindow for my main application and overriding isKeyWindow such that it only loses key when the application is no longer the users focus (as opposed to the window). This had the unintended effect of colliding with key status of the child window and having very strange effects on the keyboard input (some keys are not captured, like delete)
  • Creating a view instead of a window. Doesn't work because of this problem -- you cannot draw over a Webkit WebView these days.

Anybody Cocoa/OSX wizards have any ideas? I've become a little obsessed with this one. An itch I can't scratch.

Edit: have also tried overriding the following on the child window. When clicked, the window makes the main application window become inactive.

- (BOOL)canBecomeKeyWindow {
    return YES;
}

- (BOOL)canBecomeMainWindow {
    return NO;
}

Edit 2: After screwing about with NSMenu for a while, I scrapped that approach. It seems I found something, however. In NSPanel there is a window style mask called:

NSNonactivatingPanelMask
The panel can receive keyboard input without activating the owning application.
Valid only for an instance of NSPanel or its subclasses; not valid for a window.

Trying this out now...

Edit 3: NSNonactivatingPanelMask did not do the trick. No ideas.

like image 721
Josh Avatar asked May 30 '10 20:05

Josh


1 Answers

What you want is a window that can become the key window but which cannot become the main window. You could implement such a class yourself, but this is basically what NSPanel is for, so you might try that first.

like image 61
Chuck Avatar answered Sep 20 '22 14:09

Chuck