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

2

7

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.

Foredate answered 30/5, 2010 at 20:5 Comment(1)
Did you ever find a solution for this? Sorry, would have contacted you by email but your site appears to be down.Omnirange
P
1

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.

Phial answered 30/5, 2010 at 20:21 Comment(3)
Tried that as well. Let me see if I can't dig up the code. I can't recall if the problem was that when I overrode -canBecomeMain to return NO, it didn't seem to make any difference whatsoever, or I couldn't input text.Foredate
Also, tried NSPanel, no such luck. Again, let me see if I can't dig up the code. Had to back it up/scrap it for code review/check-inForedate
After digging up the code, have added to what I've tried. It allows the text input with -canBecomeMain returning NO, but it still simply makes the main window inactive. Its a webkit view in the child window... I wonder if webview is once again throwing a turd in the punchbowl here.Foredate
T
-1

I think this can help you: [self.childWindow makeKeyAndOrderFront:self];

Terrence answered 23/3, 2012 at 6:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.