internal/uidriver/glfw: Bug fix: More precise window size adjustment

Before this change, setWindowSize converts the size in device-
independent pixels once, invokes adjustWindowSizeBasedOnSizeLimitsInDP,
and then restore the values in device-dependent pixels. This might
introduce a slight error and then SetSize be unexpectedly invoked.
Such SetSize call with a slightly different size might not invoke
the FramebufferSize callback, and then this blocked forever when
maximizing the window.

This change fixes this by adjusting the size limits instead of the
window size so that the window size is not modified unexpectedly.

Closes #1577
This commit is contained in:
Hajime Hoshi 2021-04-18 00:56:35 +09:00
parent d6ab27a5a2
commit b5d4c834b8

View File

@ -245,6 +245,15 @@ func (u *UserInterface) setRunning(running bool) {
} }
} }
func (u *UserInterface) getWindowSizeLimits() (minw, minh, maxw, maxh int) {
u.m.RLock()
defer u.m.RUnlock()
return int(u.toGLFWPixel(float64(u.minWindowWidthInDP))),
int(u.toGLFWPixel(float64(u.minWindowHeightInDP))),
int(u.toGLFWPixel(float64(u.maxWindowWidthInDP))),
int(u.toGLFWPixel(float64(u.maxWindowHeightInDP)))
}
func (u *UserInterface) getWindowSizeLimitsInDP() (minw, minh, maxw, maxh int) { func (u *UserInterface) getWindowSizeLimitsInDP() (minw, minh, maxw, maxh int) {
u.m.RLock() u.m.RLock()
defer u.m.RUnlock() defer u.m.RUnlock()
@ -1028,6 +1037,25 @@ func (u *UserInterface) updateWindowSizeLimits() {
u.window.SetSizeLimits(minw, minh, maxw, maxh) u.window.SetSizeLimits(minw, minh, maxw, maxh)
} }
// adjustWindowSizeBasedOnSizeLimitsInDP adjust the size based on the window size limits.
// width and height are in device-dependent pixels.
func (u *UserInterface) adjustWindowSizeBasedOnSizeLimits(width, height int) (int, int) {
minw, minh, maxw, maxh := u.getWindowSizeLimits()
if minw >= 0 && width < minw {
width = minw
}
if minh >= 0 && height < minh {
height = minh
}
if maxw >= 0 && width > maxw {
width = maxw
}
if maxh >= 0 && height > maxh {
height = maxh
}
return width, height
}
// adjustWindowSizeBasedOnSizeLimitsInDP adjust the size based on the window size limits. // adjustWindowSizeBasedOnSizeLimitsInDP adjust the size based on the window size limits.
// width and height are in device-independent pixels. // width and height are in device-independent pixels.
func (u *UserInterface) adjustWindowSizeBasedOnSizeLimitsInDP(width, height int) (int, int) { func (u *UserInterface) adjustWindowSizeBasedOnSizeLimitsInDP(width, height int) (int, int) {
@ -1049,11 +1077,7 @@ func (u *UserInterface) adjustWindowSizeBasedOnSizeLimitsInDP(width, height int)
// setWindowSize must be called from the main thread. // setWindowSize must be called from the main thread.
func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) { func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
wdp := int(u.fromGLFWPixel(float64(width))) width, height = u.adjustWindowSizeBasedOnSizeLimits(width, height)
hdp := int(u.fromGLFWPixel(float64(height)))
wdp, hdp = u.adjustWindowSizeBasedOnSizeLimitsInDP(wdp, hdp)
width = int(u.toGLFWPixel(float64(wdp)))
height = int(u.toGLFWPixel(float64(hdp)))
if u.windowWidth == width && u.windowHeight == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == u.deviceScaleFactor() { if u.windowWidth == width && u.windowHeight == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == u.deviceScaleFactor() {
return return