...

Source file src/edge-infra.dev/pkg/sds/lib/xorg/xrandr/event.go

Documentation: edge-infra.dev/pkg/sds/lib/xorg/xrandr

     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