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 {
|
||||
case c_button:
|
||||
if wParam.HIWORD() == _BN_CLICKED {
|
||||
ss.event <- struct{}{}
|
||||
ss.signal()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
|
@ -58,9 +58,7 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam
|
|||
}
|
||||
return 0
|
||||
case _WM_CLOSE:
|
||||
if s.event != nil {
|
||||
s.event <- struct{}{}
|
||||
}
|
||||
s.signal()
|
||||
return 0
|
||||
default:
|
||||
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()")
|
||||
}
|
||||
|
||||
// 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 (
|
||||
c_window = iota
|
||||
c_button
|
||||
|
|
|
@ -35,19 +35,17 @@ var classTypes = [nctypes]*classData{
|
|||
setText: gtk_window_set_title,
|
||||
text: gtk_window_get_title,
|
||||
signals: map[string]func(*sysData) func() bool{
|
||||
"delete-event": func(w *sysData) func() bool {
|
||||
"delete-event": func(s *sysData) func() bool {
|
||||
return func() bool {
|
||||
if w.event != nil {
|
||||
w.event <- struct{}{}
|
||||
}
|
||||
s.signal()
|
||||
return true // do not close the window
|
||||
}
|
||||
},
|
||||
"configure-event": func(w *sysData) func() bool {
|
||||
"configure-event": func(s *sysData) func() bool {
|
||||
return func() bool {
|
||||
if w.container != nil && w.resize != nil { // wait for init
|
||||
width, height := gtk_window_get_size(w.widget)
|
||||
err := w.resize(0, 0, width, height)
|
||||
if s.container != nil && s.resize != nil { // wait for init
|
||||
width, height := gtk_window_get_size(s.widget)
|
||||
err := s.resize(0, 0, width, height)
|
||||
if err != nil {
|
||||
panic("child resize failed: " + err.Error())
|
||||
}
|
||||
|
@ -64,11 +62,9 @@ var classTypes = [nctypes]*classData{
|
|||
setText: gtk_button_set_label,
|
||||
text: gtk_button_get_label,
|
||||
signals: map[string]func(*sysData) func() bool{
|
||||
"clicked": func(w *sysData) func() bool {
|
||||
"clicked": func(s *sysData) func() bool {
|
||||
return func() bool {
|
||||
if w.event != nil {
|
||||
w.event <- struct{}{}
|
||||
}
|
||||
s.signal()
|
||||
return true // do not close the window
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue