2014-02-28 22:01:48 -06:00
// 28 february 2014
2014-03-12 20:55:45 -05:00
2014-02-28 22:01:48 -06:00
package ui
import (
2014-03-01 19:31:17 -06:00
"fmt"
2014-02-28 22:01:48 -06:00
"runtime"
"unsafe"
)
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
// #include "objc_darwin.h"
2014-05-13 07:14:28 -05:00
// #include "delegateuitask_darwin.h"
2014-02-28 22:01:48 -06:00
import "C"
var uitask chan func ( )
var (
_NSAutoreleasePool = objc_getClass ( "NSAutoreleasePool" )
_NSValue = objc_getClass ( "NSValue" )
_valueWithPointer = sel_getUid ( "valueWithPointer:" )
_performSelectorOnMainThread =
sel_getUid ( "performSelectorOnMainThread:withObject:waitUntilDone:" )
2014-03-05 19:09:15 -06:00
_stop = sel_getUid ( "stop:" )
_postEventAtStart = sel_getUid ( "postEvent:atStart:" )
2014-02-28 22:01:48 -06:00
_pointerValue = sel_getUid ( "pointerValue" )
2014-03-01 14:18:29 -06:00
_run = sel_getUid ( "run" )
2014-02-28 22:01:48 -06:00
)
2014-03-01 14:18:29 -06:00
func ui ( main func ( ) ) error {
2014-02-28 22:01:48 -06:00
runtime . LockOSThread ( )
uitask = make ( chan func ( ) )
2014-03-01 14:18:29 -06:00
2014-05-13 07:14:28 -05:00
err := initCocoa ( )
2014-03-01 14:18:29 -06:00
if err != nil {
return err
2014-02-28 22:01:48 -06:00
}
2014-03-01 14:18:29 -06:00
// 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 {
2014-05-13 07:14:28 -05:00
C . douitask ( appDelegate , unsafe . Pointer ( & f ) )
2014-03-01 14:18:29 -06:00
}
} ( )
2014-03-05 19:09:15 -06:00
go func ( ) {
main ( )
uitask <- func ( ) {
2014-05-13 07:14:28 -05:00
C . breakMainLoop ( )
2014-03-05 19:09:15 -06:00
}
} ( )
2014-03-01 14:18:29 -06:00
2014-05-13 07:14:28 -05:00
C . cocoaMainLoop ( )
2014-03-01 14:18:29 -06:00
return nil
2014-02-28 22:01:48 -06:00
}
2014-03-01 14:18:29 -06:00
// TODO move to init_darwin.go?
2014-02-28 22:01:48 -06:00
var (
_NSApplication = objc_getClass ( "NSApplication" )
_sharedApplication = sel_getUid ( "sharedApplication" )
2014-03-01 19:31:17 -06:00
_setActivationPolicy = sel_getUid ( "setActivationPolicy:" )
2014-03-12 09:02:59 -05:00
_activateIgnoringOtherApps = sel_getUid ( "activateIgnoringOtherApps:" )
2014-04-07 11:46:09 -05:00
// _setDelegate in sysdata_darwin.go
2014-02-28 22:01:48 -06:00
)
2014-05-13 07:14:28 -05:00
func initCocoa ( ) ( err error ) {
2014-04-05 12:30:56 -05:00
C . initBleh ( ) // initialize bleh_darwin.m functions
2014-03-01 15:56:22 -06:00
err = mkAppDelegate ( )
2014-03-30 10:19:13 -05:00
if err != nil {
return
}
2014-05-13 07:14:28 -05:00
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
}
2014-03-30 10:19:13 -05:00
err = mkAreaClass ( )
2014-03-01 14:18:29 -06:00
return
2014-02-28 22:01:48 -06:00
}
//export appDelegate_uitask
2014-05-13 06:56:37 -05:00
func appDelegate_uitask ( p unsafe . Pointer ) {
2014-02-28 22:01:48 -06:00
f := ( * func ( ) ) ( unsafe . Pointer ( p ) )
( * f ) ( )
}