internal/ui: Reduce calls of glfw.GetMonitors

Updates #1803
This commit is contained in:
Hajime Hoshi 2021-09-09 11:11:56 +09:00
parent 5ac357959c
commit 106ff7a84b
3 changed files with 25 additions and 20 deletions

View File

@ -160,9 +160,9 @@ func init() {
panic(err) panic(err)
} }
glfw.SetMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) { glfw.SetMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) {
cacheMonitors() updateMonitors()
}) })
cacheMonitors() updateMonitors()
} }
var glfwSystemCursors = map[driver.CursorShape]*glfw.Cursor{} var glfwSystemCursors = map[driver.CursorShape]*glfw.Cursor{}
@ -208,7 +208,7 @@ func initialize() error {
return nil return nil
} }
type cachedMonitor struct { type monitor struct {
m *glfw.Monitor m *glfw.Monitor
vm *glfw.VidMode vm *glfw.VidMode
// Pos of monitor in virtual coords // Pos of monitor in virtual coords
@ -217,18 +217,18 @@ type cachedMonitor struct {
} }
// monitors is the monitor list cache for desktop glfw compile targets. // monitors is the monitor list cache for desktop glfw compile targets.
// populated by 'cacheMonitors' which is called on init and every // populated by 'updateMonitors' which is called on init and every
// monitor config change event. // monitor config change event.
// //
// monitors must be manipulated on the main thread. // monitors must be manipulated on the main thread.
var monitors []*cachedMonitor var monitors []*monitor
func cacheMonitors() { func updateMonitors() {
monitors = nil monitors = nil
ms := glfw.GetMonitors() ms := glfw.GetMonitors()
for _, m := range ms { for _, m := range ms {
x, y := m.GetPos() x, y := m.GetPos()
monitors = append(monitors, &cachedMonitor{ monitors = append(monitors, &monitor{
m: m, m: m,
vm: m.GetVideoMode(), vm: m.GetVideoMode(),
x: x, x: x,
@ -237,12 +237,19 @@ func cacheMonitors() {
} }
} }
// getCachedMonitor returns a monitor for the given window x/y, func ensureMonitors() []*monitor {
if len(monitors) == 0 {
updateMonitors()
}
return monitors
}
// getMonitorFromPosition returns a monitor for the given window x/y,
// or returns nil if monitor is not found. // or returns nil if monitor is not found.
// //
// getCachedMonitor must be called on the main thread. // getMonitorFromPosition must be called on the main thread.
func getCachedMonitor(wx, wy int) *cachedMonitor { func getMonitorFromPosition(wx, wy int) *monitor {
for _, m := range monitors { for _, m := range ensureMonitors() {
if m.x <= wx && wx < m.x+m.vm.Width && m.y <= wy && wy < m.y+m.vm.Height { if m.x <= wx && wx < m.x+m.vm.Width && m.y <= wy && wy < m.y+m.vm.Height {
return m return m
} }
@ -1387,7 +1394,7 @@ func currentMonitor(window *glfw.Window) *glfw.Monitor {
} }
// As the fallback, detect the monitor from the window. // As the fallback, detect the monitor from the window.
if m := getCachedMonitor(window.GetPos()); m != nil { if m := getMonitorFromPosition(window.GetPos()); m != nil {
return m.m return m.m
} }
return glfw.GetPrimaryMonitor() return glfw.GetPrimaryMonitor()

View File

@ -107,10 +107,9 @@ func currentMonitorByOS(w *glfw.Window) *glfw.Monitor {
// Note: [NSApp mainWindow] is nil when it doesn't have its border. Use w here. // Note: [NSApp mainWindow] is nil when it doesn't have its border. Use w here.
win := w.GetCocoaWindow() win := w.GetCocoaWindow()
C.currentMonitorPos(C.uintptr_t(win), &x, &y) C.currentMonitorPos(C.uintptr_t(win), &x, &y)
for _, m := range glfw.GetMonitors() { for _, m := range ensureMonitors() {
mx, my := m.GetPos() if int(x) == m.x && int(y) == m.y {
if int(x) == mx && int(y) == my { return m.m
return m
} }
} }
return nil return nil

View File

@ -171,10 +171,9 @@ func currentMonitorByOS(_ *glfw.Window) *glfw.Monitor {
} }
x, y := int(mi.rcMonitor.left), int(mi.rcMonitor.top) x, y := int(mi.rcMonitor.left), int(mi.rcMonitor.top)
for _, m := range glfw.GetMonitors() { for _, m := range ensureMonitors() {
mx, my := m.GetPos() if m.x == x && m.y == y {
if mx == x && my == y { return m.m
return m
} }
} }
return nil return nil