summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--new/init_darwin.m9
-rw-r--r--new/newcontrol_darwin.m9
-rw-r--r--new/uipriv_darwin.h3
3 files changed, 18 insertions, 3 deletions
diff --git a/new/init_darwin.m b/new/init_darwin.m
index c7be20d..b1d88c3 100644
--- a/new/init_darwin.m
+++ b/new/init_darwin.m
@@ -40,6 +40,11 @@
@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;
const char *uiInit(uiInitOptions *o)
@@ -50,6 +55,10 @@ const char *uiInit(uiInitOptions *o)
// see https://github.com/andlabs/ui/issues/6
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp setDelegate:[uiAppDelegate new]];
+
+ // we can use a stock NSView for this
+ deletedControlsView = [[NSView alloc] initWithFrame:NSZeroRect];
+
return NULL;
}
diff --git a/new/newcontrol_darwin.m b/new/newcontrol_darwin.m
index f53ef58..1fff8a8 100644
--- a/new/newcontrol_darwin.m
+++ b/new/newcontrol_darwin.m
@@ -10,12 +10,11 @@ struct singleView {
uintptr_t parent;
};
-// TODO this will need to change if we want to provide removal
static void singleDestroy(uiControl *c)
{
singleView *s = (singleView *) (c->internal);
- [s->view removeFromSuperview];
+ [deletedControlsView addSubview:s->immediate];
}
static uintptr_t singleHandle(uiControl *c)
@@ -99,6 +98,9 @@ uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHas
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->internal = s;
c->destroy = singleDestroy;
@@ -115,7 +117,8 @@ BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview)
{
singleView *s = (singleView *) (c->internal);
- if (newSuperview == nil) {
+ if (newSuperview == deletedControlsView) {
+ [s->immediate release]; // we don't need the reference anymore
uiFree(s);
uiFree(c);
return YES;
diff --git a/new/uipriv_darwin.h b/new/uipriv_darwin.h
index 057af1d..e34b825 100644
--- a/new/uipriv_darwin.h
+++ b/new/uipriv_darwin.h
@@ -24,6 +24,9 @@
fprintf(stderr, "%p free\n", self); \
}
+// init_darwin.m
+extern NSView *deletedControlsView;
+
// util_darwin.m
extern void setStandardControlFont(NSControl *);
extern void disableAutocorrect(NSTextView *);