summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--link_darwin_amd64.go18
-rw-r--r--link_linux_386.go4
-rw-r--r--link_linux_amd64.go4
-rw-r--r--link_windows_386.go4
-rw-r--r--link_windows_amd64.go4
-rw-r--r--main.go23
6 files changed, 11 insertions, 46 deletions
diff --git a/link_darwin_amd64.go b/link_darwin_amd64.go
index 3a848b3..687a62a 100644
--- a/link_darwin_amd64.go
+++ b/link_darwin_amd64.go
@@ -3,21 +3,5 @@
package ui
// #cgo CFLAGS: -mmacosx-version-min=10.8 -DMACOSX_DEPLOYMENT_TARGET=10.8
-// #cgo LDFLAGS: ${SRCDIR}/libui_darwin_amd64.a -framework Foundation -framework AppKit -lpthread -mmacosx-version-min=10.8
-// #include <CoreFoundation/CoreFoundation.h>
-// #include <pthread.h>
-// extern void _CFRunLoopSetCurrent(CFRunLoopRef);
-// extern pthread_t _CFMainPThread;
+// #cgo LDFLAGS: ${SRCDIR}/libui_darwin_amd64.a -framework Foundation -framework AppKit -mmacosx-version-min=10.8
import "C"
-
-// OS X cares very deeply if we don't run on the very first thread the OS creates
-// why? who knows. it's stupid and completely indefensible. let's use undocumented APIs to get around it.
-// apple uses them too: http://www.opensource.apple.com/source/kext_tools/kext_tools-19.2/kextd_main.c?txt
-// apple HAS SUGGESTED them too: http://lists.apple.com/archives/darwin-development/2002/Sep/msg00250.html
-// gstreamer uses them too: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/sys/osxvideo/osxvideosink.m
-func ensureMainThread() {
- // TODO set to nil like the apple code?
- C._CFRunLoopSetCurrent(C.CFRunLoopGetMain())
- // TODO is this part necessary?
- C._CFMainPThread = C.pthread_self()
-}
diff --git a/link_linux_386.go b/link_linux_386.go
index 30edeba..00a0598 100644
--- a/link_linux_386.go
+++ b/link_linux_386.go
@@ -8,7 +8,3 @@ package ui
// #cgo LDFLAGS: ${SRCDIR}/libui_linux_386.a -lm -ldl
// #cgo pkg-config: gtk+-3.0
import "C"
-
-func ensureMainThread() {
- // do nothing; GTK+ doesn't care which thread we're on so long as we don't change it after starting
-}
diff --git a/link_linux_amd64.go b/link_linux_amd64.go
index 6d3d568..a1b2b3b 100644
--- a/link_linux_amd64.go
+++ b/link_linux_amd64.go
@@ -8,7 +8,3 @@ package ui
// #cgo LDFLAGS: ${SRCDIR}/libui_linux_amd64.a -lm -ldl
// #cgo pkg-config: gtk+-3.0
import "C"
-
-func ensureMainThread() {
- // do nothing; GTK+ doesn't care which thread we're on so long as we don't change it after starting
-}
diff --git a/link_windows_386.go b/link_windows_386.go
index f223ae1..776b481 100644
--- a/link_windows_386.go
+++ b/link_windows_386.go
@@ -6,7 +6,3 @@ package ui
// /* note the order; also note the lack of uuid */
// #cgo LDFLAGS: -luser32 -lkernel32 -lusp10 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -ldwrite -lole32 -loleaut32 -loleacc -static -static-libgcc -static-libstdc++
import "C"
-
-func ensureMainThread() {
- // do nothing; Windows doesn't care which thread we're on so long as we don't change it after starting
-}
diff --git a/link_windows_amd64.go b/link_windows_amd64.go
index 515bbd1..ad2d1a2 100644
--- a/link_windows_amd64.go
+++ b/link_windows_amd64.go
@@ -6,7 +6,3 @@ package ui
// /* note the order; also note the lack of uuid */
// #cgo LDFLAGS: -luser32 -lkernel32 -lusp10 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -ldwrite -lole32 -loleaut32 -loleacc -static -static-libgcc -static-libstdc++
import "C"
-
-func ensureMainThread() {
- // do nothing; Windows doesn't care which thread we're on so long as we don't change it after starting
-}
diff --git a/main.go b/main.go
index ddfefe1..b908e0a 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,13 @@ import (
// }
import "C"
+// make sure main() runs on the first thread created by the OS
+// if main() calls Main(), things will just work on macOS, where the first thread created by the OS is the only thread allowed to be the main GUI thread
+// we might as well lock the OS thread for the other platforms here too (though on those it doesn't matter *which* thread we lock to)
+func init() {
+ runtime.LockOSThread()
+}
+
// Main initializes package ui, runs f to set up the program,
// and executes the GUI main loop. f should set up the program's
// initial state: open the main window, create controls, and set up
@@ -32,29 +39,19 @@ import "C"
// nil. If package ui fails to initialize, Main returns an appropriate
// error.
func Main(f func()) error {
- errchan := make(chan error)
- go start(errchan, f)
- return <-errchan
-}
-
-func start(errchan chan error, f func()) {
- runtime.LockOSThread()
-
- ensureMainThread()
-
// TODO HEAP SAFETY
opts := C.uiInitOptions{}
estr := C.uiInit(&opts)
if estr != nil {
- errchan <- errors.New(C.GoString(estr))
+ err := errors.New(C.GoString(estr))
C.uiFreeInitError(estr)
- return
+ return err
}
// set up OnShouldQuit()
C.realOnShouldQuit()
QueueMain(f)
C.uiMain()
- errchan <- nil
+ return nil
}
// Quit queues a return from Main. It does not exit the program.