summaryrefslogtreecommitdiff
path: root/uitask_darwin.go
diff options
context:
space:
mode:
Diffstat (limited to 'uitask_darwin.go')
-rw-r--r--uitask_darwin.go42
1 files changed, 10 insertions, 32 deletions
diff --git a/uitask_darwin.go b/uitask_darwin.go
index 6d044f6..6b886cf 100644
--- a/uitask_darwin.go
+++ b/uitask_darwin.go
@@ -10,6 +10,7 @@ import (
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
// #include "objc_darwin.h"
+// #include "delegateuitask_darwin.h"
import "C"
var uitask chan func()
@@ -32,7 +33,7 @@ func ui(main func()) error {
uitask = make(chan func())
- NSApp, err := initCocoa()
+ err := initCocoa()
if err != nil {
return err
}
@@ -40,36 +41,18 @@ func ui(main func()) error {
// Cocoa must run on the first thread created by the program, so we run our dispatcher on another thread instead
go func() {
for f := range uitask {
- // we need to make an NSAutoreleasePool, otherwise we get leak warnings on stderr
- pool := C.objc_msgSend_noargs(_NSAutoreleasePool, _new)
- fp := C.objc_msgSend_ptr(_NSValue, _valueWithPointer,
- unsafe.Pointer(&f))
- C.objc_msgSend_sel_id_bool(
- appDelegate,
- _performSelectorOnMainThread,
- _uitask,
- fp,
- C.BOOL(C.YES)) // wait so we can properly drain the autorelease pool; on other platforms we wind up waiting anyway (since the main thread can only handle one thing at a time) so
- C.objc_msgSend_noargs(pool, _release)
+ C.douitask(appDelegate, unsafe.Pointer(&f))
}
}()
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.breakMainLoop()
}
}()
- C.objc_msgSend_noargs(NSApp, _run)
+ C.cocoaMainLoop()
return nil
}
@@ -84,21 +67,16 @@ var (
// _setDelegate in sysdata_darwin.go
)
-func initCocoa() (NSApp C.id, err error) {
+func initCocoa() (err error) {
C.initBleh() // initialize bleh_darwin.m functions
- NSApp = C.objc_msgSend_noargs(_NSApplication, _sharedApplication)
- r := C.objc_msgSend_int(NSApp, _setActivationPolicy,
- 0) // NSApplicationActivationPolicyRegular
- if C.BOOL(uintptr(unsafe.Pointer(r))) != C.BOOL(C.YES) {
- err = fmt.Errorf("error setting NSApplication activation policy (basically identifies our program as a separate program; needed for several things, such as Dock icon, application menu, window resizing, etc.) (unknown reason)")
- return
- }
- C.objc_msgSend_bool(NSApp, _activateIgnoringOtherApps, C.BOOL(C.YES)) // TODO actually do C.NO here? Russ Cox does YES in his devdraw; the docs say the Finder does NO
err = mkAppDelegate()
if err != nil {
return
}
- C.objc_msgSend_id(NSApp, _setDelegate, appDelegate)
+ if C.initCocoa(appDelegate) != C.YES {
+ err = fmt.Errorf("error setting NSApplication activation policy (basically identifies our program as a separate program; needed for several things, such as Dock icon, application menu, window resizing, etc.) (unknown reason)")
+ return
+ }
err = mkAreaClass()
return
}