mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
ui: Bug fix: wrong scaling when a window move across monitors
Fixes #701
This commit is contained in:
parent
0e7dab3707
commit
e0d2d5e753
@ -24,7 +24,6 @@ import (
|
||||
|
||||
const (
|
||||
logPixelsX = 88
|
||||
monitorDefaultToNull = 0
|
||||
monitorDefaultToNearest = 2
|
||||
mdtEffectiveDpi = 0
|
||||
)
|
||||
@ -178,7 +177,7 @@ func impl(x, y int) float64 {
|
||||
|
||||
// MonitorFromPoint requires to pass a POINT value, and there seems no portable way to
|
||||
// do this with Cgo. Use MonitorFromRect instead.
|
||||
m, err := monitorFromRect(uintptr(unsafe.Pointer(&lprc)), monitorDefaultToNull)
|
||||
m, err := monitorFromRect(uintptr(unsafe.Pointer(&lprc)), monitorDefaultToNearest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -774,14 +774,6 @@ func (u *userInterface) currentMonitor() *glfw.Monitor {
|
||||
if m := w.GetMonitor(); m != nil {
|
||||
return m
|
||||
}
|
||||
|
||||
wx, wy := w.GetPos()
|
||||
for _, m := range glfw.GetMonitors() {
|
||||
mx, my := m.GetPos()
|
||||
v := m.GetVideoMode()
|
||||
if mx <= wx && wx < mx+v.Width && my <= wy && wy < my+v.Height {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return glfw.GetPrimaryMonitor()
|
||||
// Get the monitor which the current window belongs to. This requires OS API.
|
||||
return currentMonitor()
|
||||
}
|
||||
|
@ -18,6 +18,25 @@
|
||||
|
||||
package ui
|
||||
|
||||
// #cgo CFLAGS: -x objective-c
|
||||
// #cgo LDFLAGS: -framework AppKit
|
||||
//
|
||||
// #import <AppKit/AppKit.h>
|
||||
//
|
||||
// static void currentMonitorPos(int* x, int* y) {
|
||||
// NSDictionary* screenDictionary = [[NSScreen mainScreen] deviceDescription];
|
||||
// NSNumber* screenID = [screenDictionary objectForKey:@"NSScreenNumber"];
|
||||
// CGDirectDisplayID aID = [screenID unsignedIntValue];
|
||||
// const CGRect bounds = CGDisplayBounds(aID);
|
||||
// *x = bounds.origin.x;
|
||||
// *y = bounds.origin.y;
|
||||
// }
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
)
|
||||
|
||||
func glfwScale() float64 {
|
||||
return 1
|
||||
}
|
||||
@ -25,3 +44,16 @@ func glfwScale() float64 {
|
||||
func adjustWindowPosition(x, y int) (int, int) {
|
||||
return x, y
|
||||
}
|
||||
|
||||
func currentMonitor() *glfw.Monitor {
|
||||
x := C.int(0)
|
||||
y := C.int(0)
|
||||
C.currentMonitorPos(&x, &y)
|
||||
for _, m := range glfw.GetMonitors() {
|
||||
mx, my := m.GetPos()
|
||||
if int(x) == mx && int(y) == my {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||
)
|
||||
|
||||
@ -30,3 +32,17 @@ func glfwScale() float64 {
|
||||
func adjustWindowPosition(x, y int) (int, int) {
|
||||
return x, y
|
||||
}
|
||||
|
||||
func currentMonitor() *glfw.Monitor {
|
||||
// TODO: Return more appropriate display.
|
||||
w := glfw.GetCurrentContext()
|
||||
wx, wy := w.GetPos()
|
||||
for _, m := range glfw.GetMonitors() {
|
||||
mx, my := m.GetPos()
|
||||
v := m.GetVideoMode()
|
||||
if mx <= wx && wx < mx+v.Width && my <= wy && wy < my+v.Height {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -16,21 +16,81 @@
|
||||
|
||||
package ui
|
||||
|
||||
// TODO: Use golang.org/x/sys/windows (NewLazyDLL) instead of cgo.
|
||||
|
||||
// #cgo LDFLAGS: -lgdi32
|
||||
//
|
||||
// #include <windows.h>
|
||||
//
|
||||
// static int getCaptionHeight() {
|
||||
// return GetSystemMetrics(SM_CYCAPTION);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||
)
|
||||
|
||||
const (
|
||||
smCyCaption = 4
|
||||
monitorDefaultToNearest = 2
|
||||
)
|
||||
|
||||
type rect struct {
|
||||
left int32
|
||||
top int32
|
||||
right int32
|
||||
bottom int32
|
||||
}
|
||||
|
||||
type monitorInfo struct {
|
||||
cbSize uint32
|
||||
rcMonitor rect
|
||||
rcWork rect
|
||||
dwFlags uint32
|
||||
}
|
||||
|
||||
var (
|
||||
// user32 is defined at hideconsole_windows.go
|
||||
procGetSystemMetrics = user32.NewProc("GetSystemMetrics")
|
||||
procGetActiveWindow = user32.NewProc("GetActiveWindow")
|
||||
procMonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
||||
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
|
||||
)
|
||||
|
||||
func getSystemMetrics(nIndex int) (int, error) {
|
||||
r, _, e := syscall.Syscall(procGetSystemMetrics.Addr(), 1, uintptr(nIndex), 0, 0)
|
||||
if e != 0 {
|
||||
return 0, fmt.Errorf("ui: GetSystemMetrics failed: error code: %d", e)
|
||||
}
|
||||
return int(r), nil
|
||||
}
|
||||
|
||||
func getActiveWindow() (uintptr, error) {
|
||||
r, _, e := syscall.Syscall(procGetActiveWindow.Addr(), 0, 0, 0, 0)
|
||||
if e != 0 {
|
||||
return 0, fmt.Errorf("ui: GetActiveWindow failed: error code: %d", e)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func monitorFromWindow(hwnd uintptr, dwFlags uint32) (uintptr, error) {
|
||||
r, _, e := syscall.Syscall(procMonitorFromWindow.Addr(), 2, hwnd, uintptr(dwFlags), 0)
|
||||
if e != 0 {
|
||||
return 0, fmt.Errorf("ui: MonitorFromWindow failed: error code: %d", e)
|
||||
}
|
||||
if r == 0 {
|
||||
return 0, fmt.Errorf("ui: MonitorFromWindow failed: returned value: %d", r)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func getMonitorInfoW(hMonitor uintptr, lpmi *monitorInfo) error {
|
||||
r, _, e := syscall.Syscall(procGetMonitorInfoW.Addr(), 2, hMonitor, uintptr(unsafe.Pointer(lpmi)), 0)
|
||||
if e != 0 {
|
||||
return fmt.Errorf("ui: GetMonitorInfoW failed: error code: %d", e)
|
||||
}
|
||||
if r == 0 {
|
||||
return fmt.Errorf("ui: GetMonitorInfoW failed: returned value: %d", r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func glfwScale() float64 {
|
||||
// This function must be called on the main thread.
|
||||
return devicescale.GetAt(currentUI.currentMonitor().GetPos())
|
||||
@ -42,9 +102,43 @@ func adjustWindowPosition(x, y int) (int, int) {
|
||||
if x < 0 {
|
||||
x = 0
|
||||
}
|
||||
t := int(C.getCaptionHeight())
|
||||
t, err := getSystemMetrics(smCyCaption)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if y < t {
|
||||
y = t
|
||||
}
|
||||
return x, y
|
||||
}
|
||||
|
||||
func currentMonitor() *glfw.Monitor {
|
||||
w, err := getActiveWindow()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if w == 0 {
|
||||
// There is no window at launching.
|
||||
return glfw.GetPrimaryMonitor()
|
||||
}
|
||||
|
||||
m, err := monitorFromWindow(w, monitorDefaultToNearest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mi := monitorInfo{}
|
||||
mi.cbSize = uint32(unsafe.Sizeof(mi))
|
||||
if err := getMonitorInfoW(m, &mi); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
x, y := int(mi.rcMonitor.left), int(mi.rcMonitor.top)
|
||||
for _, m := range glfw.GetMonitors() {
|
||||
mx, my := m.GetPos()
|
||||
if mx == x && my == y {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user