diff --git a/darwin/newcontrol.m b/darwin/newcontrol.m index bb08322f..12c9b08b 100644 --- a/darwin/newcontrol.m +++ b/darwin/newcontrol.m @@ -21,12 +21,12 @@ static void singleDestroy(uiControl *c) singleView *s = (singleView *) (c->Internal); [s->immediate retain]; // to keep alive when removing + (*(s->onDestroy))(s->onDestroyData); if (s->parent != NULL) { [s->immediate removeFromSuperview]; s->parent = NULL; } [destroyedControlsView addSubview:s->immediate]; - (*(s->onDestroy))(s->onDestroyData); [s->immediate release]; } diff --git a/darwin/parent.m b/darwin/parent.m index 35741daa..e9bae315 100644 --- a/darwin/parent.m +++ b/darwin/parent.m @@ -8,6 +8,7 @@ intmax_t marginRight; intmax_t marginBottom; } +- (void)uipDestroyMainControl; - (void)uipSetMainControl:(uiControl *)mainControl parent:(uiParent *)p; - (void)uipSetMarginLeft:(intmax_t)left top:(intmax_t)top right:(intmax_t)right bottom:(intmax_t)bottom; - (void)uipUpdate; @@ -17,24 +18,20 @@ uiLogObjCClassAllocations -- (void)viewDidMoveToSuperview -{ - // we can't just use nil because NSTabView will set page views to nil when they're tabbed away - // this means that we have to explicitly move them to the destroyed controls view when we're done with them, and likewise in NSWindow - if ([self superview] == destroyedControlsView) - if (self->mainControl != NULL) { - uiControlDestroy(self->mainControl); - self->mainControl = NULL; - } - [super viewDidMoveToSuperview]; -} - - (void)setFrameSize:(NSSize)s { [super setFrameSize:s]; [self uipUpdate]; } +- (void)uipDestroyMainControl +{ + if (self->mainControl != NULL) { + uiControlDestroy(self->mainControl); + self->mainControl = NULL; + } +} + - (void)uipSetMainControl:(uiControl *)mainControl parent:(uiParent *)p { if (self->mainControl != NULL) @@ -82,6 +79,7 @@ static void parentDestroy(uiParent *pp) uipParent *p = (uipParent *) (pp->Internal); [p retain]; // to avoid destruction upon removing from superview + [p uipDestroyMainControl]; [p removeFromSuperview]; [destroyedControlsView addSubview:p]; [p release]; diff --git a/darwin/window.m b/darwin/window.m index 94d2dbb5..8bfea308 100644 --- a/darwin/window.m +++ b/darwin/window.m @@ -29,13 +29,14 @@ uiLogObjCClassAllocations { [self.w setDelegate:nil]; // see http://stackoverflow.com/a/29523141/3408572 - // when we reach this point, we need to ensure that all the window's children are destroyed (for OS parity) - // because we need to set the content view's superview to the destroyed controls view to trigger deletion, we need to do this manually - // first, replace the current content view... + // just to be safe [self.w setContentView:[[NSView alloc] initWithFrame:NSZeroRect]]; - // ...then, trigger the deletion - [destroyedControlsView addSubview:((NSView *) uiParentHandle(self.content))]; + uiParentDestroy(self.content); + // now we need to release the window too + [self.w release]; + + // and clean up uiFree(self.uiw); [self release]; } @@ -135,8 +136,8 @@ uiWindow *uiNewWindow(const char *title, int width, int height) // NOTE: if you disagree with me about disabling substitutions, start a github issue with why and I'll be happy to consider it disableAutocorrect((NSTextView *) [d.w fieldEditor:YES forObject:nil]); - // this is what will destroy the window on close - [d.w setReleasedWhenClosed:YES]; + // don't release on close; we'll do it ourselves (see above) + [d.w setReleasedWhenClosed:NO]; d.content = uiNewParent(0); [d.w setContentView:((NSView *) uiParentHandle(d.content))];