Allow views in childWindow to become key without losing focus on parentWindow
Asked Answered
A

1

7

I added a childWindow of a custom subclass of NSWindow to a parentWindow (also a custom subclass of NSWindow). The childWindow has the NSBorderlessWindowMask and canBecomeKeyWindow: is overridden to return YES and canBecomeMainWindow: to return NO.

The childWindow is set to resize with the parentWindow. So I want to create the illusion that the views of the childWindow are part of the parentWindow. The main idea is to arrange the document windows created by the document-based application within a main window to provide a tabbed interface (just like in a browser) to switch between the documents.

My problem is that whenever I click in one of the views of the childWindow, the parentWindow (the main window) looses focus and the traffic light buttons are getting greyed out. This is obviously contrary to what I want to achieve.

I found this answer: Make NSView in NSPanel first responder without key window status

But even if I override isKeyWindow: (of the main window) to always return YES, the title bar gets greyed out nonetheless when I click into the childWindow.

I also tried to follow this advice: http://www.cocoabuilder.com/archive/cocoa/143945-non-focused-child-window.html

But I'm not sure what "include the child window in its responder chain just ahead of its nextResponder" means. With canBecomeKeyWindow: to return NO (for the childWindow), the views within the child never can become key and are always greyed out.

Any clue what I am doing wrong?

One addition: Is it possible to make the views in the childWindow FirstResponder without giving the childWindow key-status?

Adaptive answered 19/11, 2012 at 11:22 Comment(9)
Is there a reason you're not simply using a tab view (with the tabs turned off, if you'd rather use a custom tab-switcher view) to switch amongst the different views?Weatherley
@PeterHosey: Yes, the document-based application creates windows for each document. It would be extremely difficult to hack the document-based application architecture to make it produce views for each open document. The effort would essentially mean to completely rewrite the document architecture. I would like to avoid that, because it will be error-prone and I would have to implement all the features coming with future OS X versions myself. I guess it would not be worth the effort. But at the same time I think that a tabbed-based application is a good approach for my program.Adaptive
You could override makeWindowControllers to make a view controller and add its view to the nearest existing window (if there is one) instead.Weatherley
@PeterHosey: It is more than that. The whole document architecture expects windows. If I just override makeWindowController, a whole lot of features will break. This can be read in several answers on questions on how to make a single-window-based document application. I really thought the answer by Abhi Beckert for this question would be useful. But I failed so far. I just can't make views key while their corresponding window isn't. Just passing on events is not enough.Adaptive
I'm currently playing with this myself. It looks like what will work is to have the document window borderless with canBecomeKeyWindow:YES and canBecomeMainWindow:NO. The add it as a child window to the parent, and observe resize events to keep them in sync. There's more, I think perhaps isKeyWindow for the parent needs to return YES if the child window is key, but so far it seems to be working.Barbabas
@AbhiBeckert: For me (I'm on 10.8.2), the parent window loses it's key status (or better: it is drawn inactive) once I click into the child window, even if isKeyWindow: is overridden for the parent to always return yes. So you can get focused controls within your child window while maintaining an active parent window?Adaptive
When I played with it the parent window was the main window, and the child window was the key window (and therefore one of it's views would be first responder). The parent window's title bar was drawn as usual for the "main" window that is not "key" (see Text Edit's document window when a view inside NSFontPanel has first responder). That's as far as I've taken it so far.Barbabas
@AbhiBeckert: In text edit, when a view inside NSFontPanel is FirstResponder, the "traffic lights" of the document window are drawn in grey. Are your "traffic lights" remaining colored?Adaptive
No, they don't remain coloured for me. I didn't spend much time looking into how to change that... but I suspect it may be possible. I've decided to use a completely different aproach. See MikeTrent's post at cocoadev.com/wiki/DocumentBasedAppWithOneWindowForAllDocumentsBarbabas
M
2

I got this working by mimicking the behaviour of NSPopover. On investigation I found that a popover (which uses a private NSPanel subclass "_NSPopoverWindow") believed it was the key & main window, even though it is not the window returned from [NSApp keyWindow].

Create your own custom NSPanel subclass, attach it to the parent window, and then override the following methods as so:

- (BOOL)isKeyWindow {
    return YES;
}

- (BOOL)isMainWindow {
    return YES;
}

- (BOOL)canBecomeKeyWindow {
    return YES;
}

- (BOOL)canBecomeMainWindow {
    return YES;
}

- (void)makeKeyWindow {
    [super makeKeyWindow];
    [self.parentWindow makeKeyWindow];
}
- (void)makeMainWindow {
    [super makeMainWindow];
    [self.parentWindow makeMainWindow];
}
- (void)becomeKeyWindow {
    [super becomeKeyWindow];
}

- (void)becomeMainWindow {
    [super becomeMainWindow];
    [self.parentWindow becomeMainWindow];
}

- (void)resignMainWindow {

}
- (void)resignKeyWindow {

}

NSWindow with child window that does not steal its main/key status

Mineralogy answered 10/12, 2018 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.