summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redo/dialog_darwin.m6
-rw-r--r--redo/objc_darwin.h2
-rw-r--r--redo/uitask_darwin.m39
3 files changed, 43 insertions, 4 deletions
diff --git a/redo/dialog_darwin.m b/redo/dialog_darwin.m
index 3e662be..0557018 100644
--- a/redo/dialog_darwin.m
+++ b/redo/dialog_darwin.m
@@ -18,11 +18,9 @@ char *openFile(void)
[op setExtensionHidden:NO];
[op setAllowsOtherFileTypes:YES];
[op setTreatsFilePackagesAsDirectories:YES];
- // disable custom events
- // TODO doesn't seem to work
- dispatch_suspend(dispatch_get_main_queue());
+ beginModal();
ret = [op runModal];
- dispatch_resume(dispatch_get_main_queue());
+ endModal();
if (ret != NSFileHandlingPanelOKButton)
return NULL;
// string freed on the Go side
diff --git a/redo/objc_darwin.h b/redo/objc_darwin.h
index 53cb65d..f3b7e70 100644
--- a/redo/objc_darwin.h
+++ b/redo/objc_darwin.h
@@ -41,6 +41,8 @@ extern id getAppDelegate(void); /* used by the other .m files */
extern void uiinit(char **);
extern void uimsgloop(void);
extern void uistop(void);
+extern void beginModal(void);
+extern void endModal(void);
extern void issue(void *);
/* window_darwin.m */
diff --git a/redo/uitask_darwin.m b/redo/uitask_darwin.m
index d802911..9d25a61 100644
--- a/redo/uitask_darwin.m
+++ b/redo/uitask_darwin.m
@@ -129,9 +129,48 @@ void uistop(void)
[NSApp postEvent:e atStart:NO]; // let pending events take priority
}
+// because dispatch_suspend()/dispatch_resume() can't be used with the main queue
+static BOOL inmodal = NO;
+static void **modalqueue = NULL;
+static size_t mqlen = 0;
+static size_t mqcap = 0;
+
+void beginModal(void)
+{
+ inmodal = YES;
+ if (modalqueue == NULL) {
+ mqcap = 128;
+ modalqueue = (void **) malloc(mqcap * sizeof (void *));
+ if (modalqueue == NULL)
+ abort();//TODO
+ mqlen = 0;
+ }
+}
+
+void endModal(void)
+{
+ size_t i;
+
+ inmodal = NO;
+ for (i = 0; i < mqlen; i++)
+ doissue(modalqueue[i]);
+ mqlen = 0;
+}
+
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch and blocks for this
void issue(void *what)
{
+ if (inmodal) {
+ modalqueue[mqlen] = what;
+ mqlen++;
+ if (mqlen >= mqcap) {
+ mqcap *= 2;
+ modalqueue = (void **) realloc(modalqueue, mqcap * sizeof (void *));
+ if (modalqueue == NULL)
+ abort();//TODO
+ }
+ return;
+ }
dispatch_async(dispatch_get_main_queue(), ^{
doissue(what);
});