From aab22f4c1e1cee6c6e0eec8953c943af91e14cac Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 30 Sep 2023 00:20:59 +0900 Subject: [PATCH] internal/ui: bug fix: use correct regions at (*monitors).monitorFromPosition Updates #2781 --- internal/ui/monitor_glfw.go | 37 ++++++++++++++++------------------ internal/ui/ui_glfw.go | 7 +++++-- internal/ui/ui_glfw_darwin.go | 8 ++++---- internal/ui/ui_glfw_linbsd.go | 6 ------ internal/ui/ui_glfw_windows.go | 15 ++++++++------ internal/ui/window_glfw.go | 4 ++-- 6 files changed, 37 insertions(+), 40 deletions(-) diff --git a/internal/ui/monitor_glfw.go b/internal/ui/monitor_glfw.go index 753fde204..247de3759 100644 --- a/internal/ui/monitor_glfw.go +++ b/internal/ui/monitor_glfw.go @@ -17,6 +17,7 @@ package ui import ( + "image" "sync" "sync/atomic" @@ -28,13 +29,10 @@ type Monitor struct { m *glfw.Monitor videoMode *glfw.VidMode - id int - name string - x int - y int - widthInDIP float64 - heightInDIP float64 - contentScale float64 + id int + name string + boundsInGLFWPixels image.Rectangle + contentScale float64 } // Name returns the monitor's name. @@ -52,7 +50,8 @@ func (m *Monitor) deviceScaleFactor() float64 { } func (m *Monitor) sizeInDIP() (float64, float64) { - return m.widthInDIP, m.heightInDIP + w, h := m.boundsInGLFWPixels.Dx(), m.boundsInGLFWPixels.Dy() + return dipFromGLFWPixel(float64(w), m), dipFromGLFWPixel(float64(h), m) } type monitors struct { @@ -106,8 +105,8 @@ func (m *monitors) monitorFromPosition(x, y int) *Monitor { for _, m := range m.monitors { // Use an inclusive range. On macOS, the cursor position can take this range (#2794). - // TODO: Fix incorrectness in the cases of https://github.com/glfw/glfw/issues/1961. - if m.x <= x && x <= m.x+m.videoMode.Width && m.y <= y && y <= m.y+m.videoMode.Height { + b := m.boundsInGLFWPixels + if b.Min.X <= x && x <= b.Max.X && b.Min.Y <= y && y <= b.Max.Y { return m } } @@ -139,17 +138,15 @@ func (m *monitors) update() { break } - w, h := glfwMonitorSizeInDIP(m, contentScale) + w, h := glfwMonitorSizeInGLFWPixels(m) + b := image.Rect(x, y, x+w, y+h) newMonitors = append(newMonitors, &Monitor{ - m: m, - videoMode: m.GetVideoMode(), - id: i, - name: m.GetName(), - x: x, - y: y, - widthInDIP: w, - heightInDIP: h, - contentScale: contentScale, + m: m, + videoMode: m.GetVideoMode(), + id: i, + name: m.GetName(), + boundsInGLFWPixels: b, + contentScale: contentScale, }) } diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index 7ccc354c1..70db35be0 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -279,11 +279,13 @@ func (u *userInterfaceImpl) setWindowMonitor(monitor *Monitor) { w := dipToGLFWPixel(float64(ww), monitor) h := dipToGLFWPixel(float64(wh), monitor) + mx := monitor.boundsInGLFWPixels.Min.X + my := monitor.boundsInGLFWPixels.Min.Y mw, mh := monitor.sizeInDIP() mw = dipToGLFWPixel(mw, monitor) mh = dipToGLFWPixel(mh, monitor) px, py := InitialWindowPosition(int(mw), int(mh), int(w), int(h)) - u.window.SetPos(monitor.x+px, monitor.y+py) + u.window.SetPos(mx+px, my+py) if fullscreen { // Calling setFullscreen immediately might not work well, especially on Linux (#2778). @@ -1609,7 +1611,8 @@ func (u *userInterfaceImpl) setWindowPositionInDIP(x, y int, monitor *Monitor) { return } - mx, my := monitor.x, monitor.y + mx := monitor.boundsInGLFWPixels.Min.X + my := monitor.boundsInGLFWPixels.Min.Y xf := dipToGLFWPixel(float64(x), monitor) yf := dipToGLFWPixel(float64(y), monitor) if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf), monitor); u.isFullscreen() { diff --git a/internal/ui/ui_glfw_darwin.go b/internal/ui/ui_glfw_darwin.go index a4e912619..1c62104c8 100644 --- a/internal/ui/ui_glfw_darwin.go +++ b/internal/ui/ui_glfw_darwin.go @@ -184,10 +184,10 @@ func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) { return metal.NewGraphics() } -// glfwMonitorSizeInDIP must be called from the main thread. -func glfwMonitorSizeInDIP(monitor *glfw.Monitor, contentScale float64) (float64, float64) { - vm := monitor.GetVideoMode() - return float64(vm.Width), float64(vm.Height) +// glfwMonitorSizeInGLFWPixels must be called from the main thread. +func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { + vm := m.GetVideoMode() + return vm.Width, vm.Height } func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { diff --git a/internal/ui/ui_glfw_linbsd.go b/internal/ui/ui_glfw_linbsd.go index bc0349ffb..19ea2eb20 100644 --- a/internal/ui/ui_glfw_linbsd.go +++ b/internal/ui/ui_glfw_linbsd.go @@ -106,12 +106,6 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { return physWidth, physHeight } -// glfwMonitorSizeInDIP must be called from the main thread. -func glfwMonitorSizeInDIP(monitor *glfw.Monitor, contentScale float64) (float64, float64) { - w, h := glfwMonitorSizeInGLFWPixels(monitor) - return float64(w) / contentScale, float64(h) / contentScale -} - func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { return x / monitor.deviceScaleFactor() } diff --git a/internal/ui/ui_glfw_windows.go b/internal/ui/ui_glfw_windows.go index a09a04e4a..701401acf 100644 --- a/internal/ui/ui_glfw_windows.go +++ b/internal/ui/ui_glfw_windows.go @@ -86,10 +86,10 @@ func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) { return nil, nil } -// glfwMonitorSizeInDIP must be called from the main thread. -func glfwMonitorSizeInDIP(monitor *glfw.Monitor, contentScale float64) (float64, float64) { - vm := monitor.GetVideoMode() - return float64(vm.Width) / contentScale, float64(vm.Height) / contentScale +// glfwMonitorSizeInGLFWPixels must be called from the main thread. +func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { + vm := m.GetVideoMode() + return vm.Width, vm.Height } func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { @@ -105,7 +105,8 @@ func (u *userInterfaceImpl) adjustWindowPosition(x, y int, monitor *Monitor) (in return x, y } - mx, my := monitor.x, monitor.y + mx := monitor.boundsInGLFWPixels.Min.X + my := monitor.boundsInGLFWPixels.Min.Y // As the video width/height might be wrong, // adjust x/y at least to enable to handle the window (#328) if x < mx { @@ -163,7 +164,9 @@ func monitorFromWin32Window(w windows.HWND) *Monitor { x, y := int(mi.rcMonitor.left), int(mi.rcMonitor.top) for _, m := range theMonitors.append(nil) { - if m.x == x && m.y == y { + mx := m.boundsInGLFWPixels.Min.X + my := m.boundsInGLFWPixels.Min.Y + if mx == x && my == y { return m } } diff --git a/internal/ui/window_glfw.go b/internal/ui/window_glfw.go index c7b195686..b54db5cee 100644 --- a/internal/ui/window_glfw.go +++ b/internal/ui/window_glfw.go @@ -264,8 +264,8 @@ func (w *glfwWindow) Position() (int, int) { wx, wy = w.ui.window.GetPos() } m := w.ui.currentMonitor() - wx -= m.x - wy -= m.y + wx -= m.boundsInGLFWPixels.Min.X + wy -= m.boundsInGLFWPixels.Min.Y xf := dipFromGLFWPixel(float64(wx), m) yf := dipFromGLFWPixel(float64(wy), m) x, y = int(xf), int(yf)