Have ui.Go() return on main() return on Mac OS X.
This commit is contained in:
parent
011836e94d
commit
d29e1b8710
|
@ -7,6 +7,7 @@ The main culprits are:
|
|||
- data types listed as being defined in nonexistent headers
|
||||
- 32-bit/64-bit type differences that are more than just a different typedef
|
||||
- wrong documentation
|
||||
though this is not always the case.
|
||||
|
||||
Go wrapper functions (bleh_darwin.go) call these directly and take care of stdint.h -> Go type conversions.
|
||||
*/
|
||||
|
@ -17,6 +18,7 @@ Go wrapper functions (bleh_darwin.go) call these directly and take care of stdin
|
|||
|
||||
#include <Foundation/NSGeometry.h>
|
||||
#include <AppKit/NSKeyValueBinding.h>
|
||||
#include <AppKit/NSEvent.h>
|
||||
|
||||
/* exception to the above: cgo doesn't like Nil and delegate_darwin.go has //export so I can't have this there */
|
||||
Class NilClass = Nil;
|
||||
|
@ -155,3 +157,30 @@ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count)
|
|||
free(nsuints);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
See uitask_darwin.go: we need to synthesize a NSEvent so -[NSApplication stop:] will work. We cannot simply init the default NSEvent though (it throws an exception) so we must do it "the right way". This involves a very convoluted initializer; we'll just do it here to keep things clean on the Go side (this will only be run once anyway, on program exit).
|
||||
*/
|
||||
|
||||
static id c_NSEvent;
|
||||
static SEL s_newEvent;
|
||||
static BOOL newEvent_init = NO;
|
||||
|
||||
id makeDummyEvent()
|
||||
{
|
||||
if (newEvent_init == NO) {
|
||||
c_NSEvent = objc_getClass("NSEvent");
|
||||
s_newEvent = sel_getUid("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:");
|
||||
newEvent_init = YES;
|
||||
}
|
||||
return objc_msgSend(c_NSEvent, s_newEvent,
|
||||
(NSUInteger) NSApplicationDefined, /* otherEventWithType: */
|
||||
NSMakePoint(0, 0), /* location: */
|
||||
(NSUInteger) 0, /* modifierFlags: */
|
||||
(double) 0, /* timestamp: */
|
||||
(NSInteger) 0, /* windowNumber: */
|
||||
nil, /* context: */
|
||||
(short) 0, /* subtype: */
|
||||
(NSInteger) 0, /* data1: */
|
||||
(NSInteger) 0); /* data2: */
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ m2(id_id, id, id)
|
|||
extern id _objc_msgSend_rect_bool(id obj, SEL sel, int64_t x, int64_t y, int64_t w, int64_t h, BOOL b);
|
||||
extern id objc_msgSend_id_int(id obj, SEL sel, id a, intptr_t b);
|
||||
extern id objc_msgSend_id_uint(id obj, SEL sel, id a, uintptr_t b);
|
||||
m2(id_bool, id, BOOL)
|
||||
|
||||
m3(id_id_id, id, id, id)
|
||||
m3(sel_id_bool, SEL, id, BOOL)
|
||||
|
@ -100,4 +101,7 @@ m4(id_id_id_id, id, id, id, id)
|
|||
/* for listbox_darwin.go */
|
||||
extern uintptr_t *NSIndexSetEntries(id, uintptr_t);
|
||||
|
||||
/* for uitask_darwin.go */
|
||||
extern id makeDummyEvent();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@ var (
|
|||
_valueWithPointer = sel_getUid("valueWithPointer:")
|
||||
_performSelectorOnMainThread =
|
||||
sel_getUid("performSelectorOnMainThread:withObject:waitUntilDone:")
|
||||
_stop = sel_getUid("stop:")
|
||||
_postEventAtStart = sel_getUid("postEvent:atStart:")
|
||||
_pointerValue = sel_getUid("pointerValue")
|
||||
_run = sel_getUid("run")
|
||||
)
|
||||
|
@ -51,7 +53,20 @@ func ui(main func()) error {
|
|||
}
|
||||
}()
|
||||
|
||||
go main()
|
||||
go func() {
|
||||
main()
|
||||
uitask <- func() {
|
||||
// -[NSApplication stop:] stops the event loop; it won't do a clean termination, but we're not too concerned with that (at least not on the other platforms either so)
|
||||
// we can't call -[NSApplication terminate:] because that will just quit the program, ensuring we never leave ui.Go()
|
||||
C.objc_msgSend_id(NSApp, _stop, NSApp)
|
||||
// simply calling -[NSApplication stop:] is not good enough, as the stop flag is only checked when an event comes in
|
||||
// we have to create a "proper" event; a blank event will just throw an exception
|
||||
C.objc_msgSend_id_bool(NSApp,
|
||||
_postEventAtStart,
|
||||
C.makeDummyEvent(),
|
||||
C.BOOL(C.NO)) // not at start, just in case there are other events pending (TODO is this correct?)
|
||||
}
|
||||
}()
|
||||
|
||||
C.objc_msgSend_noargs(NSApp, _run)
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue