...
1 package xrandr
2
3 import (
4 "fmt"
5 "time"
6
7 "github.com/jezek/xgb"
8 "github.com/jezek/xgb/randr"
9 "github.com/jezek/xgb/xproto"
10 )
11
12 const xSettleTime = 3
13
14 type event struct {
15 xgb.Event
16 xgb.Error
17 }
18
19 func waitForEventSettle(timeout time.Duration, xgbConn *xgb.Conn, rootWindow *xproto.Window) error {
20 enable := randr.NotifyMaskScreenChange | randr.NotifyMaskCrtcChange | randr.NotifyMaskOutputChange | randr.NotifyMaskOutputProperty
21 if err := randr.SelectInputChecked(xgbConn, *rootWindow, uint16(enable)).Check(); err != nil {
22 return fmt.Errorf("failed to check xrandr events: %w", err)
23 }
24
25 now := time.Now()
26 timeoutTime := now.Add(timeout)
27
28 for {
29 eventChannel := make(chan event)
30 go func() {
31 e, err := xgbConn.WaitForEvent()
32 eventChannel <- event{Event: e, Error: err}
33 }()
34
35 select {
36 case e := <-eventChannel:
37 if e.Event == nil && e.Error == nil {
38 return fmt.Errorf("X connection closed unexpectedly while waiting for events")
39 }
40 case <-time.After(xSettleTime * time.Second):
41 return nil
42 }
43
44 if time.Now().After(timeoutTime) {
45 return fmt.Errorf("X events have not settled and timeout was reached")
46 }
47 }
48 }
49
View as plain text