From 0bcee31a6f94ad634b45d52ab5be8c2e3dc5c9f1 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 29 Sep 2023 12:20:07 +0900 Subject: [PATCH] internal/ui: bug fix: wrong monitor initialization on macOS This change fixes these issues: * `currentMouseLocation()` returned a position in the macOS native coordinate. This means the Y axis is upward, while the Y axis is downward in the GLFW coordinate. This change adjusts the Y position. * `(*monitors).monitorFromGLFWMonitor` always returned nil at least on macOS. This change replaces this with a new method `(*monitors).primaryMonitor`. Updates #807 Closes #2794 --- internal/ui/monitor_glfw.go | 13 ++++++------- internal/ui/ui_glfw.go | 4 ++-- internal/ui/ui_glfw_darwin.go | 15 ++++++++++++--- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/ui/monitor_glfw.go b/internal/ui/monitor_glfw.go index 7897056c8..a3580affe 100644 --- a/internal/ui/monitor_glfw.go +++ b/internal/ui/monitor_glfw.go @@ -79,16 +79,15 @@ func (m *monitors) append(ms []*Monitor) []*Monitor { return append(ms, m.monitors...) } -func (m *monitors) monitorFromGLFWMonitor(glfwMonitor *glfw.Monitor) *Monitor { +func (m *monitors) primaryMonitor() *Monitor { + if atomic.LoadInt32(&m.updateCalled) == 0 { + panic("ui: (*monitors).primaryMonitor must be called before (*monitors).append is called") + } + m.m.Lock() defer m.m.Unlock() - for _, m := range m.monitors { - if m.m == glfwMonitor { - return m - } - } - return nil + return m.monitors[0] } func (m *monitors) monitorFromID(id int) *Monitor { diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index 9d7c02c5e..7ccc354c1 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -172,7 +172,7 @@ func initialize() error { return err } if m == nil { - m = theMonitors.monitorFromGLFWMonitor(glfw.GetPrimaryMonitor()) + m = theMonitors.primaryMonitor() } // GetPrimaryMonitor might return nil in theory (#1887). @@ -1479,7 +1479,7 @@ func (u *userInterfaceImpl) currentMonitor() *Monitor { return m } - return theMonitors.monitorFromGLFWMonitor(glfw.GetPrimaryMonitor()) + return theMonitors.primaryMonitor() } func (u *userInterfaceImpl) readInputState(inputState *InputState) { diff --git a/internal/ui/ui_glfw_darwin.go b/internal/ui/ui_glfw_darwin.go index 5dc3eedd7..05e6cf12f 100644 --- a/internal/ui/ui_glfw_darwin.go +++ b/internal/ui/ui_glfw_darwin.go @@ -239,7 +239,7 @@ var ( sel_windowWillExitFullScreen = objc.RegisterName("windowWillExitFullScreen:") ) -func currentMouseLocation() (x, y int) { +func currentMouseLocationInDIP() (x, y int) { sig := cocoa.NSMethodSignature_signatureWithObjCTypes("{NSPoint=dd}@:") inv := cocoa.NSInvocation_invocationWithMethodSignature(sig) inv.SetTarget(objc.ID(class_NSEvent)) @@ -247,11 +247,20 @@ func currentMouseLocation() (x, y int) { inv.Invoke() var point cocoa.NSPoint inv.GetReturnValue(unsafe.Pointer(&point)) - return int(point.X), int(point.Y) + + // On macOS, the unit of GLFW (OS-native) pixels' scale and device-independent pixels's scale are the same. + // The monitor sizes' scales are also the same. + x, y = int(point.X), int(point.Y) + + // On macOS, the Y axis is upward. Adjust the Y position (#807, #2794). + y = -y + m := theMonitors.primaryMonitor() + y += m.videoMode.Height + return x, y } func initialMonitorByOS() (*Monitor, error) { - x, y := currentMouseLocation() + x, y := currentMouseLocationInDIP() // Find the monitor including the cursor. for _, m := range theMonitors.append(nil) {