internal/ui: refactoring: separate setWindowSizeInDIPImpl to setWindowSizeInDIP and setFullscreen

This commit is contained in:
Hajime Hoshi 2022-09-25 22:51:09 +09:00
parent f0dbf86799
commit 70ebd34d99
4 changed files with 62 additions and 44 deletions

View File

@ -737,7 +737,7 @@ func (u *userInterfaceImpl) registerWindowSetSizeCallback() {
return return
} }
u.adjustViewSize() u.adjustViewSizeAfterFullscreen()
if u.window.GetAttrib(glfw.Resizable) == glfw.False { if u.window.GetAttrib(glfw.Resizable) == glfw.False {
return return
@ -1272,11 +1272,22 @@ func (u *userInterfaceImpl) setWindowSizeInDIP(width, height int) {
}() }()
} }
u.setWindowSizeInDIPImpl(width, height, u.isFullscreen()) if !u.isFullscreen() {
// Set the window size after the position. The order matters.
// In the opposite order, the window size might not be correct when going back from fullscreen with multi monitors.
oldW, oldH := u.window.GetSize()
newW := int(u.dipToGLFWPixel(float64(width), u.currentMonitor()))
newH := int(u.dipToGLFWPixel(float64(height), u.currentMonitor()))
if oldW != newW || oldH != newH {
// Just after SetSize, GetSize is not reliable especially on Linux/UNIX.
// Let's wait for FramebufferSize callback in any cases.
u.waitForFramebufferSizeCallback(u.window, func() {
u.window.SetSize(newW, newH)
})
}
}
u.updateWindowSizeLimits() u.updateWindowSizeLimits()
u.adjustViewSize()
} }
// setFullscreen must be called from the main thread. // setFullscreen must be called from the main thread.
@ -1285,27 +1296,19 @@ func (u *userInterfaceImpl) setFullscreen(fullscreen bool) {
return return
} }
u.graphicsDriver.SetFullscreen(fullscreen) u.graphicsDriver.SetFullscreen(fullscreen)
u.setWindowSizeInDIPImpl(u.origWindowWidthInDIP, u.origWindowHeightInDIP, fullscreen)
}
func (u *userInterfaceImpl) minimumWindowWidth() int { // Disable the callback of SetSize. This callback can be invoked by SetMonitor or SetSize.
if u.window.GetAttrib(glfw.Decorated) == glfw.False { // ForceUpdateFrame is called from the callback.
return 1 // While setWindowSize can be called from UpdateFrame,
// calling ForceUpdateFrame inside UpdateFrame is illegal (#1505).
if u.setSizeCallbackEnabled {
u.setSizeCallbackEnabled = false
defer func() {
u.setSizeCallbackEnabled = true
}()
} }
// On Windows, giving a too small width doesn't call a callback (#165). // Enter the fullscreen.
// To prevent hanging up, return asap if the width is too small.
// 126 is an arbitrary number and I guess this is small enough .
if runtime.GOOS == "windows" {
return 126
}
// On macOS, resizing the window by cursor sometimes ignores the minimum size.
// To avoid the flaky behavior, do not add a limitation.
return 1
}
func (u *userInterfaceImpl) setWindowSizeInDIPImpl(width, height int, fullscreen bool) {
if fullscreen { if fullscreen {
if x, y := u.origWindowPos(); x == invalidPos || y == invalidPos { if x, y := u.origWindowPos(); x == invalidPos || y == invalidPos {
u.setOrigWindowPos(u.window.GetPos()) u.setOrigWindowPos(u.window.GetPos())
@ -1329,27 +1332,29 @@ func (u *userInterfaceImpl) setWindowSizeInDIPImpl(width, height int, fullscreen
u.swapBuffers() u.swapBuffers()
} }
} }
u.adjustViewSizeAfterFullscreen()
return return
} }
// Exit the fullscreen.
// Get the original window position and size before changing the state of fullscreen. // Get the original window position and size before changing the state of fullscreen.
// TODO: Why?
origX, origY := u.origWindowPos() origX, origY := u.origWindowPos()
wasFullscreen := u.isFullscreen() ww := int(u.dipToGLFWPixel(float64(u.origWindowWidthInDIP), u.currentMonitor()))
if u.isNativeFullscreenAvailable() && u.isNativeFullscreen() { wh := int(u.dipToGLFWPixel(float64(u.origWindowHeightInDIP), u.currentMonitor()))
if u.isNativeFullscreenAvailable() {
u.setNativeFullscreen(false) u.setNativeFullscreen(false)
// Adjust the window size later (after adjusting the position).
} else if !u.isNativeFullscreenAvailable() && u.window.GetMonitor() != nil { } else if !u.isNativeFullscreenAvailable() && u.window.GetMonitor() != nil {
ww := int(u.dipToGLFWPixel(float64(width), u.currentMonitor()))
wh := int(u.dipToGLFWPixel(float64(height), u.currentMonitor()))
u.window.SetMonitor(nil, 0, 0, ww, wh, 0) u.window.SetMonitor(nil, 0, 0, ww, wh, 0)
glfw.PollEvents() glfw.PollEvents()
u.swapBuffers() u.swapBuffers()
} }
if wasFullscreen { // glfw.PollEvents is necessary for macOS to enable (*glfw.Window).SetPos and SetSize (#2296).
// glfw.PollEvents is necessary for macOS to enable (*glfw.Window).SetPos and SetSize (#2296). glfw.PollEvents()
glfw.PollEvents()
}
if origX != invalidPos && origY != invalidPos { if origX != invalidPos && origY != invalidPos {
u.window.SetPos(origX, origY) u.window.SetPos(origX, origY)
@ -1362,20 +1367,30 @@ func (u *userInterfaceImpl) setWindowSizeInDIPImpl(width, height int, fullscreen
u.setOrigWindowPos(invalidPos, invalidPos) u.setOrigWindowPos(invalidPos, invalidPos)
} }
// Set the window size after the position. The order matters. if u.isNativeFullscreenAvailable() {
// In the opposite order, the window size might not be correct when going back from fullscreen with multi monitors. // Set the window size after the position. The order matters.
oldW, oldH := u.window.GetSize() // In the opposite order, the window size might not be correct when going back from fullscreen with multi monitors.
newW := int(u.dipToGLFWPixel(float64(width), u.currentMonitor())) u.window.SetSize(ww, wh)
newH := int(u.dipToGLFWPixel(float64(height), u.currentMonitor()))
if oldW != newW || oldH != newH {
// Just after SetSize, GetSize is not reliable especially on Linux/UNIX.
// Let's wait for FramebufferSize callback in any cases.
u.waitForFramebufferSizeCallback(u.window, func() {
u.window.SetSize(newW, newH)
})
} }
} }
func (u *userInterfaceImpl) minimumWindowWidth() int {
if u.window.GetAttrib(glfw.Decorated) == glfw.False {
return 1
}
// On Windows, giving a too small width doesn't call a callback (#165).
// To prevent hanging up, return asap if the width is too small.
// 126 is an arbitrary number and I guess this is small enough .
if runtime.GOOS == "windows" {
return 126
}
// On macOS, resizing the window by cursor sometimes ignores the minimum size.
// To avoid the flaky behavior, do not add a limitation.
return 1
}
// updateVsync must be called on the main thread. // updateVsync must be called on the main thread.
func (u *userInterfaceImpl) updateVsync() { func (u *userInterfaceImpl) updateVsync() {
if u.graphicsDriver.IsGL() { if u.graphicsDriver.IsGL() {

View File

@ -290,14 +290,16 @@ func (u *userInterfaceImpl) setNativeFullscreen(fullscreen bool) {
} }
} }
func (u *userInterfaceImpl) adjustViewSize() { func (u *userInterfaceImpl) adjustViewSizeAfterFullscreen() {
if u.graphicsDriver.IsGL() { if u.graphicsDriver.IsGL() {
return return
} }
window := cocoa.NSWindow{ID: objc.ID(u.window.GetCocoaWindow())} window := cocoa.NSWindow{ID: objc.ID(u.window.GetCocoaWindow())}
if window.StyleMask()&cocoa.NSWindowStyleMaskFullScreen == 0 { if window.StyleMask()&cocoa.NSWindowStyleMaskFullScreen == 0 {
return return
} }
// Apparently, adjusting the view size is not needed as of macOS 12 (#1745). // Apparently, adjusting the view size is not needed as of macOS 12 (#1745).
if cocoa.NSProcessInfo_processInfo().IsOperatingSystemAtLeastVersion(cocoa.NSOperatingSystemVersion{ if cocoa.NSProcessInfo_processInfo().IsOperatingSystemAtLeastVersion(cocoa.NSOperatingSystemVersion{
Major: 12, Major: 12,
@ -315,6 +317,7 @@ func (u *userInterfaceImpl) adjustViewSize() {
} }
viewSize.Width-- viewSize.Width--
view.SetFrameSize(viewSize) view.SetFrameSize(viewSize)
// NSColor.blackColor (0, 0, 0, 1) didn't work. // NSColor.blackColor (0, 0, 0, 1) didn't work.
// Use the transparent color instead. // Use the transparent color instead.
window.SetBackgroundColor(cocoa.NSColor_colorWithSRGBRedGreenBlueAlpha(0, 0, 0, 0)) window.SetBackgroundColor(cocoa.NSColor_colorWithSRGBRedGreenBlueAlpha(0, 0, 0, 0))

View File

@ -214,7 +214,7 @@ func (u *userInterfaceImpl) setNativeFullscreen(fullscreen bool) {
panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS)) panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS))
} }
func (u *userInterfaceImpl) adjustViewSize() { func (u *userInterfaceImpl) adjustViewSizeAfterFullscreen() {
} }
func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) { func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) {

View File

@ -178,7 +178,7 @@ func (u *userInterfaceImpl) setNativeFullscreen(fullscreen bool) {
panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS)) panic(fmt.Sprintf("ui: setNativeFullscreen is not implemented in this environment: %s", runtime.GOOS))
} }
func (u *userInterfaceImpl) adjustViewSize() { func (u *userInterfaceImpl) adjustViewSizeAfterFullscreen() {
} }
func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) { func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) {