summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stdwndclass_windows.go6
-rw-r--r--sysdata.go13
-rw-r--r--sysdata_unix.go20
3 files changed, 23 insertions, 16 deletions
diff --git a/stdwndclass_windows.go b/stdwndclass_windows.go
index 2824746..3c9861f 100644
--- a/stdwndclass_windows.go
+++ b/stdwndclass_windows.go
@@ -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(
diff --git a/sysdata.go b/sysdata.go
index e4885ac..da94766 100644
--- a/sysdata.go
+++ b/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
diff --git a/sysdata_unix.go b/sysdata_unix.go
index 3c13b8c..3250b6d 100644
--- a/sysdata_unix.go
+++ b/sysdata_unix.go
@@ -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
}
},