//go:build linux package enforce import ( "context" "fmt" "github.com/jezek/xgbutil" "github.com/jezek/xgbutil/ewmh" "github.com/jezek/xgbutil/icccm" ) // NewGuard returns the real X11 window-minimize guard. func NewGuard() Guard { return x11Guard{} } type x11Guard struct{} // MinimizeActive iconifies the currently-focused window by sending an ICCCM // WM_CHANGE_STATE -> IconicState client message to the root window. It opens a // short-lived X connection per call: enforcement fires at most once per drift // observation (which is debounce-gated upstream), so there is no shared // connection or event loop to manage, and nothing to race on shutdown. Any X // failure is returned for the caller to log; the caller never blocks on it. func (x11Guard) MinimizeActive(_ context.Context) error { X, err := xgbutil.NewConn() if err != nil { return fmt.Errorf("enforce: cannot connect to X server: %w", err) } defer X.Conn().Close() active, err := ewmh.ActiveWindowGet(X) if err != nil { return fmt.Errorf("enforce: no active window: %w", err) } if active == 0 { return nil // nothing focused; nothing to minimize } if err := ewmh.ClientEvent(X, active, "WM_CHANGE_STATE", icccm.StateIconic); err != nil { return fmt.Errorf("enforce: minimize request failed: %w", err) } return nil }