internal/ui: refactoring: (*monitors).update must be called from the main thread

In the current implementation, (*monitors).update is not called
from other threads, but the current code is fragile.
This commit is contained in:
Hajime Hoshi 2023-09-24 01:31:32 +09:00
parent 7664647ad1
commit 69e3a2b974
2 changed files with 6 additions and 2 deletions

View File

@ -63,7 +63,7 @@ var theMonitors monitors
func (m *monitors) append(ms []*Monitor) []*Monitor { func (m *monitors) append(ms []*Monitor) []*Monitor {
if atomic.LoadInt32(&m.updateCalled) == 0 { if atomic.LoadInt32(&m.updateCalled) == 0 {
m.update() panic("ui: (*monitors).update must be called before (*monitors).append is called")
} }
m.m.Lock() m.m.Lock()
@ -91,6 +91,7 @@ func (m *monitors) monitorFromID(id int) *Monitor {
return m.monitors[id] return m.monitors[id]
} }
// update must be called from the main thread.
func (m *monitors) update() { func (m *monitors) update() {
glfwMonitors := glfw.GetMonitors() glfwMonitors := glfw.GetMonitors()
newMonitors := make([]*Monitor, 0, len(glfwMonitors)) newMonitors := make([]*Monitor, 0, len(glfwMonitors))

View File

@ -155,13 +155,13 @@ func init() {
func init() { func init() {
hideConsoleWindowOnWindows() hideConsoleWindowOnWindows()
if err := initialize(); err != nil { if err := initialize(); err != nil {
panic(err) panic(err)
} }
glfw.SetMonitorCallback(glfw.ToMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) { glfw.SetMonitorCallback(glfw.ToMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) {
theMonitors.update() theMonitors.update()
})) }))
theMonitors.update()
} }
var glfwSystemCursors = map[CursorShape]*glfw.Cursor{} var glfwSystemCursors = map[CursorShape]*glfw.Cursor{}
@ -174,6 +174,9 @@ func initialize() error {
glfw.WindowHint(glfw.Visible, glfw.False) glfw.WindowHint(glfw.Visible, glfw.False)
glfw.WindowHint(glfw.ClientAPI, glfw.NoAPI) glfw.WindowHint(glfw.ClientAPI, glfw.NoAPI)
// Update the monitor first. The monitor state is depended on various functions like initialMonitorByOS.
theMonitors.update()
m, err := initialMonitorByOS() m, err := initialMonitorByOS()
if err != nil { if err != nil {
return err return err