mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 18:52:44 +01:00
internal/uidriver/glfw: Bug fix: Get the correct initial monitor and its scale
Before this fix, Win32API is used to get the current monitor. This might not work and return an unexpected monitor on some machines after the runloop starts. Instead, use the current window to get the current monitor correctly instead of the Win32APIs. To get the initial monitor, the API ForegroundWindow is still used. Updates #1584 Updates #1844
This commit is contained in:
parent
69087cdc40
commit
fcd8a6c653
@ -304,9 +304,10 @@ func (i *Input) update(window *glfw.Window, context driver.UIContext) {
|
|||||||
}
|
}
|
||||||
cx, cy := window.GetCursorPos()
|
cx, cy := window.GetCursorPos()
|
||||||
// TODO: This is tricky. Rename the function?
|
// TODO: This is tricky. Rename the function?
|
||||||
s := i.ui.deviceScaleFactor()
|
m := i.ui.currentMonitor()
|
||||||
cx = i.ui.fromGLFWPixel(cx)
|
s := i.ui.deviceScaleFactor(m)
|
||||||
cy = i.ui.fromGLFWPixel(cy)
|
cx = i.ui.fromGLFWPixel(cx, m)
|
||||||
|
cy = i.ui.fromGLFWPixel(cy, m)
|
||||||
cx, cy = context.AdjustPosition(cx, cy, s)
|
cx, cy = context.AdjustPosition(cx, cy, s)
|
||||||
|
|
||||||
// AdjustPosition can return NaN at the initialization.
|
// AdjustPosition can return NaN at the initialization.
|
||||||
|
@ -187,12 +187,11 @@ func initialize() error {
|
|||||||
defer w.Destroy()
|
defer w.Destroy()
|
||||||
initializeWindowAfterCreation(w)
|
initializeWindowAfterCreation(w)
|
||||||
|
|
||||||
m := currentMonitor(w)
|
m := initialMonitor(w)
|
||||||
theUI.initMonitor = m
|
theUI.initMonitor = m
|
||||||
v := m.GetVideoMode()
|
v := m.GetVideoMode()
|
||||||
scale := videoModeScale(m)
|
theUI.initFullscreenWidthInDP = int(theUI.fromGLFWMonitorPixel(float64(v.Width), m))
|
||||||
theUI.initFullscreenWidthInDP = int(theUI.fromGLFWMonitorPixel(float64(v.Width), scale))
|
theUI.initFullscreenHeightInDP = int(theUI.fromGLFWMonitorPixel(float64(v.Height), m))
|
||||||
theUI.initFullscreenHeightInDP = int(theUI.fromGLFWMonitorPixel(float64(v.Height), scale))
|
|
||||||
|
|
||||||
// Create system cursors. These cursors are destroyed at glfw.Terminate().
|
// Create system cursors. These cursors are destroyed at glfw.Terminate().
|
||||||
glfwSystemCursors[driver.CursorShapeDefault] = nil
|
glfwSystemCursors[driver.CursorShapeDefault] = nil
|
||||||
@ -275,17 +274,18 @@ func (u *UserInterface) getWindowSizeLimits() (minw, minh, maxw, maxh int) {
|
|||||||
defer u.m.RUnlock()
|
defer u.m.RUnlock()
|
||||||
|
|
||||||
minw, minh, maxw, maxh = -1, -1, -1, -1
|
minw, minh, maxw, maxh = -1, -1, -1, -1
|
||||||
|
m := u.currentMonitor()
|
||||||
if u.minWindowWidthInDP >= 0 {
|
if u.minWindowWidthInDP >= 0 {
|
||||||
minw = int(u.toGLFWPixel(float64(u.minWindowWidthInDP)))
|
minw = int(u.toGLFWPixel(float64(u.minWindowWidthInDP), m))
|
||||||
}
|
}
|
||||||
if u.minWindowHeightInDP >= 0 {
|
if u.minWindowHeightInDP >= 0 {
|
||||||
minh = int(u.toGLFWPixel(float64(u.minWindowHeightInDP)))
|
minh = int(u.toGLFWPixel(float64(u.minWindowHeightInDP), m))
|
||||||
}
|
}
|
||||||
if u.maxWindowWidthInDP >= 0 {
|
if u.maxWindowWidthInDP >= 0 {
|
||||||
maxw = int(u.toGLFWPixel(float64(u.maxWindowWidthInDP)))
|
maxw = int(u.toGLFWPixel(float64(u.maxWindowWidthInDP), m))
|
||||||
}
|
}
|
||||||
if u.maxWindowHeightInDP >= 0 {
|
if u.maxWindowHeightInDP >= 0 {
|
||||||
maxh = int(u.toGLFWPixel(float64(u.maxWindowHeightInDP)))
|
maxh = int(u.toGLFWPixel(float64(u.maxWindowHeightInDP), m))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -531,11 +531,10 @@ func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
|||||||
|
|
||||||
var w, h int
|
var w, h int
|
||||||
_ = u.t.Call(func() error {
|
_ = u.t.Call(func() error {
|
||||||
m := currentMonitor(u.window)
|
m := u.currentMonitor()
|
||||||
v := m.GetVideoMode()
|
v := m.GetVideoMode()
|
||||||
s := videoModeScale(m)
|
w = int(u.fromGLFWMonitorPixel(float64(v.Width), m))
|
||||||
w = int(u.fromGLFWMonitorPixel(float64(v.Width), s))
|
h = int(u.fromGLFWMonitorPixel(float64(v.Height), m))
|
||||||
h = int(u.fromGLFWMonitorPixel(float64(v.Height), s))
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return w, h
|
return w, h
|
||||||
@ -707,24 +706,20 @@ func (u *UserInterface) SetCursorShape(shape driver.CursorShape) {
|
|||||||
func (u *UserInterface) DeviceScaleFactor() float64 {
|
func (u *UserInterface) DeviceScaleFactor() float64 {
|
||||||
if !u.isRunning() {
|
if !u.isRunning() {
|
||||||
// TODO: Use the initWindowPosition. This requires to convert the units correctly (#1575).
|
// TODO: Use the initWindowPosition. This requires to convert the units correctly (#1575).
|
||||||
return u.deviceScaleFactor()
|
return u.deviceScaleFactor(u.currentMonitor())
|
||||||
}
|
}
|
||||||
|
|
||||||
f := 0.0
|
f := 0.0
|
||||||
_ = u.t.Call(func() error {
|
_ = u.t.Call(func() error {
|
||||||
f = u.deviceScaleFactor()
|
f = u.deviceScaleFactor(u.currentMonitor())
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceScaleFactor must be called from the main thread.
|
// deviceScaleFactor must be called from the main thread.
|
||||||
func (u *UserInterface) deviceScaleFactor() float64 {
|
func (u *UserInterface) deviceScaleFactor(monitor *glfw.Monitor) float64 {
|
||||||
m := u.initMonitor
|
mx, my := monitor.GetPos()
|
||||||
if u.window != nil {
|
|
||||||
m = currentMonitor(u.window)
|
|
||||||
}
|
|
||||||
mx, my := m.GetPos()
|
|
||||||
return devicescale.GetAt(mx, my)
|
return devicescale.GetAt(mx, my)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,20 +891,21 @@ func (u *UserInterface) init() error {
|
|||||||
|
|
||||||
setSize := func() {
|
setSize := func() {
|
||||||
ww, wh := u.getInitWindowSize()
|
ww, wh := u.getInitWindowSize()
|
||||||
ww = int(u.toGLFWPixel(float64(ww)))
|
ww = int(u.toGLFWPixel(float64(ww), u.initMonitor))
|
||||||
wh = int(u.toGLFWPixel(float64(wh)))
|
wh = int(u.toGLFWPixel(float64(wh), u.initMonitor))
|
||||||
u.setWindowSize(ww, wh, u.isFullscreen())
|
u.setWindowSize(ww, wh, u.isFullscreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the window size and the window position in this order on Linux or other UNIX using X (#1118),
|
// Set the window size and the window position in this order on Linux or other UNIX using X (#1118),
|
||||||
// but this should be inverted on Windows. This is very tricky, but there is no obvious way to solve
|
// but this should be inverted on Windows. This is very tricky, but there is no obvious way to solve
|
||||||
// this. This doesn't matter on macOS.
|
// this. This doesn't matter on macOS.
|
||||||
|
wx, wy := u.getInitWindowPosition()
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
u.setWindowPosition(u.getInitWindowPosition())
|
u.setWindowPosition(wx, wy, u.initMonitor)
|
||||||
setSize()
|
setSize()
|
||||||
} else {
|
} else {
|
||||||
setSize()
|
setSize()
|
||||||
u.setWindowPosition(u.getInitWindowPosition())
|
u.setWindowPosition(wx, wy, u.initMonitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
u.updateWindowSizeLimits()
|
u.updateWindowSizeLimits()
|
||||||
@ -945,19 +941,18 @@ func (u *UserInterface) updateSize() (float64, float64, bool) {
|
|||||||
// fullscreened. Use the monitor size.
|
// fullscreened. Use the monitor size.
|
||||||
// On macOS's native fullscreen, the window's size returns a more precise size
|
// On macOS's native fullscreen, the window's size returns a more precise size
|
||||||
// reflecting the adjustment of the view size (#1745).
|
// reflecting the adjustment of the view size (#1745).
|
||||||
m := currentMonitor(u.window)
|
m := u.currentMonitor()
|
||||||
v := m.GetVideoMode()
|
v := m.GetVideoMode()
|
||||||
ww, wh := v.Width, v.Height
|
ww, wh := v.Width, v.Height
|
||||||
s := videoModeScale(m)
|
w = u.fromGLFWMonitorPixel(float64(ww), m)
|
||||||
w = u.fromGLFWMonitorPixel(float64(ww), s)
|
h = u.fromGLFWMonitorPixel(float64(wh), m)
|
||||||
h = u.fromGLFWMonitorPixel(float64(wh), s)
|
|
||||||
} else {
|
} else {
|
||||||
// Instead of u.windowWidth and u.windowHeight, use the actual window size here.
|
// Instead of u.windowWidth and u.windowHeight, use the actual window size here.
|
||||||
// On Windows, the specified size at SetSize and the actual window size might not
|
// On Windows, the specified size at SetSize and the actual window size might not
|
||||||
// match (#1163).
|
// match (#1163).
|
||||||
ww, wh := u.window.GetSize()
|
ww, wh := u.window.GetSize()
|
||||||
w = u.fromGLFWPixel(float64(ww))
|
w = u.fromGLFWPixel(float64(ww), u.currentMonitor())
|
||||||
h = u.fromGLFWPixel(float64(wh))
|
h = u.fromGLFWPixel(float64(wh), u.currentMonitor())
|
||||||
}
|
}
|
||||||
|
|
||||||
return w, h, true
|
return w, h, true
|
||||||
@ -1140,26 +1135,27 @@ func (u *UserInterface) swapBuffers() {
|
|||||||
|
|
||||||
// updateWindowSizeLimits must be called from the main thread.
|
// updateWindowSizeLimits must be called from the main thread.
|
||||||
func (u *UserInterface) updateWindowSizeLimits() {
|
func (u *UserInterface) updateWindowSizeLimits() {
|
||||||
|
m := u.currentMonitor()
|
||||||
minw, minh, maxw, maxh := u.getWindowSizeLimitsInDP()
|
minw, minh, maxw, maxh := u.getWindowSizeLimitsInDP()
|
||||||
if minw < 0 {
|
if minw < 0 {
|
||||||
minw = glfw.DontCare
|
minw = glfw.DontCare
|
||||||
} else {
|
} else {
|
||||||
minw = int(u.toGLFWPixel(float64(minw)))
|
minw = int(u.toGLFWPixel(float64(minw), m))
|
||||||
}
|
}
|
||||||
if minh < 0 {
|
if minh < 0 {
|
||||||
minh = glfw.DontCare
|
minh = glfw.DontCare
|
||||||
} else {
|
} else {
|
||||||
minh = int(u.toGLFWPixel(float64(minh)))
|
minh = int(u.toGLFWPixel(float64(minh), m))
|
||||||
}
|
}
|
||||||
if maxw < 0 {
|
if maxw < 0 {
|
||||||
maxw = glfw.DontCare
|
maxw = glfw.DontCare
|
||||||
} else {
|
} else {
|
||||||
maxw = int(u.toGLFWPixel(float64(maxw)))
|
maxw = int(u.toGLFWPixel(float64(maxw), m))
|
||||||
}
|
}
|
||||||
if maxh < 0 {
|
if maxh < 0 {
|
||||||
maxh = glfw.DontCare
|
maxh = glfw.DontCare
|
||||||
} else {
|
} else {
|
||||||
maxh = int(u.toGLFWPixel(float64(maxh)))
|
maxh = int(u.toGLFWPixel(float64(maxh), m))
|
||||||
}
|
}
|
||||||
u.window.SetSizeLimits(minw, minh, maxw, maxh)
|
u.window.SetSizeLimits(minw, minh, maxw, maxh)
|
||||||
}
|
}
|
||||||
@ -1208,7 +1204,7 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
|
|||||||
|
|
||||||
u.Graphics().SetFullscreen(fullscreen)
|
u.Graphics().SetFullscreen(fullscreen)
|
||||||
|
|
||||||
if u.windowWidth == width && u.windowHeight == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == u.deviceScaleFactor() {
|
if u.windowWidth == width && u.windowHeight == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == u.deviceScaleFactor(u.currentMonitor()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1219,7 +1215,7 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool) {
|
|||||||
height = 1
|
height = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
u.lastDeviceScaleFactor = u.deviceScaleFactor()
|
u.lastDeviceScaleFactor = u.deviceScaleFactor(u.currentMonitor())
|
||||||
|
|
||||||
// To make sure the current existing framebuffers are rendered,
|
// To make sure the current existing framebuffers are rendered,
|
||||||
// swap buffers here before SetSize is called.
|
// swap buffers here before SetSize is called.
|
||||||
@ -1264,7 +1260,7 @@ func (u *UserInterface) setWindowSizeImpl(width, height int, fullscreen bool) bo
|
|||||||
if u.isNativeFullscreenAvailable() {
|
if u.isNativeFullscreenAvailable() {
|
||||||
u.setNativeFullscreen(fullscreen)
|
u.setNativeFullscreen(fullscreen)
|
||||||
} else {
|
} else {
|
||||||
m := currentMonitor(u.window)
|
m := u.currentMonitor()
|
||||||
v := m.GetVideoMode()
|
v := m.GetVideoMode()
|
||||||
u.window.SetMonitor(m, 0, 0, v.Width, v.Height, v.RefreshRate)
|
u.window.SetMonitor(m, 0, 0, v.Width, v.Height, v.RefreshRate)
|
||||||
|
|
||||||
@ -1279,7 +1275,7 @@ func (u *UserInterface) setWindowSizeImpl(width, height int, fullscreen bool) bo
|
|||||||
// On Windows, giving a too small width doesn't call a callback (#165).
|
// On Windows, giving a too small width doesn't call a callback (#165).
|
||||||
// To prevent hanging up, return asap if the width is too small.
|
// To prevent hanging up, return asap if the width is too small.
|
||||||
// 126 is an arbitrary number and I guess this is small enough.
|
// 126 is an arbitrary number and I guess this is small enough.
|
||||||
minWindowWidth := int(u.toGLFWPixel(126))
|
minWindowWidth := int(u.toGLFWPixel(126, u.currentMonitor()))
|
||||||
if u.window.GetAttrib(glfw.Decorated) == glfw.False {
|
if u.window.GetAttrib(glfw.Decorated) == glfw.False {
|
||||||
minWindowWidth = 1
|
minWindowWidth = 1
|
||||||
}
|
}
|
||||||
@ -1395,12 +1391,34 @@ func (u *UserInterface) updateVsync() {
|
|||||||
u.Graphics().SetVsyncEnabled(u.fpsMode == driver.FPSModeVsyncOn)
|
u.Graphics().SetVsyncEnabled(u.fpsMode == driver.FPSModeVsyncOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialMonitor returns the initial monitor to show the window.
|
||||||
|
//
|
||||||
|
// The given window is just a hint and might not be used to determine the initial monitor.
|
||||||
|
//
|
||||||
|
// initialMonitor must be called on the main thread.
|
||||||
|
func initialMonitor(window *glfw.Window) *glfw.Monitor {
|
||||||
|
if m := initialMonitorByOS(); m != nil {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
return currentMonitorImpl(window)
|
||||||
|
}
|
||||||
|
|
||||||
// currentMonitor returns the current active monitor.
|
// currentMonitor returns the current active monitor.
|
||||||
//
|
//
|
||||||
|
// currentMonitor must be called on the main thread.
|
||||||
|
func (u *UserInterface) currentMonitor() *glfw.Monitor {
|
||||||
|
if !u.isRunning() {
|
||||||
|
return u.initMonitor
|
||||||
|
}
|
||||||
|
return currentMonitorImpl(u.window)
|
||||||
|
}
|
||||||
|
|
||||||
|
// currentMonitorImpl returns the current active monitor.
|
||||||
|
//
|
||||||
// The given window might or might not be used to detect the monitor.
|
// The given window might or might not be used to detect the monitor.
|
||||||
//
|
//
|
||||||
// currentMonitor must be called on the main thread.
|
// currentMonitorImpl must be called on the main thread.
|
||||||
func currentMonitor(window *glfw.Window) *glfw.Monitor {
|
func currentMonitorImpl(window *glfw.Window) *glfw.Monitor {
|
||||||
// GetMonitor is available only in fullscreen.
|
// GetMonitor is available only in fullscreen.
|
||||||
if m := window.GetMonitor(); m != nil {
|
if m := window.GetMonitor(); m != nil {
|
||||||
return m
|
return m
|
||||||
@ -1479,7 +1497,7 @@ func (u *UserInterface) SetInitFocused(focused bool) {
|
|||||||
|
|
||||||
func (u *UserInterface) monitorPosition() (int, int) {
|
func (u *UserInterface) monitorPosition() (int, int) {
|
||||||
// TODO: fromGLFWMonitorPixel might be required.
|
// TODO: fromGLFWMonitorPixel might be required.
|
||||||
return currentMonitor(u.window).GetPos()
|
return u.currentMonitor().GetPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) Input() driver.Input {
|
func (u *UserInterface) Input() driver.Input {
|
||||||
@ -1626,7 +1644,7 @@ func (u *UserInterface) setWindowResizable(resizable bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setWindowPosition must be called from the main thread.
|
// setWindowPosition must be called from the main thread.
|
||||||
func (u *UserInterface) setWindowPosition(x, y int) {
|
func (u *UserInterface) setWindowPosition(x, y int, monitor *glfw.Monitor) {
|
||||||
if u.setSizeCallbackEnabled {
|
if u.setSizeCallbackEnabled {
|
||||||
u.setSizeCallbackEnabled = false
|
u.setSizeCallbackEnabled = false
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -1634,9 +1652,9 @@ func (u *UserInterface) setWindowPosition(x, y int) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
mx, my := currentMonitor(u.window).GetPos()
|
mx, my := monitor.GetPos()
|
||||||
xf := u.toGLFWPixel(float64(x))
|
xf := u.toGLFWPixel(float64(x), monitor)
|
||||||
yf := u.toGLFWPixel(float64(y))
|
yf := u.toGLFWPixel(float64(y), monitor)
|
||||||
if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf)); u.isFullscreen() {
|
if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf)); u.isFullscreen() {
|
||||||
u.setOrigPos(x, y)
|
u.setOrigPos(x, y)
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,14 +127,13 @@ func videoModeScale(m *glfw.Monitor) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fromGLFWMonitorPixel must be called from the main thread.
|
// fromGLFWMonitorPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWMonitorPixel(x float64, videoModeScale float64) float64 {
|
func (u *UserInterface) fromGLFWMonitorPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
// videoModeScale is always 1 on macOS,
|
// videoModeScale is always 1 on macOS.
|
||||||
// however leaving the divison in place for consistency.
|
return x
|
||||||
return x / videoModeScale
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromGLFWPixel must be called from the main thread.
|
// fromGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWPixel(x float64) float64 {
|
func (u *UserInterface) fromGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
// NOTE: On macOS, GLFW exposes the device independent coordinate system.
|
// NOTE: On macOS, GLFW exposes the device independent coordinate system.
|
||||||
// Thus, the conversion functions are unnecessary,
|
// Thus, the conversion functions are unnecessary,
|
||||||
// however we still need the deviceScaleFactor internally
|
// however we still need the deviceScaleFactor internally
|
||||||
@ -143,7 +142,7 @@ func (u *UserInterface) fromGLFWPixel(x float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// toGLFWPixel must be called from the main thread.
|
// toGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) toGLFWPixel(x float64) float64 {
|
func (u *UserInterface) toGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +150,10 @@ func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
|||||||
return x, y
|
return x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initialMonitorByOS() *glfw.Monitor {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func currentMonitorByOS(w *glfw.Window) *glfw.Monitor {
|
func currentMonitorByOS(w *glfw.Window) *glfw.Monitor {
|
||||||
x := C.int(0)
|
x := C.int(0)
|
||||||
y := C.int(0)
|
y := C.int(0)
|
||||||
|
@ -117,24 +117,28 @@ func videoModeScaleUncached(m *glfw.Monitor) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fromGLFWMonitorPixel must be called from the main thread.
|
// fromGLFWMonitorPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWMonitorPixel(x float64, videoModeScale float64) float64 {
|
func (u *UserInterface) fromGLFWMonitorPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x / (videoModeScale * u.deviceScaleFactor())
|
return x / (videoModeScale(monitor) * u.deviceScaleFactor(monitor))
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromGLFWPixel must be called from the main thread.
|
// fromGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWPixel(x float64) float64 {
|
func (u *UserInterface) fromGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x / u.deviceScaleFactor()
|
return x / u.deviceScaleFactor(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// toGLFWPixel must be called from the main thread.
|
// toGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) toGLFWPixel(x float64) float64 {
|
func (u *UserInterface) toGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x * u.deviceScaleFactor()
|
return x * u.deviceScaleFactor(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
||||||
return x, y
|
return x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initialMonitorByOS() *glfw.Monitor {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func currentMonitorByOS(_ *glfw.Window) *glfw.Monitor {
|
func currentMonitorByOS(_ *glfw.Window) *glfw.Monitor {
|
||||||
// TODO: Implement this correctly. (#1119).
|
// TODO: Implement this correctly. (#1119).
|
||||||
return nil
|
return nil
|
||||||
|
@ -47,7 +47,6 @@ type monitorInfo struct {
|
|||||||
var (
|
var (
|
||||||
// user32 is defined at hideconsole_windows.go
|
// user32 is defined at hideconsole_windows.go
|
||||||
procGetSystemMetrics = user32.NewProc("GetSystemMetrics")
|
procGetSystemMetrics = user32.NewProc("GetSystemMetrics")
|
||||||
procGetActiveWindow = user32.NewProc("GetActiveWindow")
|
|
||||||
procGetForegroundWindow = user32.NewProc("GetForegroundWindow")
|
procGetForegroundWindow = user32.NewProc("GetForegroundWindow")
|
||||||
procMonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
procMonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
||||||
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
|
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
|
||||||
@ -61,14 +60,6 @@ func getSystemMetrics(nIndex int) (int, error) {
|
|||||||
return int(r), nil
|
return int(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getActiveWindow() (uintptr, error) {
|
|
||||||
r, _, e := procGetActiveWindow.Call()
|
|
||||||
if e != nil && e.(windows.Errno) != 0 {
|
|
||||||
return 0, fmt.Errorf("ui: GetActiveWindow failed: error code: %d", e)
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getForegroundWindow() (uintptr, error) {
|
func getForegroundWindow() (uintptr, error) {
|
||||||
r, _, e := procGetForegroundWindow.Call()
|
r, _, e := procGetForegroundWindow.Call()
|
||||||
if e != nil && e.(windows.Errno) != 0 {
|
if e != nil && e.(windows.Errno) != 0 {
|
||||||
@ -102,28 +93,23 @@ func getMonitorInfoW(hMonitor uintptr, lpmi *monitorInfo) error {
|
|||||||
// clearVideoModeScaleCache must be called from the main thread.
|
// clearVideoModeScaleCache must be called from the main thread.
|
||||||
func clearVideoModeScaleCache() {}
|
func clearVideoModeScaleCache() {}
|
||||||
|
|
||||||
// videoModeScale must be called from the main thread.
|
|
||||||
func videoModeScale(m *glfw.Monitor) float64 {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// fromGLFWMonitorPixel must be called from the main thread.
|
// fromGLFWMonitorPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWMonitorPixel(x float64, videoModeScale float64) float64 {
|
func (u *UserInterface) fromGLFWMonitorPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x / (videoModeScale * u.deviceScaleFactor())
|
return x / u.deviceScaleFactor(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromGLFWPixel must be called from the main thread.
|
// fromGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) fromGLFWPixel(x float64) float64 {
|
func (u *UserInterface) fromGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x / u.deviceScaleFactor()
|
return x / u.deviceScaleFactor(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// toGLFWPixel must be called from the main thread.
|
// toGLFWPixel must be called from the main thread.
|
||||||
func (u *UserInterface) toGLFWPixel(x float64) float64 {
|
func (u *UserInterface) toGLFWPixel(x float64, monitor *glfw.Monitor) float64 {
|
||||||
return x * u.deviceScaleFactor()
|
return x * u.deviceScaleFactor(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
||||||
mx, my := currentMonitor(u.window).GetPos()
|
mx, my := u.currentMonitor().GetPos()
|
||||||
// As the video width/height might be wrong,
|
// As the video width/height might be wrong,
|
||||||
// adjust x/y at least to enable to handle the window (#328)
|
// adjust x/y at least to enable to handle the window (#328)
|
||||||
if x < mx {
|
if x < mx {
|
||||||
@ -139,28 +125,24 @@ func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
|||||||
return x, y
|
return x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentMonitorByOS(_ *glfw.Window) *glfw.Monitor {
|
func initialMonitorByOS() *glfw.Monitor {
|
||||||
// TODO: Why not using the given window?
|
// Get the foreground window, that is common among multiple processes.
|
||||||
|
w, err := getForegroundWindow()
|
||||||
// TODO: Should we return nil here?
|
|
||||||
w, err := getActiveWindow()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if w == 0 {
|
if w == 0 {
|
||||||
// The active window doesn't exist when launching, or the application is runnable on unfocused.
|
// GetForegroundWindow can return null according to the document.
|
||||||
// Get the foreground window, that is common among multiple processes.
|
return nil
|
||||||
w, err = getForegroundWindow()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if w == 0 {
|
|
||||||
// GetForegroundWindow can return null according to the document.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return monitorFromWin32Window(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func currentMonitorByOS(w *glfw.Window) *glfw.Monitor {
|
||||||
|
return monitorFromWin32Window(w.GetWin32Window())
|
||||||
|
}
|
||||||
|
|
||||||
|
func monitorFromWin32Window(w uintptr) *glfw.Monitor {
|
||||||
// Get the current monitor by the window handle instead of the window position. It is because the window
|
// Get the current monitor by the window handle instead of the window position. It is because the window
|
||||||
// position is not relaiable in some cases e.g. when the window is put across multiple monitors.
|
// position is not relaiable in some cases e.g. when the window is put across multiple monitors.
|
||||||
|
|
||||||
|
@ -181,11 +181,12 @@ func (w *window) Position() (int, int) {
|
|||||||
} else {
|
} else {
|
||||||
wx, wy = w.ui.window.GetPos()
|
wx, wy = w.ui.window.GetPos()
|
||||||
}
|
}
|
||||||
mx, my := currentMonitor(w.ui.window).GetPos()
|
m := w.ui.currentMonitor()
|
||||||
|
mx, my := m.GetPos()
|
||||||
wx -= mx
|
wx -= mx
|
||||||
wy -= my
|
wy -= my
|
||||||
xf := w.ui.fromGLFWPixel(float64(wx))
|
xf := w.ui.fromGLFWPixel(float64(wx), m)
|
||||||
yf := w.ui.fromGLFWPixel(float64(wy))
|
yf := w.ui.fromGLFWPixel(float64(wy), m)
|
||||||
x, y = int(xf), int(yf)
|
x, y = int(xf), int(yf)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -198,7 +199,7 @@ func (w *window) SetPosition(x, y int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
w.ui.setWindowPosition(x, y)
|
w.ui.setWindowPosition(x, y, w.ui.currentMonitor())
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -210,8 +211,8 @@ func (w *window) Size() (int, int) {
|
|||||||
}
|
}
|
||||||
ww, wh := 0, 0
|
ww, wh := 0, 0
|
||||||
_ = w.ui.t.Call(func() error {
|
_ = w.ui.t.Call(func() error {
|
||||||
ww = int(w.ui.fromGLFWPixel(float64(w.ui.windowWidth)))
|
ww = int(w.ui.fromGLFWPixel(float64(w.ui.windowWidth), w.ui.currentMonitor()))
|
||||||
wh = int(w.ui.fromGLFWPixel(float64(w.ui.windowHeight)))
|
wh = int(w.ui.fromGLFWPixel(float64(w.ui.windowHeight), w.ui.currentMonitor()))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return ww, wh
|
return ww, wh
|
||||||
@ -229,8 +230,8 @@ func (w *window) SetSize(width, height int) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ww := int(w.ui.toGLFWPixel(float64(width)))
|
ww := int(w.ui.toGLFWPixel(float64(width), w.ui.currentMonitor()))
|
||||||
wh := int(w.ui.toGLFWPixel(float64(height)))
|
wh := int(w.ui.toGLFWPixel(float64(height), w.ui.currentMonitor()))
|
||||||
w.ui.setWindowSize(ww, wh, w.ui.isFullscreen())
|
w.ui.setWindowSize(ww, wh, w.ui.isFullscreen())
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user