diff --git a/delegateuitask_darwin.m b/delegateuitask_darwin.m index ed912eb..9f16071 100644 --- a/delegateuitask_darwin.m +++ b/delegateuitask_darwin.m @@ -127,7 +127,7 @@ void douitask(id appDelegate, void *p) fp = [NSValue valueWithPointer:p]; [appDelegate performSelectorOnMainThread:@selector(uitask:) withObject:fp - waitUntilDone: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 + waitUntilDone:YES]; // wait since that's what we want the Go uitask() to do [pool release]; } diff --git a/dialog_darwin.go b/dialog_darwin.go index 038c640..fe44d8f 100644 --- a/dialog_darwin.go +++ b/dialog_darwin.go @@ -19,7 +19,7 @@ func dialog_send(pchan unsafe.Pointer, res C.intptr_t) { func _msgBox(parent *Window, primarytext string, secondarytext string, style uintptr) chan int { ret := make(chan int) - uitask <- func() { + uitask(func() { var pwin C.id = nil if parent != dialogWindow { @@ -36,7 +36,7 @@ func _msgBox(parent *Window, primarytext string, secondarytext string, style uin case 1: // error C.msgBoxError(pwin, primary, secondary, unsafe.Pointer(&ret)) } - } + }) return ret } diff --git a/sysdata_darwin.go b/sysdata_darwin.go index 48b7d44..06c921e 100644 --- a/sysdata_darwin.go +++ b/sysdata_darwin.go @@ -225,20 +225,14 @@ func (s *sysData) make(window *sysData) error { if window != nil { parentWindow = window.id } - ret := make(chan C.id) - defer close(ret) - uitask <- func() { - ret <- ct.make(parentWindow, s.alternate, s) - } - s.id = <-ret - if ct.getinside != nil { - uitask <- func() { - ret <- ct.getinside(s.id) + uitask(func() { + s.id = ct.make(parentWindow, s.alternate, s) + if ct.getinside != nil { + addSysData(ct.getinside(s.id), s) + } else { + addSysData(s.id, s) } - addSysData(<-ret, s) - } else { - addSysData(s.id, s) - } + }) return nil } @@ -249,33 +243,21 @@ func (s *sysData) firstShow() error { } func (s *sysData) show() { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].show(s.id) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) hide() { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].hide(s.id) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) setText(text string) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].settext(s.id, toNSString(text)) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error { @@ -288,147 +270,111 @@ func (s *sysData) setRect(x int, y int, width int, height int, winheight int) er } func (s *sysData) isChecked() bool { - ret := make(chan bool) - defer close(ret) - uitask <- func() { - ret <- C.isCheckboxChecked(s.id) != C.NO - } - return <-ret + var b bool + + uitask(func() { + b = C.isCheckboxChecked(s.id) != C.NO + }) + return b } func (s *sysData) text() string { - ret := make(chan string) - defer close(ret) - uitask <- func() { + var text string + + uitask(func() { str := classTypes[s.ctype].text(s.id, s.alternate) - ret <- fromNSString(str) - } - return <-ret + text = fromNSString(str) + }) + return text } func (s *sysData) append(what string) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].append(s.id, what, s.alternate) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) insertBefore(what string, before int) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].insertBefore(s.id, what, before, s.alternate) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) selectedIndex() int { - ret := make(chan int) - defer close(ret) - uitask <- func() { - ret <- classTypes[s.ctype].selIndex(s.id) - } - return <-ret + var i int + + uitask(func() { + i = classTypes[s.ctype].selIndex(s.id) + }) + return i } func (s *sysData) selectedIndices() []int { - ret := make(chan []int) - defer close(ret) - uitask <- func() { - ret <- classTypes[s.ctype].selIndices(s.id) - } - return <-ret + var i []int + + uitask(func() { + i = classTypes[s.ctype].selIndices(s.id) + }) + return i } func (s *sysData) selectedTexts() []string { - ret := make(chan []string) - defer close(ret) - uitask <- func() { - ret <- classTypes[s.ctype].selTexts(s.id) - } - return <-ret + var texts []string + + uitask(func() { + texts = classTypes[s.ctype].selTexts(s.id) + }) + return texts } func (s *sysData) setWindowSize(width int, height int) error { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.windowSetContentSize(s.id, C.intptr_t(width), C.intptr_t(height)) - ret <- struct{}{} - } - <-ret + }) return nil } func (s *sysData) delete(index int) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { classTypes[s.ctype].delete(s.id, index) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) setProgress(percent int) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.setProgress(s.id, C.intptr_t(percent)) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) len() int { - ret := make(chan int) - defer close(ret) - uitask <- func() { - ret <- classTypes[s.ctype].len(s.id) - } - return <-ret + var i int + + uitask(func() { + i = classTypes[s.ctype].len(s.id) + }) + return i } func (s *sysData) setAreaSize(width int, height int) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.setAreaSize(s.id, C.intptr_t(width), C.intptr_t(height)) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) repaintAll() { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.display(s.id) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) center() { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.center(s.id) - ret <- struct{}{} - } - <-ret + }) } func (s *sysData) setChecked(checked bool) { - ret := make(chan struct{}) - defer close(ret) - uitask <- func() { + uitask(func() { C.setCheckboxChecked(s.id, toBOOL(checked)) - ret <- struct{}{} - } - <-ret + }) } diff --git a/uitask_darwin.go b/uitask_darwin.go index 754418c..5932cac 100644 --- a/uitask_darwin.go +++ b/uitask_darwin.go @@ -14,30 +14,25 @@ import ( // #include "objc_darwin.h" import "C" -var uitask chan func() +// can be run from any thread +// will wait for return; see delegateuitask_darwin.m +func uitask(f func()) { + C.douitask(appDelegate, unsafe.Pointer(&f)) +} func ui(main func()) error { runtime.LockOSThread() - uitask = make(chan func()) - err := initCocoa() if err != nil { return err } - // 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 { - C.douitask(appDelegate, unsafe.Pointer(&f)) - } - }() - go func() { main() - uitask <- func() { + uitask(func() { C.breakMainLoop() - } + }) }() C.cocoaMainLoop()