internal/uidriver/glfw: Bug fix: Crash when returning from fullscreen

ForceUpdate was called unexpectedly inside Update. This caused the
race condition.

Closes #1505
This commit is contained in:
Hajime Hoshi 2021-02-23 16:52:09 +09:00
parent b8cdcdb847
commit 18d526c2d3
3 changed files with 19 additions and 5 deletions

View File

@ -35,7 +35,7 @@ func (w windows) add(win *glfw.Window) *Window {
if win == nil {
return nil
}
ww := &Window{win}
ww := &Window{w: win}
windowsM.Lock()
w[win] = ww
windowsM.Unlock()
@ -87,6 +87,8 @@ func (m *Monitor) GetVideoMode() *VidMode {
type Window struct {
w *glfw.Window
prevSizeCallback SizeCallback
}
func (w *Window) Destroy() {
@ -191,7 +193,9 @@ func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
}
}
w.w.SetSizeCallback(gcb)
return nil // TODO
prev := w.prevSizeCallback
w.prevSizeCallback = cbfun
return prev
}
func (w *Window) SetIcon(images []image.Image) {

View File

@ -42,7 +42,7 @@ func (w glfwWindows) add(win uintptr) *Window {
if win == 0 {
return nil
}
ww := &Window{win}
ww := &Window{w: win}
glfwWindowsM.Lock()
w[win] = ww
glfwWindowsM.Unlock()
@ -91,6 +91,8 @@ func (m *Monitor) GetVideoMode() *VidMode {
type Window struct {
w uintptr
prevSizeCallback SizeCallback
}
func (w *Window) Destroy() {
@ -218,7 +220,7 @@ func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallbac
return nil // TODO
}
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous FramebufferSizeCallback) {
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
var gcb uintptr
if cbfun != nil {
gcb = windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr {
@ -228,7 +230,9 @@ func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous FramebufferSizeCa
}
glfwDLL.call("glfwSetWindowSizeCallback", w.w, gcb)
panicError()
return nil // TODO
prev := w.prevSizeCallback
w.prevSizeCallback = cbfun
return prev
}
func (w *Window) SetIcon(images []image.Image) {

View File

@ -946,6 +946,12 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
// swap buffers here before SetSize is called.
u.swapBuffers()
// Do not fire the callback of SetSize. This callback can be invoked by SetMonitor or SetSize.
// ForceUpdate is called from the callback.
// While setWindowSize can be called from Update, calling ForceUpdate inside Update is illegal (#1505).
f := u.window.SetSizeCallback(nil)
defer u.window.SetSizeCallback(f)
var windowRecreated bool
if fullscreen {