@@ -23,6 +23,16 @@ func newQueue() *queue {
2323 }
2424}
2525
26+ func newInvalidateTrampoline (window * app.Window ) chan struct {} {
27+ c := make (chan struct {}, 1 )
28+ go func () {
29+ for range c {
30+ window .Invalidate ()
31+ }
32+ }()
33+ return c
34+ }
35+
2636// Plugin is the main interface for the plugins.
2737type Plugin struct {
2838 window * app.Window
@@ -34,8 +44,6 @@ type Plugin struct {
3444 eventsCustomNext * queue
3545 eventsCustomCurrent * queue
3646
37- eventsPool []event.Event
38-
3947 RedirectEvent map [reflect.Type ][]int
4048 RedirectOp map [reflect.Type ][]int
4149 RedirectCommands map [reflect.Type ][]int
@@ -47,6 +55,8 @@ type Plugin struct {
4755
4856 OriginalFrame func (ops * op.Ops )
4957 OriginalSource input.Source
58+
59+ invalidator chan struct {}
5060}
5161
5262// NewPlugin creates a new plugin.
@@ -60,6 +70,10 @@ func NewPlugin(w *app.Window) *Plugin {
6070 RedirectEvent : make (map [reflect.Type ][]int , 128 ),
6171 eventsCustomNext : newQueue (),
6272 eventsCustomCurrent : newQueue (),
73+
74+ // That is required to prevent deadlock when sending events
75+ // in the main-thread. Gio bug.
76+ invalidator : newInvalidateTrampoline (w ),
6377 }
6478
6579 for index , pf := range registeredPlugins {
@@ -102,7 +116,7 @@ func (l *Plugin) SendEvent(tag event.Tag, data event.Event) {
102116 l .eventsCustomNext .taggedEvents [tag ] = append (l .eventsCustomNext .taggedEvents [tag ], data )
103117
104118 if ! l .Invalidated .Load () {
105- l .window . Invalidate ()
119+ l .invalidator <- struct {}{}
106120 l .Invalidated .Store (true )
107121 }
108122}
@@ -119,7 +133,7 @@ func (l *Plugin) SendEventUntagged(tag uint64, data event.Event) {
119133 l .eventsCustomNext .untaggedEvents [tag ] = append (l .eventsCustomNext .untaggedEvents [tag ], data )
120134
121135 if ! l .Invalidated .Load () {
122- l .window . Invalidate ()
136+ l .invalidator <- struct {}{}
123137 l .Invalidated .Store (true )
124138 }
125139}
0 commit comments