internal/uidriver/glfw: Separate createWindow and registring the callback

createWindow created a window and also registered the SetSize callback.
This was problematic in setWindowSize, since the callback was invoked
in setWindowSize unexpectedly.

This change separates createWindow and registring the callback so that
the created window in setWindowSize doesn't invoke the callback until
setWindowSize finishes.

Closes #1505
This commit is contained in:
Hajime Hoshi 2021-03-06 01:39:20 +09:00
parent fda421c5fe
commit 990fb14f17

View File

@ -624,6 +624,16 @@ func (u *UserInterface) createWindow() error {
u.window.SetTitle(u.title) u.window.SetTitle(u.title)
// TODO: Set icons // TODO: Set icons
return nil
}
// unregisterWindowSetSizeCallback must be called from the main thread.
func (u *UserInterface) unregisterWindowSetSizeCallback() {
u.window.SetSizeCallback(nil)
}
// registerWindowSetSizeCallback must be called from the main thread.
func (u *UserInterface) registerWindowSetSizeCallback() {
u.window.SetSizeCallback(func(_ *glfw.Window, width, height int) { u.window.SetSizeCallback(func(_ *glfw.Window, width, height int) {
if u.window.GetAttrib(glfw.Resizable) == glfw.False { if u.window.GetAttrib(glfw.Resizable) == glfw.False {
return return
@ -661,8 +671,6 @@ func (u *UserInterface) createWindow() error {
u.err = err u.err = err
} }
}) })
return nil
} }
func (u *UserInterface) init() error { func (u *UserInterface) init() error {
@ -713,6 +721,7 @@ func (u *UserInterface) init() error {
if err := u.createWindow(); err != nil { if err := u.createWindow(); err != nil {
return err return err
} }
u.registerWindowSetSizeCallback()
setPosition := func() { setPosition := func() {
u.iwindow.setPosition(u.getInitWindowPosition()) u.iwindow.setPosition(u.getInitWindowPosition())
@ -948,12 +957,8 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
// Do not fire the callback of SetSize. This callback can be invoked by SetMonitor or SetSize. // Do not fire the callback of SetSize. This callback can be invoked by SetMonitor or SetSize.
// ForceUpdate is called from the callback. // ForceUpdate is called from the callback.
// While setWindowSize can be called from Update, calling ForceUpdate inside Update is illegal (#1505). // While setWindowSize can be called from Update, calling ForceUpdate inside Update is illegal (#1505).
f := u.window.SetSizeCallback(nil) u.unregisterWindowSetSizeCallback()
defer func() { defer u.registerWindowSetSizeCallback()
// u.window can be changed before this deferred function is executed.
// Wrap this call by an anonymous function (#1522).
u.window.SetSizeCallback(f)
}()
var windowRecreated bool var windowRecreated bool