Made event dispatch asynchronous to avoid deadlocks; right now events that cannot be dispatched get dropped.
This commit is contained in:
parent
16ab1763ba
commit
1f08c874e0
|
@ -32,7 +32,7 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam
|
||||||
switch ss.ctype {
|
switch ss.ctype {
|
||||||
case c_button:
|
case c_button:
|
||||||
if wParam.HIWORD() == _BN_CLICKED {
|
if wParam.HIWORD() == _BN_CLICKED {
|
||||||
ss.event <- struct{}{}
|
ss.signal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
@ -58,9 +58,7 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
case _WM_CLOSE:
|
case _WM_CLOSE:
|
||||||
if s.event != nil {
|
s.signal()
|
||||||
s.event <- struct{}{}
|
|
||||||
}
|
|
||||||
return 0
|
return 0
|
||||||
default:
|
default:
|
||||||
r1, _, _ := defWindowProc.Call(
|
r1, _, _ := defWindowProc.Call(
|
||||||
|
|
13
sysdata.go
13
sysdata.go
|
@ -55,6 +55,19 @@ func (c *cSysData) delete(int) error {
|
||||||
panic(runtime.GOOS + " sysData does not define delete()")
|
panic(runtime.GOOS + " sysData does not define delete()")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task.
|
||||||
|
// Thanks skelterjohn for this techinque: if we can't queue any more events, drop them; TODO this would be best if the channel is buffered
|
||||||
|
func (s *cSysData) signal() {
|
||||||
|
if s.event != nil {
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case s.event <- struct{}{}:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
c_window = iota
|
c_window = iota
|
||||||
c_button
|
c_button
|
||||||
|
|
|
@ -35,19 +35,17 @@ var classTypes = [nctypes]*classData{
|
||||||
setText: gtk_window_set_title,
|
setText: gtk_window_set_title,
|
||||||
text: gtk_window_get_title,
|
text: gtk_window_get_title,
|
||||||
signals: map[string]func(*sysData) func() bool{
|
signals: map[string]func(*sysData) func() bool{
|
||||||
"delete-event": func(w *sysData) func() bool {
|
"delete-event": func(s *sysData) func() bool {
|
||||||
return func() bool {
|
return func() bool {
|
||||||
if w.event != nil {
|
s.signal()
|
||||||
w.event <- struct{}{}
|
|
||||||
}
|
|
||||||
return true // do not close the window
|
return true // do not close the window
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"configure-event": func(w *sysData) func() bool {
|
"configure-event": func(s *sysData) func() bool {
|
||||||
return func() bool {
|
return func() bool {
|
||||||
if w.container != nil && w.resize != nil { // wait for init
|
if s.container != nil && s.resize != nil { // wait for init
|
||||||
width, height := gtk_window_get_size(w.widget)
|
width, height := gtk_window_get_size(s.widget)
|
||||||
err := w.resize(0, 0, width, height)
|
err := s.resize(0, 0, width, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("child resize failed: " + err.Error())
|
panic("child resize failed: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -64,11 +62,9 @@ var classTypes = [nctypes]*classData{
|
||||||
setText: gtk_button_set_label,
|
setText: gtk_button_set_label,
|
||||||
text: gtk_button_get_label,
|
text: gtk_button_get_label,
|
||||||
signals: map[string]func(*sysData) func() bool{
|
signals: map[string]func(*sysData) func() bool{
|
||||||
"clicked": func(w *sysData) func() bool {
|
"clicked": func(s *sysData) func() bool {
|
||||||
return func() bool {
|
return func() bool {
|
||||||
if w.event != nil {
|
s.signal()
|
||||||
w.event <- struct{}{}
|
|
||||||
}
|
|
||||||
return true // do not close the window
|
return true // do not close the window
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue