From ac2b3620b93c7f6df055438908b8dbf207e31e18 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 18 Apr 2021 17:35:46 +0900 Subject: [PATCH] internal/uidriver/glfw: Bug fix: Crash on some operations on native fullscreen mode (macOS) This change forbids some operations when the wiindow is natively fullscreened on macOS in order to avoid crashes. Closes #1578 --- internal/uidriver/glfw/ui.go | 5 +++++ internal/uidriver/glfw/ui_darwin.go | 9 +++++++++ internal/uidriver/glfw/ui_unix.go | 4 ++++ internal/uidriver/glfw/ui_windows.go | 4 ++++ internal/uidriver/glfw/window.go | 12 ++++++++++++ run.go | 3 +++ window.go | 9 +++++++++ 7 files changed, 46 insertions(+) diff --git a/internal/uidriver/glfw/ui.go b/internal/uidriver/glfw/ui.go index 5b356f290..57af06d4d 100644 --- a/internal/uidriver/glfw/ui.go +++ b/internal/uidriver/glfw/ui.go @@ -432,13 +432,18 @@ func (u *UserInterface) SetFullscreen(fullscreen bool) { } var update bool + var nativeFullscreen bool _ = u.t.Call(func() error { update = u.isFullscreen() != fullscreen + nativeFullscreen = u.isNativeFullscreen() return nil }) if !update { return } + if nativeFullscreen { + return + } var w, h int _ = u.t.Call(func() error { diff --git a/internal/uidriver/glfw/ui_darwin.go b/internal/uidriver/glfw/ui_darwin.go index f1e26af0b..0689a03fe 100644 --- a/internal/uidriver/glfw/ui_darwin.go +++ b/internal/uidriver/glfw/ui_darwin.go @@ -38,6 +38,11 @@ package glfw // *x = bounds.origin.x; // *y = bounds.origin.y; // } +// +// static bool isNativeFullscreen() { +// return [[NSApplication sharedApplication] currentSystemPresentationOptions] & +// NSApplicationPresentationFullScreen; +// } import "C" import ( @@ -82,3 +87,7 @@ func currentMonitorByOS(w *glfw.Window) *glfw.Monitor { func (u *UserInterface) nativeWindow() uintptr { return u.window.GetCocoaWindow() } + +func (u *UserInterface) isNativeFullscreen() bool { + return bool(C.isNativeFullscreen()) +} diff --git a/internal/uidriver/glfw/ui_unix.go b/internal/uidriver/glfw/ui_unix.go index e9c45f36d..9d9a21ebb 100644 --- a/internal/uidriver/glfw/ui_unix.go +++ b/internal/uidriver/glfw/ui_unix.go @@ -61,3 +61,7 @@ func (u *UserInterface) nativeWindow() uintptr { // TODO: Implement this. return 0 } + +func (u *UserInterface) isNativeFullscreen() bool { + return false +} diff --git a/internal/uidriver/glfw/ui_windows.go b/internal/uidriver/glfw/ui_windows.go index 341f42d7a..3d9257fce 100644 --- a/internal/uidriver/glfw/ui_windows.go +++ b/internal/uidriver/glfw/ui_windows.go @@ -182,3 +182,7 @@ func currentMonitorByOS(_ *glfw.Window) *glfw.Monitor { func (u *UserInterface) nativeWindow() uintptr { return u.window.GetWin32Window() } + +func (u *UserInterface) isNativeFullscreen() bool { + return false +} diff --git a/internal/uidriver/glfw/window.go b/internal/uidriver/glfw/window.go index 290fba4fe..43e2fbc67 100644 --- a/internal/uidriver/glfw/window.go +++ b/internal/uidriver/glfw/window.go @@ -48,6 +48,10 @@ func (w *window) SetDecorated(decorated bool) { } _ = w.ui.t.Call(func() error { + if w.ui.isNativeFullscreen() { + return nil + } + v := glfw.False if decorated { v = glfw.True @@ -80,6 +84,10 @@ func (w *window) SetResizable(resizable bool) { return } _ = w.ui.t.Call(func() error { + if w.ui.isNativeFullscreen() { + return nil + } + v := glfw.False if resizable { v = glfw.True @@ -107,6 +115,10 @@ func (w *window) SetFloating(floating bool) { return } _ = w.ui.t.Call(func() error { + if w.ui.isNativeFullscreen() { + return nil + } + v := glfw.False if floating { v = glfw.True diff --git a/run.go b/run.go index 991c048a6..b3ef8ab5c 100644 --- a/run.go +++ b/run.go @@ -254,6 +254,9 @@ func IsFullscreen() bool { // // SetFullscreen does nothing on browsers or mobiles. // +// SetFullscreen does nothing on macOS when the window is fullscreened natively by the macOS desktop +// instead of SetFullscreen(true). +// // SetFullscreen is concurrent-safe. func SetFullscreen(fullscreen bool) { uiDriver().SetFullscreen(fullscreen) diff --git a/window.go b/window.go index 5ede13cc5..cf128403c 100644 --- a/window.go +++ b/window.go @@ -42,6 +42,9 @@ func IsWindowDecorated() bool { // SetWindowDecorated works only on desktops. // SetWindowDecorated does nothing on other platforms. // +// SetWindowDecorated does nothing on macOS when the window is fullscreened natively by the macOS desktop +// instead of SetFullscreen(true). +// // SetWindowDecorated is concurrent-safe. func SetWindowDecorated(decorated bool) { if w := uiDriver().Window(); w != nil { @@ -67,6 +70,9 @@ func IsWindowResizable() bool { // // If SetWindowResizable is called with true and Run is used, SetWindowResizable panics. Use RunGame instead. // +// SetWindowResizable does nothing on macOS when the window is fullscreened natively by the macOS desktop +// instead of SetFullscreen(true). +// // SetWindowResizable is concurrent-safe. func SetWindowResizable(resizable bool) { theUIContext.setWindowResizable(resizable) @@ -251,6 +257,9 @@ func IsWindowFloating() bool { // // SetWindowFloating does nothing on browsers or mobiles. // +// SetWindowFloating does nothing on macOS when the window is fullscreened natively by the macOS desktop +// instead of SetFullscreen(true). +// // SetWindowFloating is concurrent-safe. func SetWindowFloating(float bool) { if w := uiDriver().Window(); w != nil {