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

View File

@ -42,7 +42,7 @@ func (w glfwWindows) add(win uintptr) *Window {
if win == 0 { if win == 0 {
return nil return nil
} }
ww := &Window{win} ww := &Window{w: win}
glfwWindowsM.Lock() glfwWindowsM.Lock()
w[win] = ww w[win] = ww
glfwWindowsM.Unlock() glfwWindowsM.Unlock()
@ -91,6 +91,8 @@ func (m *Monitor) GetVideoMode() *VidMode {
type Window struct { type Window struct {
w uintptr w uintptr
prevSizeCallback SizeCallback
} }
func (w *Window) Destroy() { func (w *Window) Destroy() {
@ -218,7 +220,7 @@ func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallbac
return nil // TODO return nil // TODO
} }
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous FramebufferSizeCallback) { func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
var gcb uintptr var gcb uintptr
if cbfun != nil { if cbfun != nil {
gcb = windows.NewCallbackCDecl(func(window uintptr, width int, height int) uintptr { 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) glfwDLL.call("glfwSetWindowSizeCallback", w.w, gcb)
panicError() panicError()
return nil // TODO prev := w.prevSizeCallback
w.prevSizeCallback = cbfun
return prev
} }
func (w *Window) SetIcon(images []image.Image) { 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. // swap buffers here before SetSize is called.
u.swapBuffers() 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 var windowRecreated bool
if fullscreen { if fullscreen {