Converted the GTK+ backend to use the new uitask. Indeterminate progressbars no longer work; this will be fixed soon.
This commit is contained in:
parent
607e710459
commit
e04e5f5cad
|
@ -89,7 +89,7 @@ func our_idle_callback(what C.gpointer) C.gboolean {
|
||||||
return C.FALSE // remove this idle function; we're finished
|
return C.FALSE // remove this idle function; we're finished
|
||||||
}
|
}
|
||||||
|
|
||||||
func gdk_threads_add_idle(idleop *gtkIdleOp) {
|
func gdk_threads_add_idle_op(idleop *gtkIdleOp) {
|
||||||
C.gdk_threads_add_idle(C.GCallback(C.our_idle_callback),
|
C.gdk_threads_add_idle(C.GCallback(C.our_idle_callback),
|
||||||
C.gpointer(unsafe.Pointer(idleop)))
|
C.gpointer(unsafe.Pointer(idleop)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,9 +220,10 @@ func (s *sysData) delete(index int) {
|
||||||
func (s *sysData) progressPulse() {
|
func (s *sysData) progressPulse() {
|
||||||
// TODO this could probably be done differently...
|
// TODO this could probably be done differently...
|
||||||
pulse := func() {
|
pulse := func() {
|
||||||
touitask(func() {
|
// TODO
|
||||||
gtk_progress_bar_pulse(s.widget)
|
// touitask(func() {
|
||||||
})
|
// gtk_progress_bar_pulse(s.widget)
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
var ticker *time.Ticker
|
var ticker *time.Ticker
|
||||||
|
|
|
@ -6,13 +6,52 @@ package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo pkg-config: gtk+-3.0
|
// #cgo pkg-config: gtk+-3.0
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
|
// /* unfortunately, there's no way to differentiate between the main thread and other threads; in fact, doing what we do on other platforms is discouraged by the GTK+ devs!
|
||||||
|
// but I can't avoid this any other way... so we have structures defined on the C side to skirt the garbage collector */
|
||||||
|
// struct uitaskParams {
|
||||||
|
// void *window; /* createWindow */
|
||||||
|
// void *control; /* createWindow */
|
||||||
|
// gboolean show; /* createWindow */
|
||||||
|
// };
|
||||||
|
// static struct uitaskParams *mkParams(void)
|
||||||
|
// {
|
||||||
|
// /* g_malloc0() will abort on not enough memory */
|
||||||
|
// return (struct uitaskParams *) g_malloc0(sizeof (struct uitaskParams));
|
||||||
|
// }
|
||||||
|
// static void freeParams(struct uitaskParams *p)
|
||||||
|
// {
|
||||||
|
// g_free(p);
|
||||||
|
// }
|
||||||
|
// extern gboolean our_createWindow_callback(gpointer);
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
var uitask chan func()
|
//export our_createWindow_callback
|
||||||
|
func our_createWindow_callback(what C.gpointer) C.gboolean {
|
||||||
|
uc := (*C.struct_uitaskParams)(unsafe.Pointer(what))
|
||||||
|
w := (*Window)(unsafe.Pointer(uc.window))
|
||||||
|
c := *(*Control)(unsafe.Pointer(uc.control))
|
||||||
|
s := fromgbool(uc.show)
|
||||||
|
w.create(c, s)
|
||||||
|
C.freeParams(uc)
|
||||||
|
return C.FALSE // remove this idle function; we're finished
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_uitask) createWindow(w *Window, c Control, s bool) {
|
||||||
|
uc := C.mkParams()
|
||||||
|
uc.window = unsafe.Pointer(w)
|
||||||
|
uc.control = unsafe.Pointer(&c)
|
||||||
|
uc.show = togbool(s)
|
||||||
|
gdk_threads_add_idle(C.our_createWindow_callback, unsafe.Pointer(uc))
|
||||||
|
}
|
||||||
|
|
||||||
|
func gdk_threads_add_idle(f unsafe.Pointer, what unsafe.Pointer) {
|
||||||
|
C.gdk_threads_add_idle(C.GCallback(f), C.gpointer(what))
|
||||||
|
}
|
||||||
|
|
||||||
func uiinit() error {
|
func uiinit() error {
|
||||||
err := gtk_init()
|
err := gtk_init()
|
||||||
|
@ -20,8 +59,6 @@ func uiinit() error {
|
||||||
return fmt.Errorf("gtk_init() failed: %v", err)
|
return fmt.Errorf("gtk_init() failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do this only on success, just to be safe
|
|
||||||
uitask = make(chan func())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,25 +66,19 @@ func ui() {
|
||||||
// thanks to tristan and Daniel_S in irc.gimp.net/#gtk
|
// thanks to tristan and Daniel_S in irc.gimp.net/#gtk
|
||||||
// see our_idle_callback in callbacks_unix.go for details
|
// see our_idle_callback in callbacks_unix.go for details
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
// TODO do differently
|
||||||
var f func()
|
<-Stop
|
||||||
|
// using gdk_threads_add_idle() will make sure it gets run when any events currently being handled finish running
|
||||||
select {
|
f := func() {
|
||||||
case f = <-uitask:
|
C.gtk_main_quit()
|
||||||
// do nothing
|
|
||||||
case <-Stop:
|
|
||||||
f = func() {
|
|
||||||
C.gtk_main_quit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done := make(chan struct{})
|
|
||||||
gdk_threads_add_idle(>kIdleOp{
|
|
||||||
what: f,
|
|
||||||
done: done,
|
|
||||||
})
|
|
||||||
<-done
|
|
||||||
close(done)
|
|
||||||
}
|
}
|
||||||
|
done := make(chan struct{})
|
||||||
|
gdk_threads_add_idle_op(>kIdleOp{
|
||||||
|
what: f,
|
||||||
|
done: done,
|
||||||
|
})
|
||||||
|
<-done
|
||||||
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
C.gtk_main()
|
C.gtk_main()
|
||||||
|
|
Loading…
Reference in New Issue