publish immutable, latest-wins OSD snapshots without blocking UART/WFB/video
keep OperatorConfig, GSPolicy, VTXAck, and GSObservedLink distinct, with an explicit versioned seam for future FlightTelemetry from #19/#20
render ARM, adaptive-link state, and authoritative VIDEO ON/OFF from startup; show NO DATA before the first snapshot and visibly retain stale last-known data
map fallback fullscreen/below and transparent input-pass-through OSD fullscreen/above from the first frame
keep OSD above fallback when video is absent and above tracked fullscreen video when present
hide the cursor natively from the first mapped frame on both Ground Station layers, without relying on wfb-ng/unclutter
treat CH6 only as temporary maxPower; never present static configuration as VTX-applied state
Install both binaries from the current head. Expected before video: immediate fullscreen fallback, hidden cursor, visible OSD with VIDEO OFF and explicit no-data/fresh/stale state. Expected after WFB video starts/stops: OSD remains visible above video or fallback and VIDEO ON/OFF follows the display-observed lifecycle. Fresh Orange Pi confirmation remains required.
X11 hardware root-cause correction
Orange Pi logs proved the blank-cursor regression used root-depth (24) pixmaps where X11 CreateCursor requires depth-1 bitmaps. The unchecked cursor failure invalidated the unchecked CreateWindow; the later checked Shape request only surfaced a downstream BadWindow. The current head uses checked depth-1 cursor construction, checked window creation before any Shape/Map request, complete cleanup, and a fail-open default cursor so optional cursor hiding can never suppress either Ground Station layer.
OSD timer starvation correction
Live X11 evidence showed the OSD mapped and topmost but its bounding Shape remained 0x0+0+0 across multiple refresh periods with no errors. The event loop drained a continuous non-Expose root-event stream without returning to timer checks, starving the only 1 Hz redraw that can punch an initially empty Shape. The current head bounds each drain batch to 32 processed events, guaranteeing refresh/liveness/cancellation fairness while preserving event-driven canvas behavior and serialized X11 access.
Closes #3
## Summary
- publish immutable, latest-wins OSD snapshots without blocking UART/WFB/video
- keep `OperatorConfig`, `GSPolicy`, `VTXAck`, and `GSObservedLink` distinct, with an explicit versioned seam for future `FlightTelemetry` from #19/#20
- render ARM, adaptive-link state, and authoritative `VIDEO ON/OFF` from startup; show `NO DATA` before the first snapshot and visibly retain stale last-known data
- map fallback fullscreen/below and transparent input-pass-through OSD fullscreen/above from the first frame
- keep OSD above fallback when video is absent and above tracked fullscreen video when present
- hide the cursor natively from the first mapped frame on both Ground Station layers, without relying on wfb-ng/unclutter
- treat CH6 only as temporary `maxPower`; never present static configuration as VTX-applied state
## Validation
- `gofmt -l .`
- `go vet ./...`
- `go test ./...`
- `go test -race ./...`
- both linux/arm64 binaries with CI-parity settings
- `git diff --check`, cumulative issue-only path review, added-lines secret/security scan
## Hardware acceptance
Install both binaries from the current head. Expected before video: immediate fullscreen fallback, hidden cursor, visible OSD with `VIDEO OFF` and explicit no-data/fresh/stale state. Expected after WFB video starts/stops: OSD remains visible above video or fallback and `VIDEO ON/OFF` follows the display-observed lifecycle. Fresh Orange Pi confirmation remains required.
## X11 hardware root-cause correction
Orange Pi logs proved the blank-cursor regression used root-depth (24) pixmaps where X11 `CreateCursor` requires depth-1 bitmaps. The unchecked cursor failure invalidated the unchecked `CreateWindow`; the later checked Shape request only surfaced a downstream `BadWindow`. The current head uses checked depth-1 cursor construction, checked window creation before any Shape/Map request, complete cleanup, and a fail-open default cursor so optional cursor hiding can never suppress either Ground Station layer.
## OSD timer starvation correction
Live X11 evidence showed the OSD mapped and topmost but its bounding Shape remained `0x0+0+0` across multiple refresh periods with no errors. The event loop drained a continuous non-Expose root-event stream without returning to timer checks, starving the only 1 Hz redraw that can punch an initially empty Shape. The current head bounds each drain batch to 32 processed events, guaranteeing refresh/liveness/cancellation fairness while preserving event-driven canvas behavior and serialized X11 access.
piotr
was assigned by grzesiu2026-10-17 08:49:56 +02:00
grzesiu
changed title from Ground Station OSD data model and overlay renderer to Ground Station OSD data model and always-visible overlay renderer2026-11-03 13:11:57 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #3
Summary
OperatorConfig,GSPolicy,VTXAck, andGSObservedLinkdistinct, with an explicit versioned seam for futureFlightTelemetryfrom #19/#20VIDEO ON/OFFfrom startup; showNO DATAbefore the first snapshot and visibly retain stale last-known datamaxPower; never present static configuration as VTX-applied stateValidation
gofmt -l .go vet ./...go test ./...go test -race ./...git diff --check, cumulative issue-only path review, added-lines secret/security scanHardware acceptance
Install both binaries from the current head. Expected before video: immediate fullscreen fallback, hidden cursor, visible OSD with
VIDEO OFFand explicit no-data/fresh/stale state. Expected after WFB video starts/stops: OSD remains visible above video or fallback andVIDEO ON/OFFfollows the display-observed lifecycle. Fresh Orange Pi confirmation remains required.X11 hardware root-cause correction
Orange Pi logs proved the blank-cursor regression used root-depth (24) pixmaps where X11
CreateCursorrequires depth-1 bitmaps. The unchecked cursor failure invalidated the uncheckedCreateWindow; the later checked Shape request only surfaced a downstreamBadWindow. The current head uses checked depth-1 cursor construction, checked window creation before any Shape/Map request, complete cleanup, and a fail-open default cursor so optional cursor hiding can never suppress either Ground Station layer.OSD timer starvation correction
Live X11 evidence showed the OSD mapped and topmost but its bounding Shape remained
0x0+0+0across multiple refresh periods with no errors. The event loop drained a continuous non-Expose root-event stream without returning to timer checks, starving the only 1 Hz redraw that can punch an initially empty Shape. The current head bounds each drain batch to 32 processed events, guaranteeing refresh/liveness/cancellation fairness while preserving event-driven canvas behavior and serialized X11 access.grzesiu referenced this pull request2026-10-17 21:46:32 +02:00
Ground Station OSD data model and overlay rendererto Ground Station OSD data model and always-visible overlay rendererView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.