package xorg import ( "context" "fmt" "time" "github.com/jezek/xgb" "k8s.io/apimachinery/pkg/util/wait" "edge-infra.dev/pkg/sds/display/displaymanager/waiter" "edge-infra.dev/pkg/sds/lib/xorg/xrandr" ) const tick = time.Second // Returns a DisplayWaiter which waits for Xorg to be ready. // // The Xorg waiter will always wait for the specified minimum wait time // and will exit with error if the timeout is reached. func NewXorgDisplayWaiter(r xrandr.Xrandr, minWaitTime, timeout time.Duration) waiter.DisplayWaiter { return &displayWaiter{ Xrandr: r, minWaitTime: minWaitTime, timeout: timeout, } } type displayWaiter struct { xrandr.Xrandr minWaitTime time.Duration timeout time.Duration } func (x *displayWaiter) Wait(ctx context.Context) error { // wait for successful connection to X if err := waitForXgbConnection(ctx, x.timeout); err != nil { return fmt.Errorf("unable to connect to X: %w", err) } return x.Xrandr.WaitUntilReady(x.minWaitTime, x.timeout) } type ConditionWithContextFunc func(context.Context) (done bool, err error) func waitForXgbConnection(ctx context.Context, timeout time.Duration) error { return wait.PollUntilContextTimeout(ctx, tick, timeout, true, func(_ context.Context) (bool, error) { _, err := xgb.NewConn() return err == nil, err }) }