internal/ui: bug fix: use correct regions at (*monitors).monitorFromPosition

Updates #2781
This commit is contained in:
Hajime Hoshi 2023-09-30 00:20:59 +09:00
parent 2fbef2106d
commit aab22f4c1e
6 changed files with 37 additions and 40 deletions

View File

@ -17,6 +17,7 @@
package ui
import (
"image"
"sync"
"sync/atomic"
@ -30,10 +31,7 @@ type Monitor struct {
id int
name string
x int
y int
widthInDIP float64
heightInDIP float64
boundsInGLFWPixels image.Rectangle
contentScale float64
}
@ -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,16 +138,14 @@ 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,
boundsInGLFWPixels: b,
contentScale: contentScale,
})
}

View File

@ -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() {

View File

@ -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 {

View File

@ -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()
}

View File

@ -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
}
}

View File

@ -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)