Q: I have an instance of an NSOpenGLView subclass that doesn't draw correctly after I close and then re-open its window. What's happening, and how can I fix it?A: In Mac OS X, version 10.3 and earlier, NSOpenGLView doesn't redraw properly after the window it's in has been closed and re-opened. One easy work-around is to remove the view from the view hierarchy, and then re-insert it. In the code below, MyOpenGLView registers itself for the notification that its window will close. In the -prepareForWindowClosing: method, the view also registers itself for the NSWindowDidUpdateNotification, which will be sent when the window is re-opened. The -windowReopened: method retains the view, removes it from the view hierarchy, then re-inserts it and balances the -retain message with a -release message. Listing 1: Resetting NSOpenGLView's drawing environment
@implementation MyOpenGLView
- (void) awakeFromNib
{
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(prepareForWindowClosing:)
name: NSWindowWillCloseNotification
object: [self window]];
}
- (void) prepareForWindowClosing:(NSNotification *) notification
{
// we'll need to know the next time the window updates,
// which will be when it's re-opened.
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(windowReopened:)
name: NSWindowDidUpdateNotification
object: [self window]];
// Make sure we draw right away when the window is re-opened.
[self setNeedsDisplay:YES];
}
- (void) windowReopened:(NSNotification *)aNotification
{
// Fix up the state of the NSOpenGLView by removing it from and
// re-adding it to the view hierarchy
NSView *superviewStash = [self superview];
[self retain]; // Must retain before removing from superview
[self removeFromSuperview];
[superviewStash addSubview:self];
[self release]; // Must balance all -retain and -release messages.
// After this, we don't care about window exposed notifications, so
// we'll stop listening for them
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:NSWindowDidUpdateNotification
object:[self window]];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@end
Document Revision HistoryDate | Notes |
---|
2004-12-03 | Workaround for NSOpenGLView failure to draw after its window is closed and re-opened. |
Posted: 2004-12-03
|