app: process driver funcs before queueing more

Window.driverFunc says it can be run from any context. However, running
it from the Window.run event loop may deadlock, at least until an
unrelated event arrives from the driver (e.g. a mouse move).

Example:
Window.Invalidate is called, which caused Window.run to queue a driver
func, and notify the Window.wakeups channel. However, another
Window.Invalidate arrives just in time for Window.run to process that
before Window.wakeups, leading to a deadlock because only one driver
func can be queued.

This change fixes the problem by processing wakeups before potentially
queueing more driver functions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-09-16 10:49:42 +02:00
parent f896a72ea1
commit c9d85c97e1
+7
View File
@@ -517,6 +517,13 @@ func (w *Window) run(options []Option) {
)
if wakeup != nil {
wakeups = w.wakeups
// Make sure any pending deferred driver functions are processed before calling
// into driverFunc again; only one driver function can be queued at a time.
select {
case <-wakeups:
wakeup()
default:
}
}
if w.delayedDraw != nil {
timer = w.delayedDraw.C