mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-14 15:07:26 +01:00
internal/uidriver/glfw: Bug fix: Disable the SetSize callback for most of GLFW window functions
Updates #1576 Updates #1585 Closes #1606
This commit is contained in:
parent
74018348c0
commit
ee8bfcd837
@ -816,9 +816,6 @@ func (u *UserInterface) init() error {
|
|||||||
}
|
}
|
||||||
u.setSizeCallbackEnabled = true
|
u.setSizeCallbackEnabled = true
|
||||||
|
|
||||||
setPosition := func() {
|
|
||||||
u.iwindow.setPosition(u.getInitWindowPosition())
|
|
||||||
}
|
|
||||||
setSize := func() {
|
setSize := func() {
|
||||||
ww, wh := u.getInitWindowSize()
|
ww, wh := u.getInitWindowSize()
|
||||||
ww = int(u.toGLFWPixel(float64(ww)))
|
ww = int(u.toGLFWPixel(float64(ww)))
|
||||||
@ -830,11 +827,11 @@ func (u *UserInterface) init() error {
|
|||||||
// but this should be inverted on Windows. This is very tricky, but there is no obvious way to solve
|
// but this should be inverted on Windows. This is very tricky, but there is no obvious way to solve
|
||||||
// this. This doesn't matter on macOS.
|
// this. This doesn't matter on macOS.
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
setPosition()
|
u.setWindowPosition(u.getInitWindowPosition())
|
||||||
setSize()
|
setSize()
|
||||||
} else {
|
} else {
|
||||||
setSize()
|
setSize()
|
||||||
setPosition()
|
u.setWindowPosition(u.getInitWindowPosition())
|
||||||
}
|
}
|
||||||
|
|
||||||
u.updateWindowSizeLimits()
|
u.updateWindowSizeLimits()
|
||||||
@ -1353,8 +1350,12 @@ func (u *UserInterface) Window() driver.Window {
|
|||||||
return &u.iwindow
|
return &u.iwindow
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) maximize() {
|
// GLFW's functions to manipulate a window can invoke the SetSize callback (#1576, #1585, #1606).
|
||||||
// Maximize invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
// As the callback must not be called in the frame (between BeginFrame and EndFrame),
|
||||||
|
// disable the callback temporarily.
|
||||||
|
|
||||||
|
// maximizeWindow must be called from the main thread.
|
||||||
|
func (u *UserInterface) maximizeWindow() {
|
||||||
if u.setSizeCallbackEnabled {
|
if u.setSizeCallbackEnabled {
|
||||||
u.setSizeCallbackEnabled = false
|
u.setSizeCallbackEnabled = false
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1368,8 +1369,8 @@ func (u *UserInterface) maximize() {
|
|||||||
u.setWindowSize(w, h, u.isFullscreen())
|
u.setWindowSize(w, h, u.isFullscreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) iconify() {
|
// iconifyWindow must be called from the main thread.
|
||||||
// Iconify invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
func (u *UserInterface) iconifyWindow() {
|
||||||
if u.setSizeCallbackEnabled {
|
if u.setSizeCallbackEnabled {
|
||||||
u.setSizeCallbackEnabled = false
|
u.setSizeCallbackEnabled = false
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1382,8 +1383,8 @@ func (u *UserInterface) iconify() {
|
|||||||
// Rather, the window size might be (0, 0) and it might be impossible to call setWindowSize (#1585).
|
// Rather, the window size might be (0, 0) and it might be impossible to call setWindowSize (#1585).
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) restore() {
|
// restoreWindow must be called from the main thread.
|
||||||
// Restore invokes the SetSize callback but the callback must not be called in the game's Update (#1576).
|
func (u *UserInterface) restoreWindow() {
|
||||||
if u.setSizeCallbackEnabled {
|
if u.setSizeCallbackEnabled {
|
||||||
u.setSizeCallbackEnabled = false
|
u.setSizeCallbackEnabled = false
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1397,9 +1398,8 @@ func (u *UserInterface) restore() {
|
|||||||
u.setWindowSize(w, h, u.isFullscreen())
|
u.setWindowSize(w, h, u.isFullscreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) setDecorated(decorated bool) {
|
// setWindowDecorated must be called from the main thread.
|
||||||
// SetAttrib with glfw.Decorated invokes the SetSize callback but the callback must not be called in the game's Update (#1586).
|
func (u *UserInterface) setWindowDecorated(decorated bool) {
|
||||||
// SetSize callback is invoked in the limited situations like just after restoring from the fullscreen mode.
|
|
||||||
if u.setSizeCallbackEnabled {
|
if u.setSizeCallbackEnabled {
|
||||||
u.setSizeCallbackEnabled = false
|
u.setSizeCallbackEnabled = false
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1412,7 +1412,75 @@ func (u *UserInterface) setDecorated(decorated bool) {
|
|||||||
}
|
}
|
||||||
u.window.SetAttrib(glfw.Decorated, v)
|
u.window.SetAttrib(glfw.Decorated, v)
|
||||||
|
|
||||||
// Just after restoring from the fullscreen mode, the window's size might be a wrong value on Windows.
|
// The title can be lost when the decoration is gone. Recover this.
|
||||||
// This was the cause to invoke SetSize callback unexpectedly. This sounds like a GLFW's issue, but this is not confirmed.
|
if decorated {
|
||||||
// As the window size should not be changed, setWindowSize doesn't have to be called anyway.
|
u.window.SetTitle(u.title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setWindowFloating must be called from the main thread.
|
||||||
|
func (u *UserInterface) setWindowFloating(floating bool) {
|
||||||
|
if u.setSizeCallbackEnabled {
|
||||||
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
v := glfw.False
|
||||||
|
if floating {
|
||||||
|
v = glfw.True
|
||||||
|
}
|
||||||
|
u.window.SetAttrib(glfw.Floating, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setWindowResizable must be called from the main thread.
|
||||||
|
func (u *UserInterface) setWindowResizable(resizable bool) {
|
||||||
|
if u.setSizeCallbackEnabled {
|
||||||
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
v := glfw.False
|
||||||
|
if resizable {
|
||||||
|
v = glfw.True
|
||||||
|
}
|
||||||
|
u.window.SetAttrib(glfw.Resizable, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setWindowPosition must be called from the main thread.
|
||||||
|
func (u *UserInterface) setWindowPosition(x, y int) {
|
||||||
|
if u.setSizeCallbackEnabled {
|
||||||
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
mx, my := currentMonitor(u.window).GetPos()
|
||||||
|
xf := u.toGLFWPixel(float64(x))
|
||||||
|
yf := u.toGLFWPixel(float64(y))
|
||||||
|
if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf)); u.isFullscreen() {
|
||||||
|
u.origPosX, u.origPosY = x, y
|
||||||
|
} else {
|
||||||
|
u.window.SetPos(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call setWindowSize explicitly in order to update the rendering since the callback is disabled now.
|
||||||
|
// This is necessary in some very limited cases (#1606).
|
||||||
|
w, h := u.window.GetSize()
|
||||||
|
u.setWindowSize(w, h, u.isFullscreen())
|
||||||
|
}
|
||||||
|
|
||||||
|
// setWindowTitle must be called from the main thread.
|
||||||
|
func (u *UserInterface) setWindowTitle(title string) {
|
||||||
|
if u.setSizeCallbackEnabled {
|
||||||
|
u.setSizeCallbackEnabled = false
|
||||||
|
defer func() {
|
||||||
|
u.setSizeCallbackEnabled = true
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
u.window.SetTitle(title)
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,7 @@ func (w *window) SetDecorated(decorated bool) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
w.ui.setDecorated(decorated)
|
w.ui.setWindowDecorated(decorated)
|
||||||
|
|
||||||
// The title can be lost when the decoration is gone. Recover this.
|
|
||||||
if decorated {
|
|
||||||
w.ui.window.SetTitle(w.ui.title)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -82,12 +77,7 @@ func (w *window) SetResizable(resizable bool) {
|
|||||||
if w.ui.isNativeFullscreen() {
|
if w.ui.isNativeFullscreen() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
w.ui.setWindowResizable(resizable)
|
||||||
v := glfw.False
|
|
||||||
if resizable {
|
|
||||||
v = glfw.True
|
|
||||||
}
|
|
||||||
w.ui.window.SetAttrib(glfw.Resizable, v)
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -113,12 +103,7 @@ func (w *window) SetFloating(floating bool) {
|
|||||||
if w.ui.isNativeFullscreen() {
|
if w.ui.isNativeFullscreen() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
w.ui.setWindowFloating(floating)
|
||||||
v := glfw.False
|
|
||||||
if floating {
|
|
||||||
v = glfw.True
|
|
||||||
}
|
|
||||||
w.ui.window.SetAttrib(glfw.Floating, v)
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -144,7 +129,7 @@ func (w *window) Maximize() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.ui.maximize()
|
w.ui.maximizeWindow()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -167,7 +152,7 @@ func (w *window) Minimize() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.ui.iconify()
|
w.ui.iconifyWindow()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -178,7 +163,7 @@ func (w *window) Restore() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.ui.restore()
|
w.ui.restoreWindow()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -212,23 +197,11 @@ func (w *window) SetPosition(x, y int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.setPosition(x, y)
|
w.ui.setWindowPosition(x, y)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPosition must be called from the main thread
|
|
||||||
func (w *window) setPosition(x, y int) {
|
|
||||||
mx, my := currentMonitor(w.ui.window).GetPos()
|
|
||||||
xf := w.ui.toGLFWPixel(float64(x))
|
|
||||||
yf := w.ui.toGLFWPixel(float64(y))
|
|
||||||
if x, y := w.ui.adjustWindowPosition(mx+int(xf), my+int(yf)); w.ui.isFullscreen() {
|
|
||||||
w.ui.origPosX, w.ui.origPosY = x, y
|
|
||||||
} else {
|
|
||||||
w.ui.window.SetPos(x, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *window) Size() (int, int) {
|
func (w *window) Size() (int, int) {
|
||||||
if !w.ui.isRunning() {
|
if !w.ui.isRunning() {
|
||||||
ww, wh := w.ui.getInitWindowSize()
|
ww, wh := w.ui.getInitWindowSize()
|
||||||
@ -282,7 +255,7 @@ func (w *window) SetTitle(title string) {
|
|||||||
}
|
}
|
||||||
w.ui.title = title
|
w.ui.title = title
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.ui.window.SetTitle(title)
|
w.ui.setWindowTitle(title)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user