From 07480ed66d6bf08af5659a219642d0c3b29cb6e4 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 23 Aug 2020 23:37:58 +0900 Subject: [PATCH] uidriver/glfw: Add better fallbacks for currentMonitorFromPosition Updates #1119 --- internal/uidriver/glfw/ui.go | 11 ++++++----- internal/uidriver/glfw/ui_darwin.go | 18 ++++++++++-------- internal/uidriver/glfw/ui_windows.go | 16 +++++++++++----- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/internal/uidriver/glfw/ui.go b/internal/uidriver/glfw/ui.go index 734807076..b29fa8937 100644 --- a/internal/uidriver/glfw/ui.go +++ b/internal/uidriver/glfw/ui.go @@ -1094,12 +1094,13 @@ func (u *UserInterface) updateVsync() { // // currentMonitor must be called on the main thread. func (u *UserInterface) currentMonitor() *glfw.Monitor { - if w := u.window; w != nil { - // GetMonitor is available only on fullscreen. - if m := w.GetMonitor(); m != nil { - return m - } + // GetMonitor is available only on fullscreen. + if m := u.window.GetMonitor(); m != nil { + return m } + + // Getting a monitor from a window position is not reliable in general (e.g., when a window is put across + // multiple monitors). // Get the monitor which the current window belongs to. This requires OS API. return u.currentMonitorFromPosition() } diff --git a/internal/uidriver/glfw/ui_darwin.go b/internal/uidriver/glfw/ui_darwin.go index 89da75b69..eb1f3ae43 100644 --- a/internal/uidriver/glfw/ui_darwin.go +++ b/internal/uidriver/glfw/ui_darwin.go @@ -59,16 +59,18 @@ func (u *UserInterface) currentMonitorFromPosition() *glfw.Monitor { x := C.int(0) y := C.int(0) // Note: [NSApp mainWindow] is nil when it doesn't have its border. Use u.window here. - if u.window != nil { - win := u.window.GetCocoaWindow() - C.currentMonitorPos(win, &x, &y) - for _, m := range glfw.GetMonitors() { - mx, my := m.GetPos() - if int(x) == mx && int(y) == my { - return m - } + win := u.window.GetCocoaWindow() + C.currentMonitorPos(win, &x, &y) + for _, m := range glfw.GetMonitors() { + mx, my := m.GetPos() + if int(x) == mx && int(y) == my { + return m } } + + if m, ok := getCachedMonitor(u.window.GetPos()); ok { + return m.m + } return glfw.GetPrimaryMonitor() } diff --git a/internal/uidriver/glfw/ui_windows.go b/internal/uidriver/glfw/ui_windows.go index 17c7a5bb7..cf05e70fb 100644 --- a/internal/uidriver/glfw/ui_windows.go +++ b/internal/uidriver/glfw/ui_windows.go @@ -121,6 +121,13 @@ func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) { } func (u *UserInterface) currentMonitorFromPosition() *glfw.Monitor { + fallback := func() *glfw.Monitor { + if m, ok := getCachedMonitor(u.window.GetPos()); ok { + return m.m + } + return glfw.GetPrimaryMonitor() + } + // TODO: Should we use u.window.GetWin32Window() here? w, err := getActiveWindow() if err != nil { @@ -134,9 +141,8 @@ func (u *UserInterface) currentMonitorFromPosition() *glfw.Monitor { panic(err) } if w == 0 { - // GetForegroundWindow can return null according to the document. Use - // the primary monitor instead. - return glfw.GetPrimaryMonitor() + // GetForegroundWindow can return null according to the document. + return fallback() } } @@ -146,7 +152,7 @@ func (u *UserInterface) currentMonitorFromPosition() *glfw.Monitor { m, err := monitorFromWindow(w, monitorDefaultToNearest) if err != nil { // monitorFromWindow can return error on Wine. Ignore this. - return glfw.GetPrimaryMonitor() + return fallback() } mi := monitorInfo{} @@ -162,7 +168,7 @@ func (u *UserInterface) currentMonitorFromPosition() *glfw.Monitor { return m } } - return glfw.GetPrimaryMonitor() + return fallback() } func (u *UserInterface) nativeWindow() unsafe.Pointer {