Started to implement proper destruction logic for Mac OS X controls.

This commit is contained in:
Pietro Gagliardi 2015-04-10 23:22:46 -04:00
parent b982e69fb7
commit 347a254d9f
3 changed files with 18 additions and 3 deletions

View File

@ -40,6 +40,11 @@
@end @end
// we are not in control of the actual lifetimes and refcounts of NSViews (see http://stackoverflow.com/a/29523141/3408572)
// when we're done with a view, it'll be added as a subview of this one, and this one will be released on application shutdown
// we need this separate view because it's possible for controls to have no parent but still be alive
NSView *deletedControlsView;
uiInitOptions options; uiInitOptions options;
const char *uiInit(uiInitOptions *o) const char *uiInit(uiInitOptions *o)
@ -50,6 +55,10 @@ const char *uiInit(uiInitOptions *o)
// see https://github.com/andlabs/ui/issues/6 // see https://github.com/andlabs/ui/issues/6
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp setDelegate:[uiAppDelegate new]]; [NSApp setDelegate:[uiAppDelegate new]];
// we can use a stock NSView for this
deletedControlsView = [[NSView alloc] initWithFrame:NSZeroRect];
return NULL; return NULL;
} }

View File

@ -10,12 +10,11 @@ struct singleView {
uintptr_t parent; uintptr_t parent;
}; };
// TODO this will need to change if we want to provide removal
static void singleDestroy(uiControl *c) static void singleDestroy(uiControl *c)
{ {
singleView *s = (singleView *) (c->internal); singleView *s = (singleView *) (c->internal);
[s->view removeFromSuperview]; [deletedControlsView addSubview:s->immediate];
} }
static uintptr_t singleHandle(uiControl *c) static uintptr_t singleHandle(uiControl *c)
@ -99,6 +98,9 @@ uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHas
s->immediate = (NSView *) (s->scrollView); s->immediate = (NSView *) (s->scrollView);
} }
// and keep a reference to s->immediate for when we remove the control from its parent
[s->immediate retain];
c = uiNew(uiControl); c = uiNew(uiControl);
c->internal = s; c->internal = s;
c->destroy = singleDestroy; c->destroy = singleDestroy;
@ -115,7 +117,8 @@ BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview)
{ {
singleView *s = (singleView *) (c->internal); singleView *s = (singleView *) (c->internal);
if (newSuperview == nil) { if (newSuperview == deletedControlsView) {
[s->immediate release]; // we don't need the reference anymore
uiFree(s); uiFree(s);
uiFree(c); uiFree(c);
return YES; return YES;

View File

@ -24,6 +24,9 @@
fprintf(stderr, "%p free\n", self); \ fprintf(stderr, "%p free\n", self); \
} }
// init_darwin.m
extern NSView *deletedControlsView;
// util_darwin.m // util_darwin.m
extern void setStandardControlFont(NSControl *); extern void setStandardControlFont(NSControl *);
extern void disableAutocorrect(NSTextView *); extern void disableAutocorrect(NSTextView *);