internal/ui: use the cursor position to choose the initial monitor for Linux/UNIX

Updates #1918
Closes #1982
This commit is contained in:
Hajime Hoshi 2022-02-08 03:10:59 +09:00
parent 294ee43716
commit 2fc09c7fcb
2 changed files with 28 additions and 31 deletions

View File

@ -169,37 +169,12 @@ 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)
var m *glfw.Monitor m, err := initialMonitorByOS()
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { if err != nil {
var err error return err
m, err = initialMonitorByOS() }
if err != nil { if m == nil {
return err m = glfw.GetPrimaryMonitor()
}
if m == nil {
m = glfw.GetPrimaryMonitor()
}
} else {
// Create a window to set the initial monitor.
// TODO: Instead of a dummy window, get a mouse cursor position and get a monitor from it (#1982).
w, err := glfw.CreateWindow(16, 16, "", nil, nil)
if err != nil {
return err
}
if w == nil {
// This can happen on Windows Remote Desktop (#903).
panic("ui: glfw.CreateWindow must not return nil")
}
defer w.Destroy()
initializeWindowAfterCreation(w)
theUI.waitForFramebufferSizeCallback(w, nil)
m, err = initialMonitorByOS()
if err != nil {
return err
}
if m == nil {
m = currentMonitorImpl(w)
}
} }
theUI.initMonitor = m theUI.initMonitor = m

View File

@ -134,6 +134,28 @@ func (u *UserInterface) adjustWindowPosition(x, y int, monitor *glfw.Monitor) (i
} }
func initialMonitorByOS() (*glfw.Monitor, error) { func initialMonitorByOS() (*glfw.Monitor, error) {
xconn, err := xgb.NewConn()
if err != nil {
// Assume we're on pure Wayland then.
return nil, nil
}
defer xconn.Close()
root := xproto.Setup(xconn).DefaultScreen(xconn).Root
rep, err := xproto.QueryPointer(xconn, root).Reply()
if err != nil {
return nil, err
}
x, y := int(rep.RootX), int(rep.RootY)
// Find the monitor including the cursor.
for _, m := range ensureMonitors() {
w, h := m.vm.Width, m.vm.Height
if x >= m.x && x < m.x+w && y >= m.y && y < m.y+h {
return m.m, nil
}
}
return nil, nil return nil, nil
} }