NSOpenglView appears in front of NSView after deminimize window - macos

I have a NSView displayed over a NSOpenGLView. I am using the 'setWantsLayer:YES' to force the NSView to appear over the opengl context. But when I minimize the window and deminimize it again, the NSView is no more over the NSOpenGLView.
Is there a way to prevent this behaviour?

Ok, I have found a solution for this issue. Is not maybe the best, but solves the issue.
First, I have declared a notifier in my appDelegate class:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(windowDidDeminiaturize:)
name:NSWindowDidDeminiaturizeNotification object:nil];
This notifier detects the window deminimization event. Then, in the callback function, I do this:
- (void)windowDidDeminiaturize:(NSNotification *)notification
{
[view_PlaybackView setWantsLayer:NO];
[view_PlaybackView setWantsLayer:YES];
}
And the view is again shown in front of the NSOpenGLView.

Related

Check if there are nspopover opened before creating new one

I have in my code some functionality to open a popover anytime an event happens. Problem is that if those events happen one after the other the popovers opened are overlapped.
I would like to close one popover when opening new one.
Is there any way to get from nswindow if there is an active popover?
Thanks in advance and regards
I think you need play with NSPopover's notification methods such as:
- (void)popoverDidShow:(NSNotification *)notification;
- (void)popoverWillClose:(NSNotification *)notification;
And add some logic which will hide not closed popover...
Finally I was able to figure it out by using notifications posted:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(popoverWillShow:)
name:NSPopoverWillShowNotification
object:nil];
And then in the selector I compare the objects: (popover is an NSPopover)
- (void)popoverWillShow:(NSNotification *)notification {
if (![popover isEqual:[notification object]])
[self close];
}

Warning: Attempted to present * whose not in the window hierarchy

I have tried to deal with this issue for too long. Please give me any of your thoughts.
I am presenting a View Controller from an SKScene by sending a Local Notification. [[NSNotificationCenter defaultCenter] postNotificationName:#"closeScene" object:nil];
The notification is handled in the beginning view controller.
- (void)viewDidLoad{ [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closeScene) name:#"closeScene" object:Nil];
[super viewDidLoad];}
Then:
-(void)closeScene {
//Remove the SKView, or present another viewController here.
constructionViewController *view = [[constructionViewController alloc] init];
[self presentViewController:view animated:YES completion:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"closeScene" object:nil];
}
And every time the notification is sent, I get the warning:
Warning: Attempt to present <constructinoViewController: 0x10ae64160> on <constructinoViewController: 0x10ab329d0> whose view is not in the window hierarchy!
Any help would more than appreciated. Thank you in advance!
When is closeScene called, exactly - before or after viewDidAppear gets called?
The error you're seeing usually happens when you try to present a view controller before the parent is actually displayed on screen. Typically this is because you've called presentViewController before the parent's viewDidAppear method has been called.
Try adding a logging statement to viewDidAppear and see whether it appears in the logs before or after your 'view is not in the window hierarchy' error. If it appears after you'll know what the problem is, and how to fix it (make sure presentViewController is only called after the parent view controller has been displayed). If it's before you probably have an altogether different problem...

Forcing a delegate method to be called

I have a delegate method of an NSSplitView like this:
- (void)splitViewWillResizeSubviews:(NSNotification *)aNotification
{
NSLog(#"RESIZE!");
}
This method is called whenever I drag a divider, so it registered properly. I would like to call this from another object, and was thinking to use this:
[[NSNotificationCenter defaultCenter] postNotificationName:NSSplitViewWillResizeSubviewsNotification object:self];
According to the Apple docs, this is the notification that should be sent to call the delegate method. However, it does not work. Does anyone have an idea what I am doing wrong?
You can just invoke the method manually
NSSplitView * yourSplitView; //Get reference to your splitview
id yourSplitViewDelegate = [yourSplitView delegate];
[yourSplitViewDelegate splitViewWillResizeSubviews:nil];//Optionally create the NSNotification with relevant data
If you really want to go through notification center, make sure self in your question is the NSSplitView.
NSSplitView * yourSplitView; //Get reference to your splitview
[[NSNotificationCenter defaultCenter] postNotificationName:NSSplitViewWillResizeSubviewsNotification object:yourSplitView];
Turns out that I needed to manually register the delegate class for the NSSplitViewWillResizeSubviewsNotification notifications!
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(splitViewWillResizeSubviews:)
name:NSSplitViewWillResizeSubviewsNotification
object:vc];
where vc is the viewcontroller that should be sending the notifications.
This is unexpected behavior (to me), since an <NSSplitViewDelegate> is expected to register automatically for NSSplitView... notifications.

cancelOperation not called in NSView subclass

cancelOperation: is not being called in my bare-bones NSView subclass when I press Esc.
I checked and the Esc key is received on keyDown. Also, other action messages (such as moveLeft) are being called.
The view is part of a Window shown like this:
[self.window addChildWindow:wc.window ordered:NSWindowAbove];
[wc.window makeKeyAndOrderFront:self];
What am I doing wrong?
In my case, I have an app with a couple of NSWindows. I had to call
[self.window makeFirstResponder:self] in my NSView subclass to have the view respond to cancelOperation:.
Are you implementing it as cancelOperation or cancelOperation:? There's a big difference. The method signature should be:
- (void)cancelOperation:(id)sender
This works for me with a vanilla NSView.
My derived NSView had the same problem. It was resolved after implementing acceptsFirstResponder as follows:
- (BOOL)acceptsFirstResponder
{
return YES;
}

NSWindowDidBecomeMainNotification firing for ALL windows

I have an app with two windows - a main window, and a preferences window which can be opened from the menubar. I am trying to implement a notification that the preferences window becomes the main window so that I can update it when it is opened, however my notificaton is firing whenever any window opens, even a different window.
inside my PrefsWindowViewController.m awakeFromNib I have:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didBecomeMain:)
name:NSWindowDidBecomeMainNotification
object:nil];
And in my PrefsWindowViewController.m dealloc, I have:
[[NSNotificationCenter defaultCenter] removeObserver:self name: NSWindowDidBecomeMainNotification object:nil];
Can anybody explain why this might get called when a different window besides my PrefsWindow becomes the main window?
It's because you're passing nil for the object: parameter. Pass your preferences window instead, or check [notification object] == yourPrefsWindow in your callback.

Resources