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
|
- data types listed as being defined in nonexistent headers
|
||||||
- 32-bit/64-bit type differences that are more than just a different typedef
|
- 32-bit/64-bit type differences that are more than just a different typedef
|
||||||
- wrong documentation
|
- 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.
|
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 <Foundation/NSGeometry.h>
|
||||||
#include <AppKit/NSKeyValueBinding.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 */
|
/* 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;
|
Class NilClass = Nil;
|
||||||
|
@ -155,3 +157,30 @@ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count)
|
||||||
free(nsuints);
|
free(nsuints);
|
||||||
return ret;
|
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_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_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);
|
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(id_id_id, id, id, id)
|
||||||
m3(sel_id_bool, SEL, id, BOOL)
|
m3(sel_id_bool, SEL, id, BOOL)
|
||||||
|
@ -100,4 +101,7 @@ m4(id_id_id_id, id, id, id, id)
|
||||||
/* for listbox_darwin.go */
|
/* for listbox_darwin.go */
|
||||||
extern uintptr_t *NSIndexSetEntries(id, uintptr_t);
|
extern uintptr_t *NSIndexSetEntries(id, uintptr_t);
|
||||||
|
|
||||||
|
/* for uitask_darwin.go */
|
||||||
|
extern id makeDummyEvent();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,6 +20,8 @@ var (
|
||||||
_valueWithPointer = sel_getUid("valueWithPointer:")
|
_valueWithPointer = sel_getUid("valueWithPointer:")
|
||||||
_performSelectorOnMainThread =
|
_performSelectorOnMainThread =
|
||||||
sel_getUid("performSelectorOnMainThread:withObject:waitUntilDone:")
|
sel_getUid("performSelectorOnMainThread:withObject:waitUntilDone:")
|
||||||
|
_stop = sel_getUid("stop:")
|
||||||
|
_postEventAtStart = sel_getUid("postEvent:atStart:")
|
||||||
_pointerValue = sel_getUid("pointerValue")
|
_pointerValue = sel_getUid("pointerValue")
|
||||||
_run = sel_getUid("run")
|
_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)
|
C.objc_msgSend_noargs(NSApp, _run)
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue