Create a separate OSD overlay layer above fullscreen video.
Initial sources
GX12 UART final RC channels;
Ground Station lifecycle state;
later: WFB RX RSSI/SNR/loss/FEC and VTX runtime state.
Constraints
OSD refresh may be slower than video.
Video remains the highest-priority render path.
Keep layout/theme intentionally minimal in this issue; detailed visual design is a separate decision.
Do not introduce direct dependency on Betaflight MSP VTX for WFB quality.
## Goal
Create a separate OSD overlay layer above fullscreen video.
## Initial sources
- GX12 UART final RC channels;
- Ground Station lifecycle state;
- later: WFB RX RSSI/SNR/loss/FEC and VTX runtime state.
## Constraints
- OSD refresh may be slower than video.
- Video remains the highest-priority render path.
- Keep layout/theme intentionally minimal in this issue; detailed visual design is a separate decision.
- Do not introduce direct dependency on Betaflight MSP VTX for WFB quality.
Do not begin the on-video renderer until #8 is complete. The existing fallback/menu canvas is intentionally below fpv-video; #8 introduces the distinct transparent top-level overlay needed for OSD over video.
## Dependency update
Do not begin the on-video renderer until #8 is complete. The existing fallback/menu canvas is intentionally below `fpv-video`; #8 introduces the distinct transparent top-level overlay needed for OSD over video.
Order: **#2 → #8 → #3**.
#2 / #9 no-WFB and video-presence lifecycle — closed
#8 / #12 fallback/menu vs transparent OSD layer split — closed
Start #3 now with the data-model/rendering boundary only:
immutable snapshot for final RC state, FC arm state, requested CH6 WFB power, and decoded-video presence;
publish snapshots from the supervisor without blocking UART/WFB/video;
render minimal Viture OSD through the separate top-level overlay layer.
Do not block #3 on #6. WFB RX RSSI/loss/FEC comes later through #6 and is added to the same snapshot model once its adapter exists. Menu/profile work remains #4 after #3.
## Ready to start
Dependencies are now complete:
```text
#2 / #9 no-WFB and video-presence lifecycle — closed
#8 / #12 fallback/menu vs transparent OSD layer split — closed
```
Start #3 now with the data-model/rendering boundary only:
1. immutable snapshot for final RC state, FC arm state, requested CH6 WFB power, and decoded-video presence;
2. publish snapshots from the supervisor without blocking UART/WFB/video;
3. render minimal Viture OSD through the separate top-level overlay layer.
Do not block #3 on #6. WFB RX RSSI/loss/FEC comes later through #6 and is added to the same snapshot model once its adapter exists. Menu/profile work remains #4 after #3.
grzesiu
was assigned by piotr2026-10-17 08:17:01 +02:00
Nowy head: 79ea5d62b70b58a9d85f04ef91d798514c3eac14, liniowo na main@ffae3560c423ab221d991885639612549b057b12.
Follow-up rozdziela cztery niezależne wartości OSD: OperatorConfig, GSPolicy, VTXAck i GSObservedLink. CH6 jest wyłącznie tymczasowym limitem maxPower; poziom 0 oznacza OFF/brak komendy, a brak producenta ma jawny stan pending/unknown. Konfiguracja statyczna nie jest przedstawiana jako stan zastosowany przez VTX. Producenci z #6 i #16–#18 pozostają poza zakresem.
Dane sprzętowe Piotra ujawniły także przyczynę niewidocznego OSD: później przełączone w fullscreen okno video mogło przykryć wcześniej utworzony overlay. OSD ponownie wymusza teraz położenie nad aktywnym, śledzonym oknem video w swoim cyklu odświeżania; dodano test regresyjny.
Walidacja końcowego drzewa przeszła: focused tests, pełne go test ./..., go test -race ./..., vet, gofmt, oba buildy linux/arm64, git diff --check i skan nowych linii. CI dla dokładnego SHA zakończyło się sukcesem: run 233.
Pozostaje akceptacja na Orange Pi po zainstalowaniu obu binariów z nowego headu: potwierdzenie widocznego ARM/adaptive-link OSD nad fullscreen video.
PR #15 zaktualizowany: https://git.piksar.eu/piotr/groundstation/pulls/15
Nowy head: `79ea5d62b70b58a9d85f04ef91d798514c3eac14`, liniowo na `main@ffae3560c423ab221d991885639612549b057b12`.
Follow-up rozdziela cztery niezależne wartości OSD: `OperatorConfig`, `GSPolicy`, `VTXAck` i `GSObservedLink`. CH6 jest wyłącznie tymczasowym limitem `maxPower`; poziom `0` oznacza OFF/brak komendy, a brak producenta ma jawny stan pending/unknown. Konfiguracja statyczna nie jest przedstawiana jako stan zastosowany przez VTX. Producenci z #6 i #16–#18 pozostają poza zakresem.
Dane sprzętowe Piotra ujawniły także przyczynę niewidocznego OSD: później przełączone w fullscreen okno video mogło przykryć wcześniej utworzony overlay. OSD ponownie wymusza teraz położenie nad aktywnym, śledzonym oknem video w swoim cyklu odświeżania; dodano test regresyjny.
Walidacja końcowego drzewa przeszła: focused tests, pełne `go test ./...`, `go test -race ./...`, vet, gofmt, oba buildy linux/arm64, `git diff --check` i skan nowych linii. CI dla dokładnego SHA zakończyło się sukcesem: [run 233](https://git.piksar.eu/piotr/groundstation/actions/runs/233).
Pozostaje akceptacja na Orange Pi po zainstalowaniu **obu** binariów z nowego headu: potwierdzenie widocznego ARM/adaptive-link OSD nad fullscreen video.
Tak — build z PR #15 powinien wyświetlać w lewym górnym rogu dwie białe linie: ARM ARMED/ARM OFF oraz PWR ON/PWR OFF. Stan OFF zmienia tekst, nie ukrywa OSD.
Najpierw sprawdź pochodzenie obu binariów; wymagany commit to f0d5052ccb993ae28d8e730530a1a207157fe482:
go version -m /usr/local/bin/groundstation /usr/local/bin/groundstation-display | grep -E 'vcs.revision|path'
ls -l --time-style=full-iso /usr/local/bin/groundstation*
PR #15 nadal nie jest scalony, a main wskazuje ffae3560…, więc oficjalny artefakt z main nie zawiera jeszcze OSD. Samo podmienienie jednego binarium także nie wystarczy: groundstation publikuje snapshot, a groundstation-display go renderuje.
Jeżeli oba binaria są z f0d5052…, sprawdź kolejno:
Plik /run/groundstation/osd-state.bin musi istnieć i mieć mtime odświeżane mniej więcej co 0,5 s; display odrzuca stan starszy niż 2 s. Nie wyświetlaj zawartości pliku ani .Xauthority.
wymieniono tylko jedno z dwóch binariów albo usługi nie zrestartowano;
brak świeżego snapshotu z poprawnych ramek UART, niezgodna ścieżka -osd-state lub display nie widzi okna video przez X11.
Podeślij wynik powyższych poleceń; wskażę dokładnie, na której bramce zatrzymuje się OSD.
Tak — build z PR #15 powinien wyświetlać w lewym górnym rogu dwie białe linie: `ARM ARMED`/`ARM OFF` oraz `PWR ON`/`PWR OFF`. Stan OFF zmienia tekst, nie ukrywa OSD.
Najpierw sprawdź pochodzenie **obu** binariów; wymagany commit to `f0d5052ccb993ae28d8e730530a1a207157fe482`:
```sh
go version -m /usr/local/bin/groundstation /usr/local/bin/groundstation-display | grep -E 'vcs.revision|path'
ls -l --time-style=full-iso /usr/local/bin/groundstation*
```
PR #15 nadal nie jest scalony, a `main` wskazuje `ffae3560…`, więc oficjalny artefakt z `main` nie zawiera jeszcze OSD. Samo podmienienie jednego binarium także nie wystarczy: `groundstation` publikuje snapshot, a `groundstation-display` go renderuje.
Jeżeli oba binaria są z `f0d5052…`, sprawdź kolejno:
```sh
systemctl cat groundstation
systemctl status groundstation --no-pager
journalctl -u groundstation -b --no-pager -n 80
journalctl -u groundstation -b --no-pager | grep -iE 'osd|UART|display reconnect|discard frame'
ps -ef | grep -E 'groundstation|fpv-video'
stat -c '%y %s %a %n' /run/groundstation/osd-state.bin
sleep 1
stat -c '%y %s %a %n' /run/groundstation/osd-state.bin
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority wmctrl -l
```
Plik `/run/groundstation/osd-state.bin` musi istnieć i mieć mtime odświeżane mniej więcej co 0,5 s; display odrzuca stan starszy niż 2 s. Nie wyświetlaj zawartości pliku ani `.Xauthority`.
Najbardziej prawdopodobne przyczyny:
1. uruchomione są binaria z `main`, a nie z PR #15;
2. wymieniono tylko jedno z dwóch binariów albo usługi nie zrestartowano;
3. brak świeżego snapshotu z poprawnych ramek UART, niezgodna ścieżka `-osd-state` lub display nie widzi okna video przez X11.
Podeślij wynik powyższych poleceń; wskażę dokładnie, na której bramce zatrzymuje się OSD.
Poprzednia blokada diagnostyczna jest nieaktualna. Kolejny recovery zakończył się poprawnie, wykazał czysty worktree po awariach, a poprawka została zreviewowana, zwalidowana i wypchnięta do PR #15 jako 79ea5d62b70b58a9d85f04ef91d798514c3eac14. CI run 233 zakończyło się sukcesem. Oczekiwana jest wyłącznie świeża akceptacja sprzętowa po instalacji obu binariów.
Poprzednia blokada diagnostyczna jest nieaktualna. Kolejny recovery zakończył się poprawnie, wykazał czysty worktree po awariach, a poprawka została zreviewowana, zwalidowana i wypchnięta do PR #15 jako `79ea5d62b70b58a9d85f04ef91d798514c3eac14`. CI [run 233](https://git.piksar.eu/piotr/groundstation/actions/runs/233) zakończyło się sukcesem. Oczekiwana jest wyłącznie świeża akceptacja sprzętowa po instalacji obu binariów.
The OSD initially renders target/table/level/applied state even before adaptive control exists. Do not show static YAML as applied VTX state.
This issue is the prerequisite for table-driven control; see new follow-up issues for provisioning and runtime execution.
## Adaptive-link architecture update
OSD must model four distinct values, never one ambiguous “mode/power” field:
```text
OperatorConfig → selected table generation/hash and temporary CH6 maxPower
GSPolicy → requested runtime level 0..127 plus reason/timestamp
VTXAck → accepted table generation/hash, applied level, lifecycle/error
GSObservedLink → WFB receiver metrics and freshness
```
The OSD initially renders target/table/level/applied state even before adaptive control exists. Do not show static YAML as applied VTX state.
This issue is the prerequisite for table-driven control; see new follow-up issues for provisioning and runtime execution.
ODS layer is not rendered. When ground station starts It shows a window which is not fullscreen. there is no osd data. after wfb-ng stream starts it is opened fullscreen but still no osd data. I expect fullscreen app even without video stream and old data on top of it. If there is no video the info should be included in osd too
ODS layer is not rendered. When ground station starts It shows a window which is not fullscreen. there is no osd data. after wfb-ng stream starts it is opened fullscreen but still no osd data. I expect fullscreen app even without video stream and old data on top of it. If there is no video the info should be included in osd too
Nowy head: 3d6d1460075115b524cdb85c276cb1890e6e1347.
Dodatkowo zmieniono kontrakt wyświetlania zgodnie z obserwacją Piotra:
fallback i OSD mapują się fullscreen od pierwszej klatki, jeszcze przed video (FULLSCREEN+BELOW / FULLSCREEN+ABOVE ustawione przed MapWindow);
OSD renderuje się także bez streamu i pokazuje VIDEO OFF;
przed pierwszym snapshotem pokazuje jawne NO DATA/wartości nieznane;
ostatnie poprawne dane nie znikają po przekroczeniu freshness — pozostają jako wyraźnie DATA STALE;
po pojawieniu się fullscreen video OSD pozostaje nad nim i przełącza stan na VIDEO ON.
Niezależny review wykrył, że wcześniejsze żądanie fullscreen dopiero po mapowaniu pozwalało XFCE najpierw udekorować/przesunąć okna albo nie przełączyć ich bez wmctrl; poprawiono to właściwościami EWMH pre-map i dodano test regresyjny.
Końcowa walidacja: focused tests, go test ./..., go test -race ./..., vet, gofmt, oba buildy linux/arm64, git diff --check i skan nowych linii — wszystko zaliczone. CI dla dokładnego SHA: run 300completed / success.
Pozostaje świeża akceptacja na Orange Pi po zainstalowaniu obu binariów z tego headu.
Follow-up sprzętowy wdrożony do PR https://git.piksar.eu/piotr/groundstation/pulls/15
Nowy head: `3d6d1460075115b524cdb85c276cb1890e6e1347`.
Dodatkowo zmieniono kontrakt wyświetlania zgodnie z obserwacją Piotra:
- fallback i OSD mapują się fullscreen od pierwszej klatki, jeszcze przed video (`FULLSCREEN+BELOW` / `FULLSCREEN+ABOVE` ustawione przed `MapWindow`);
- OSD renderuje się także bez streamu i pokazuje `VIDEO OFF`;
- przed pierwszym snapshotem pokazuje jawne `NO DATA`/wartości nieznane;
- ostatnie poprawne dane nie znikają po przekroczeniu freshness — pozostają jako wyraźnie `DATA STALE`;
- po pojawieniu się fullscreen video OSD pozostaje nad nim i przełącza stan na `VIDEO ON`.
Niezależny review wykrył, że wcześniejsze żądanie fullscreen dopiero po mapowaniu pozwalało XFCE najpierw udekorować/przesunąć okna albo nie przełączyć ich bez `wmctrl`; poprawiono to właściwościami EWMH pre-map i dodano test regresyjny.
Końcowa walidacja: focused tests, `go test ./...`, `go test -race ./...`, vet, gofmt, oba buildy linux/arm64, `git diff --check` i skan nowych linii — wszystko zaliczone. CI dla dokładnego SHA: [run 300](https://git.piksar.eu/piotr/groundstation/actions/runs/300) `completed / success`.
Pozostaje świeża akceptacja na Orange Pi po zainstalowaniu obu binariów z tego headu.
It's better because there is fullscreen on gs process start. But there is cursor visible which disappears only if wfb-ng is enabled. Cursor should be hidden. OSD still does not show
It's better because there is fullscreen on gs process start. But there is cursor visible which disappears only if wfb-ng is enabled. Cursor should be hidden. OSD still does not show
Tracked by #20. This remains the active first item. Keep its state model extensible for FlightTelemetry, GSObservedLink, policy table identity and requested/applied level.
Tracked by https://git.piksar.eu/piotr/groundstation/issues/20. This remains the active first item. Keep its state model extensible for `FlightTelemetry`, `GSObservedLink`, policy table identity and requested/applied level.
Nowy head: 296569232e3e300483955f29d36f69d0647506d4.
Naprawiono dwie potwierdzone przyczyny:
kursor jest teraz ukrywany natywnym pustym kursorem X11 na obu warstwach od pierwszej zmapowanej klatki; nie zależy już od wfb-ng, fpv-video ani unclutter;
po zatrzymaniu video fallback podnosił się nad OSD, a OSD ponawiało stacking tylko przy aktywnym video. Teraz bez video OSD okresowo wraca nad fallback, a z video pozostaje nad śledzonym oknem streamu.
Uwzględniono też steering z #20/#19: obecny wersjonowany model zachowuje rozłączne domeny GSObservedLink, table identity oraz requested/applied level i ma udokumentowany seam dla przyszłego FlightTelemetry, bez pustych/fikcyjnych pól runtime. Testy pinują rozłączne zakresy, atomowe odrzucanie uszkodzonych rekordów i samonaprawę po heartbeat.
Pełna walidacja końcowego drzewa przeszła: go test ./..., go test -race ./..., vet, gofmt, oba buildy linux/arm64, git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 301completed / success.
Pozostaje ponowna akceptacja na Orange Pi po instalacji obu binariów z tego headu: kursor ukryty od startu oraz widoczne OSD przed, podczas i po cyklu video.
Kolejny follow-up sprzętowy gotowy w PR https://git.piksar.eu/piotr/groundstation/pulls/15
Nowy head: `296569232e3e300483955f29d36f69d0647506d4`.
Naprawiono dwie potwierdzone przyczyny:
- kursor jest teraz ukrywany natywnym pustym kursorem X11 na obu warstwach od pierwszej zmapowanej klatki; nie zależy już od `wfb-ng`, `fpv-video` ani `unclutter`;
- po zatrzymaniu video fallback podnosił się nad OSD, a OSD ponawiało stacking tylko przy aktywnym video. Teraz bez video OSD okresowo wraca nad fallback, a z video pozostaje nad śledzonym oknem streamu.
Uwzględniono też steering z #20/#19: obecny wersjonowany model zachowuje rozłączne domeny `GSObservedLink`, table identity oraz requested/applied level i ma udokumentowany seam dla przyszłego `FlightTelemetry`, bez pustych/fikcyjnych pól runtime. Testy pinują rozłączne zakresy, atomowe odrzucanie uszkodzonych rekordów i samonaprawę po heartbeat.
Pełna walidacja końcowego drzewa przeszła: `go test ./...`, `go test -race ./...`, vet, gofmt, oba buildy linux/arm64, `git diff --check`, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: [run 301](https://git.piksar.eu/piotr/groundstation/actions/runs/301) `completed / success`.
Pozostaje ponowna akceptacja na Orange Pi po instalacji obu binariów z tego headu: kursor ukryty od startu oraz widoczne OSD przed, podczas i po cyklu video.
It broke groundstation window. now cursor disappears if I set aux to >10 but window is not showing. it appears only if vtx is enabled. I want a gs window (fullscreen) always visible - even if vtx power aux <10. This should be main window that appears on orangepi start.
OSD still is not visible (tested when video was streamed)
It broke groundstation window. now cursor disappears if I set aux to >10 but window is not showing. it appears only if vtx is enabled. I want a gs window (fullscreen) always visible - even if vtx power aux <10. This should be main window that appears on orangepi start.
OSD still is not visible (tested when video was streamed)
Wycofuję wcześniejsze stwierdzenie, że główną przyczyną jest zakopanie okien przez globalne hinty BELOW/ABOVE. Wynik AUX OFF i ON falsyfikuje tę diagnozę jako przyczynę bieżącego objawu: obu okien Ground Station w ogóle nie ma w _NET_CLIENT_LIST_STACKING ani wmctrl.
Kod tworzy oba okna jako zarządzane InputOutput, dzieci root window, bez override_redirect, i wykonuje MapWindow. Gdyby były tylko zasłonięte lub miały pusty Shape, nadal występowałyby na liście klientów. Ich brak oznacza, że groundstation-display ich nie mapuje albo po nieudanym Open niszczy połączenie/okna i pozostaje w pętli reconnect.
Hipotezy do rozróżnienia:
Najbardziej prawdopodobna:Open obu warstw kończy się błędem X11 i reconnectem; log pokaże powtarzane open_failed/błąd zasobu lub autoryzacji, a pełne drzewo nie pokaże okien GS.
Uruchomione binarium/proces nie odpowiada aktualnemu headowi albo proces display nie działa; brak właściwego procesu/revision i brak okien.
Okna istnieją krótko pomiędzy reconnectami; drzewo może je pokazać jako 1920x1080 root children, ale kolejne próbki znikną.
Uruchom poniższy blok przy AUX OFF. Nie odczytuje .Xauthority ani innych sekretów:
echo'=== PROCESS / REVISION ==='
ps -eo pid,lstart,args | grep -E '[g]roundstation-display|[g]roundstation -config'command -v go >/dev/null && go version -m /usr/local/bin/groundstation /usr/local/bin/groundstation-display | grep -E 'path|vcs.revision'||trueecho'=== DISPLAY ERRORS THIS BOOT ==='
journalctl -u groundstation -b --no-pager | grep -iE 'display reconnect|open_failed|wait_failed|BadCursor|BadPixmap|BadWindow|x protocol|connect X11'| tail -n 120echo'=== FULL ROOT TREE ==='
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority xwininfo -root -tree
echo'=== FULLSCREEN ROOT CHILD CANDIDATES ==='
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority sh -c '
ids=$(xwininfo -root -tree | sed -nE "s/^[[:space:]]*(0x[0-9a-fA-F]+).*1920x1080.*/\1/p")
for id in $ids; do
echo "=== WINDOW $id ==="
xprop -id "$id" WM_CLASS WM_NAME _NET_WM_WINDOW_TYPE _NET_WM_STATE 2>&1
xwininfo -id "$id" 2>&1 | grep -E "Parent window id|Map State|Override Redirect State|Absolute upper-left|Width:|Height:"
done
'
Nie wykonuję kolejnej zmiany kodu przed wskazaniem dokładnego błędu Open albo potwierdzeniem, że okna są mapowane i znikają.
## Korekta diagnozy po live stacku
Wycofuję wcześniejsze stwierdzenie, że główną przyczyną jest zakopanie okien przez globalne hinty `BELOW/ABOVE`. Wynik AUX OFF i ON falsyfikuje tę diagnozę jako przyczynę bieżącego objawu: obu okien Ground Station w ogóle nie ma w `_NET_CLIENT_LIST_STACKING` ani `wmctrl`.
Kod tworzy oba okna jako zarządzane `InputOutput`, dzieci root window, bez `override_redirect`, i wykonuje `MapWindow`. Gdyby były tylko zasłonięte lub miały pusty Shape, nadal występowałyby na liście klientów. Ich brak oznacza, że `groundstation-display` ich nie mapuje albo po nieudanym `Open` niszczy połączenie/okna i pozostaje w pętli reconnect.
Hipotezy do rozróżnienia:
1. **Najbardziej prawdopodobna:** `Open` obu warstw kończy się błędem X11 i reconnectem; log pokaże powtarzane `open_failed`/błąd zasobu lub autoryzacji, a pełne drzewo nie pokaże okien GS.
2. Uruchomione binarium/proces nie odpowiada aktualnemu headowi albo proces display nie działa; brak właściwego procesu/revision i brak okien.
3. Okna istnieją krótko pomiędzy reconnectami; drzewo może je pokazać jako 1920x1080 root children, ale kolejne próbki znikną.
Uruchom poniższy blok przy AUX OFF. Nie odczytuje `.Xauthority` ani innych sekretów:
```sh
echo '=== PROCESS / REVISION ==='
ps -eo pid,lstart,args | grep -E '[g]roundstation-display|[g]roundstation -config'
command -v go >/dev/null && go version -m /usr/local/bin/groundstation /usr/local/bin/groundstation-display | grep -E 'path|vcs.revision' || true
echo '=== DISPLAY ERRORS THIS BOOT ==='
journalctl -u groundstation -b --no-pager | grep -iE 'display reconnect|open_failed|wait_failed|BadCursor|BadPixmap|BadWindow|x protocol|connect X11' | tail -n 120
echo '=== FULL ROOT TREE ==='
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority xwininfo -root -tree
echo '=== FULLSCREEN ROOT CHILD CANDIDATES ==='
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority sh -c '
ids=$(xwininfo -root -tree | sed -nE "s/^[[:space:]]*(0x[0-9a-fA-F]+).*1920x1080.*/\1/p")
for id in $ids; do
echo "=== WINDOW $id ==="
xprop -id "$id" WM_CLASS WM_NAME _NET_WM_WINDOW_TYPE _NET_WM_STATE 2>&1
xwininfo -id "$id" 2>&1 | grep -E "Parent window id|Map State|Override Redirect State|Absolute upper-left|Width:|Height:"
done
'
```
Nie wykonuję kolejnej zmiany kodu przed wskazaniem dokładnego błędu `Open` albo potwierdzeniem, że okna są mapowane i znikają.
PR #15 pozostaje otwarty na headzie 296569232e3e300483955f29d36f69d0647506d4; CI run 301 jest zielone.
Błąd sprzętowy nie jest rozwiązany: przy AUX OFF i ON oba okna Ground Station są nieobecne w wmctrl i _NET_CLIENT_LIST_STACKING.
To falsyfikuje wcześniejszą diagnozę o samym zakryciu warstw. Kod oczekuje dwóch zarządzanych, zmapowanych okien; ich brak wskazuje na nieudany Open/pętlę reconnect, niewłaściwe binarium albo bardzo krótkie mapowanie i niszczenie okien.
Worktree i zdalny PR są czyste; nie ma aktywnego joba ani nieopublikowanych zmian.
Do wskazania dokładnego błędu brakuje wyniku drugiego, poprawionego bloku z komentarza #1284: sekcji PROCESS / REVISION, DISPLAY ERRORS THIS BOOT oraz pełnego xwininfo -root -tree. Pierwszy przesłany blok obejmował tylko zarządzane klienty i nie pokazuje błędu Open.
Po wklejeniu tego jednego wyniku rozstrzygnę, czy problemem jest BadCursor/BadPixmap, Xauth/reconnect, deployment starego binarium czy krótkotrwałe niszczenie okien. Do tego czasu nie dokładam kolejnej spekulacyjnej poprawki.
Status:
- PR #15 pozostaje otwarty na headzie `296569232e3e300483955f29d36f69d0647506d4`; CI [run 301](https://git.piksar.eu/piotr/groundstation/actions/runs/301) jest zielone.
- Błąd sprzętowy **nie jest rozwiązany**: przy AUX OFF i ON oba okna Ground Station są nieobecne w `wmctrl` i `_NET_CLIENT_LIST_STACKING`.
- To falsyfikuje wcześniejszą diagnozę o samym zakryciu warstw. Kod oczekuje dwóch zarządzanych, zmapowanych okien; ich brak wskazuje na nieudany `Open`/pętlę reconnect, niewłaściwe binarium albo bardzo krótkie mapowanie i niszczenie okien.
- Worktree i zdalny PR są czyste; nie ma aktywnego joba ani nieopublikowanych zmian.
Do wskazania dokładnego błędu brakuje wyniku **drugiego, poprawionego bloku** z komentarza `#1284`: sekcji `PROCESS / REVISION`, `DISPLAY ERRORS THIS BOOT` oraz pełnego `xwininfo -root -tree`. Pierwszy przesłany blok obejmował tylko zarządzane klienty i nie pokazuje błędu `Open`.
Po wklejeniu tego jednego wyniku rozstrzygnę, czy problemem jest `BadCursor`/`BadPixmap`, Xauth/reconnect, deployment starego binarium czy krótkotrwałe niszczenie okien. Do tego czasu nie dokładam kolejnej spekulacyjnej poprawki.
Poprawka potwierdzonego root cause jest gotowa w PR #15
Nowy head: b7e054e94913abe16292cf9e08d848ccf46acdd9.
Log Orange Pi wskazał dokładny łańcuch błędu: blank cursor tworzył source/mask pixmapy z głębokością root window 24, choć X11 CreateCursor wymaga bitmap depth 1. Niesprawdzony CreateCursor kończył się błędem, niepoprawny cursor unieważniał niesprawdzony CreateWindow, a dopiero kolejny sprawdzany Shape zgłaszał wtórny BadWindow. Dlatego oba okna GS nie istniały i display pozostawał w reconnect loop.
Naprawa:
depth-1 bitmapy i depth-compatible GC;
sprawdzanie każdego żądania kursora oraz CreateWindow z dokładnym wskazaniem błędu;
brak Shape/Map na nieutworzonym oknie;
opcjonalna awaria ukrycia kursora nie blokuje mapowania okna z domyślnym kursorem ani nie powoduje reconnect storm;
pełny cleanup zasobów, w tym ścieżki błędów.
Niezależny review i pełna walidacja przeszły: focused/race tests, go test ./..., go test -race ./..., vet, gofmt, oba buildy linux/arm64, git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 309completed / success.
Po instalacji obu binariów z tego headu oczekiwane jest zniknięcie pętli empty shape region 2: BadWindow, obecność obu okien GS od startu oraz widoczne OSD niezależnie od AUX/video. Pozostaje świeża akceptacja na Orange Pi.
Poprawka potwierdzonego root cause jest gotowa w PR https://git.piksar.eu/piotr/groundstation/pulls/15
Nowy head: `b7e054e94913abe16292cf9e08d848ccf46acdd9`.
Log Orange Pi wskazał dokładny łańcuch błędu: blank cursor tworzył source/mask pixmapy z głębokością root window `24`, choć X11 `CreateCursor` wymaga bitmap depth `1`. Niesprawdzony `CreateCursor` kończył się błędem, niepoprawny cursor unieważniał niesprawdzony `CreateWindow`, a dopiero kolejny sprawdzany Shape zgłaszał wtórny `BadWindow`. Dlatego oba okna GS nie istniały i display pozostawał w reconnect loop.
Naprawa:
- depth-1 bitmapy i depth-compatible GC;
- sprawdzanie każdego żądania kursora oraz `CreateWindow` z dokładnym wskazaniem błędu;
- brak Shape/Map na nieutworzonym oknie;
- opcjonalna awaria ukrycia kursora nie blokuje mapowania okna z domyślnym kursorem ani nie powoduje reconnect storm;
- pełny cleanup zasobów, w tym ścieżki błędów.
Niezależny review i pełna walidacja przeszły: focused/race tests, `go test ./...`, `go test -race ./...`, vet, gofmt, oba buildy linux/arm64, `git diff --check`, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: [run 309](https://git.piksar.eu/piotr/groundstation/actions/runs/309) `completed / success`.
Po instalacji obu binariów z tego headu oczekiwane jest zniknięcie pętli `empty shape region 2: BadWindow`, obecność obu okien GS od startu oraz widoczne OSD niezależnie od AUX/video. Pozostaje świeża akceptacja na Orange Pi.
Aktualny trace kodu wyklucza dwie hipotezy: template zawsze generuje NO DATA/VIDEO OFF, a po rysowaniu nie ma czyszczenia tekstu. Pusty początkowy Shape nie powinien blokować całości, bo OSD ma niezależny refresh 1 Hz.
Najbardziej prawdopodobny jest teraz konflikt warstwy xfwm4: kombinacja OSD DOCK + FULLSCREEN + ABOVE może przypisać je do globalnej warstwy, w której sibling restack nie przechodzi nad canvas/video. Drugą możliwością jest to, że 1 Hz redraw nie rozszerza bounding Shape na urządzeniu.
Uruchom blok dwa razy — AUX/video OFF, potem ON. W każdej próbie wykonuje dwie próbki Shape oddzielone 2 sekundami. Nie odczytuje sekretów:
jeśli OSD ma niepusty Shape, lecz leży pod canvas/video — potwierdzony jest konflikt globalnych warstw;
jeśli jego Shape pozostaje pusty w obu próbkach — problem jest w produkcyjnym punch/flush;
jeśli OSD znów znika z listy — log wskaże nowy błąd Open/reconnect.
Aktualny trace kodu wyklucza dwie hipotezy: template zawsze generuje `NO DATA`/`VIDEO OFF`, a po rysowaniu nie ma czyszczenia tekstu. Pusty początkowy Shape nie powinien blokować całości, bo OSD ma niezależny refresh 1 Hz.
Najbardziej prawdopodobny jest teraz konflikt warstwy xfwm4: kombinacja OSD `DOCK + FULLSCREEN + ABOVE` może przypisać je do globalnej warstwy, w której sibling restack nie przechodzi nad canvas/video. Drugą możliwością jest to, że 1 Hz redraw nie rozszerza bounding Shape na urządzeniu.
Uruchom blok dwa razy — **AUX/video OFF**, potem **ON**. W każdej próbie wykonuje dwie próbki Shape oddzielone 2 sekundami. Nie odczytuje sekretów:
```sh
printf '
=== MODE: AUX VIDEO OFF/ON (dopisz ręcznie) ===
'
echo '=== DISPLAY ERRORS / STACK ==='
journalctl -u groundstation -b --no-pager | grep -iE 'display reconnect|open_failed|wait_failed|shape|stack|BadWindow|x protocol' | tail -n 80
runuser -u orangepi -- env DISPLAY=:0 XAUTHORITY=/home/orangepi/.Xauthority sh -c '
echo "=== WM CLIENTS ==="
wmctrl -lGx
echo "=== STACK BOTTOM -> TOP ==="
xprop -root _NET_CLIENT_LIST_STACKING
echo "=== ROOT TREE ==="
xwininfo -root -tree
ids=$(xprop -root _NET_CLIENT_LIST_STACKING | cut -d# -f2 | tr "," " ")
for sample in 1 2; do
echo "=== SAMPLE $sample ==="
for id in $ids; do
echo "=== WINDOW $id ==="
xprop -id "$id" WM_CLASS WM_NAME _NET_WM_WINDOW_TYPE _NET_WM_STATE _NET_FRAME_EXTENTS 2>&1
xwininfo -shape -id "$id" 2>&1 | grep -E "Map State|Override Redirect State|Absolute upper-left|Width:|Height:|Window shape extents|Bounding Shape|Clip Shape"
done
sleep 2
done
'
```
Interpretacja:
- jeśli OSD ma niepusty Shape, lecz leży pod canvas/video — potwierdzony jest konflikt globalnych warstw;
- jeśli jego Shape pozostaje pusty w obu próbkach — problem jest w produkcyjnym punch/flush;
- jeśli OSD znów znika z listy — log wskaże nowy błąd Open/reconnect.
Poprawka potwierdzonego braku OSD jest gotowa w PR #15
Nowy head: 5d067ee82d7c0446efdd1ae2cffa40e208ec2843.
Live pomiar wykazał, że okno OSD było zmapowane i topmost zarówno bez video, jak i nad fullscreen streamem, ale jego bounding Shape pozostawał 0x0+0+0 w dwóch próbkach oddzielonych ponad jednym okresem refresh. To wykluczyło stacking.
Root cause: pętla X11 opróżniała kolejkę zdarzeń w nieograniczonym inner loop. Ciągły strumień non-Expose root events nie pozwalał wrócić do timera 1 Hz; jedyny redraw mogący rozszerzyć początkowo pusty Shape nigdy się nie wykonywał.
Naprawa ogranicza partię do 32 przetworzonych zdarzeń, po czym zawsze obsługuje refresh, liveness i cancellation. Żadne zdarzenia nie są odrzucane; canvas pozostaje event-driven; wejściowy Shape OSD pozostaje pusty, a bounding Shape jest aktualizowany przez template ops.
Niezależny review i pełna walidacja przeszły: storm regression tests, focused/race tests, go test ./..., go test -race ./..., vet, gofmt, oba buildy linux/arm64, git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 321completed / success.
Po instalacji obu binariów z tego headu OSD powinno rozszerzyć Shape w pierwszym cyklu refresh i pokazać co najmniej NO DATA/VIDEO OFF, a następnie aktualne lub DATA STALE wartości. Pozostaje świeża akceptacja na Orange Pi.
Poprawka potwierdzonego braku OSD jest gotowa w PR https://git.piksar.eu/piotr/groundstation/pulls/15
Nowy head: `5d067ee82d7c0446efdd1ae2cffa40e208ec2843`.
Live pomiar wykazał, że okno OSD było zmapowane i topmost zarówno bez video, jak i nad fullscreen streamem, ale jego bounding Shape pozostawał `0x0+0+0` w dwóch próbkach oddzielonych ponad jednym okresem refresh. To wykluczyło stacking.
Root cause: pętla X11 opróżniała kolejkę zdarzeń w nieograniczonym inner loop. Ciągły strumień non-Expose root events nie pozwalał wrócić do timera 1 Hz; jedyny redraw mogący rozszerzyć początkowo pusty Shape nigdy się nie wykonywał.
Naprawa ogranicza partię do 32 przetworzonych zdarzeń, po czym zawsze obsługuje refresh, liveness i cancellation. Żadne zdarzenia nie są odrzucane; canvas pozostaje event-driven; wejściowy Shape OSD pozostaje pusty, a bounding Shape jest aktualizowany przez template ops.
Niezależny review i pełna walidacja przeszły: storm regression tests, focused/race tests, `go test ./...`, `go test -race ./...`, vet, gofmt, oba buildy linux/arm64, `git diff --check`, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: [run 321](https://git.piksar.eu/piotr/groundstation/actions/runs/321) `completed / success`.
Po instalacji obu binariów z tego headu OSD powinno rozszerzyć Shape w pierwszym cyklu refresh i pokazać co najmniej `NO DATA`/`VIDEO OFF`, a następnie aktualne lub `DATA STALE` wartości. Pozostaje świeża akceptacja na Orange Pi.
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.
Goal
Create a separate OSD overlay layer above fullscreen video.
Initial sources
Constraints
Dependency update
Do not begin the on-video renderer until #8 is complete. The existing fallback/menu canvas is intentionally below
fpv-video; #8 introduces the distinct transparent top-level overlay needed for OSD over video.Order: #2 → #8 → #3.
Ready to start
Dependencies are now complete:
Start #3 now with the data-model/rendering boundary only:
Do not block #3 on #6. WFB RX RSSI/loss/FEC comes later through #6 and is added to the same snapshot model once its adapter exists. Menu/profile work remains #4 after #3.
PR #15 zaktualizowany: #15
Nowy head:
79ea5d62b70b58a9d85f04ef91d798514c3eac14, liniowo namain@ffae3560c423ab221d991885639612549b057b12.Follow-up rozdziela cztery niezależne wartości OSD:
OperatorConfig,GSPolicy,VTXAckiGSObservedLink. CH6 jest wyłącznie tymczasowym limitemmaxPower; poziom0oznacza OFF/brak komendy, a brak producenta ma jawny stan pending/unknown. Konfiguracja statyczna nie jest przedstawiana jako stan zastosowany przez VTX. Producenci z #6 i #16–#18 pozostają poza zakresem.Dane sprzętowe Piotra ujawniły także przyczynę niewidocznego OSD: później przełączone w fullscreen okno video mogło przykryć wcześniej utworzony overlay. OSD ponownie wymusza teraz położenie nad aktywnym, śledzonym oknem video w swoim cyklu odświeżania; dodano test regresyjny.
Walidacja końcowego drzewa przeszła: focused tests, pełne
go test ./...,go test -race ./..., vet, gofmt, oba buildy linux/arm64,git diff --checki skan nowych linii. CI dla dokładnego SHA zakończyło się sukcesem: run 233.Pozostaje akceptacja na Orange Pi po zainstalowaniu obu binariów z nowego headu: potwierdzenie widocznego ARM/adaptive-link OSD nad fullscreen video.
spróbuj ponownie. obraz buildera powinien być teraz obecny
Uruchomiłem nowy groundstation ale nie widzę żadnego dodatkowego overlaya OSD. Czy już coś powinno się renderować?
Tak — build z PR #15 powinien wyświetlać w lewym górnym rogu dwie białe linie:
ARM ARMED/ARM OFForazPWR ON/PWR OFF. Stan OFF zmienia tekst, nie ukrywa OSD.Najpierw sprawdź pochodzenie obu binariów; wymagany commit to
f0d5052ccb993ae28d8e730530a1a207157fe482:PR #15 nadal nie jest scalony, a
mainwskazujeffae3560…, więc oficjalny artefakt zmainnie zawiera jeszcze OSD. Samo podmienienie jednego binarium także nie wystarczy:groundstationpublikuje snapshot, agroundstation-displaygo renderuje.Jeżeli oba binaria są z
f0d5052…, sprawdź kolejno:Plik
/run/groundstation/osd-state.binmusi istnieć i mieć mtime odświeżane mniej więcej co 0,5 s; display odrzuca stan starszy niż 2 s. Nie wyświetlaj zawartości pliku ani.Xauthority.Najbardziej prawdopodobne przyczyny:
main, a nie z PR #15;-osd-statelub display nie widzi okna video przez X11.Podeślij wynik powyższych poleceń; wskażę dokładnie, na której bramce zatrzymuje się OSD.
Poprzednia blokada diagnostyczna jest nieaktualna. Kolejny recovery zakończył się poprawnie, wykazał czysty worktree po awariach, a poprawka została zreviewowana, zwalidowana i wypchnięta do PR #15 jako
79ea5d62b70b58a9d85f04ef91d798514c3eac14. CI run 233 zakończyło się sukcesem. Oczekiwana jest wyłącznie świeża akceptacja sprzętowa po instalacji obu binariów.Adaptive-link architecture update
OSD must model four distinct values, never one ambiguous “mode/power” field:
The OSD initially renders target/table/level/applied state even before adaptive control exists. Do not show static YAML as applied VTX state.
This issue is the prerequisite for table-driven control; see new follow-up issues for provisioning and runtime execution.
ODS layer is not rendered. When ground station starts It shows a window which is not fullscreen. there is no osd data. after wfb-ng stream starts it is opened fullscreen but still no osd data. I expect fullscreen app even without video stream and old data on top of it. If there is no video the info should be included in osd too
Follow-up sprzętowy wdrożony do PR #15
Nowy head:
3d6d1460075115b524cdb85c276cb1890e6e1347.Dodatkowo zmieniono kontrakt wyświetlania zgodnie z obserwacją Piotra:
FULLSCREEN+BELOW/FULLSCREEN+ABOVEustawione przedMapWindow);VIDEO OFF;NO DATA/wartości nieznane;DATA STALE;VIDEO ON.Niezależny review wykrył, że wcześniejsze żądanie fullscreen dopiero po mapowaniu pozwalało XFCE najpierw udekorować/przesunąć okna albo nie przełączyć ich bez
wmctrl; poprawiono to właściwościami EWMH pre-map i dodano test regresyjny.Końcowa walidacja: focused tests,
go test ./...,go test -race ./..., vet, gofmt, oba buildy linux/arm64,git diff --checki skan nowych linii — wszystko zaliczone. CI dla dokładnego SHA: run 300completed / success.Pozostaje świeża akceptacja na Orange Pi po zainstalowaniu obu binariów z tego headu.
It's better because there is fullscreen on gs process start. But there is cursor visible which disappears only if wfb-ng is enabled. Cursor should be hidden. OSD still does not show
Tracked by #20. This remains the active first item. Keep its state model extensible for
FlightTelemetry,GSObservedLink, policy table identity and requested/applied level.Kolejny follow-up sprzętowy gotowy w PR #15
Nowy head:
296569232e3e300483955f29d36f69d0647506d4.Naprawiono dwie potwierdzone przyczyny:
wfb-ng,fpv-videoaniunclutter;Uwzględniono też steering z #20/#19: obecny wersjonowany model zachowuje rozłączne domeny
GSObservedLink, table identity oraz requested/applied level i ma udokumentowany seam dla przyszłegoFlightTelemetry, bez pustych/fikcyjnych pól runtime. Testy pinują rozłączne zakresy, atomowe odrzucanie uszkodzonych rekordów i samonaprawę po heartbeat.Pełna walidacja końcowego drzewa przeszła:
go test ./...,go test -race ./..., vet, gofmt, oba buildy linux/arm64,git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 301completed / success.Pozostaje ponowna akceptacja na Orange Pi po instalacji obu binariów z tego headu: kursor ukryty od startu oraz widoczne OSD przed, podczas i po cyklu video.
It broke groundstation window. now cursor disappears if I set aux to >10 but window is not showing. it appears only if vtx is enabled. I want a gs window (fullscreen) always visible - even if vtx power aux <10. This should be main window that appears on orangepi start.
OSD still is not visible (tested when video was streamed)
Korekta diagnozy po live stacku
Wycofuję wcześniejsze stwierdzenie, że główną przyczyną jest zakopanie okien przez globalne hinty
BELOW/ABOVE. Wynik AUX OFF i ON falsyfikuje tę diagnozę jako przyczynę bieżącego objawu: obu okien Ground Station w ogóle nie ma w_NET_CLIENT_LIST_STACKINGaniwmctrl.Kod tworzy oba okna jako zarządzane
InputOutput, dzieci root window, bezoverride_redirect, i wykonujeMapWindow. Gdyby były tylko zasłonięte lub miały pusty Shape, nadal występowałyby na liście klientów. Ich brak oznacza, żegroundstation-displayich nie mapuje albo po nieudanymOpenniszczy połączenie/okna i pozostaje w pętli reconnect.Hipotezy do rozróżnienia:
Openobu warstw kończy się błędem X11 i reconnectem; log pokaże powtarzaneopen_failed/błąd zasobu lub autoryzacji, a pełne drzewo nie pokaże okien GS.Uruchom poniższy blok przy AUX OFF. Nie odczytuje
.Xauthorityani innych sekretów:Nie wykonuję kolejnej zmiany kodu przed wskazaniem dokładnego błędu
Openalbo potwierdzeniem, że okna są mapowane i znikają.jaki status?
Status:
296569232e3e300483955f29d36f69d0647506d4; CI run 301 jest zielone.wmctrli_NET_CLIENT_LIST_STACKING.Open/pętlę reconnect, niewłaściwe binarium albo bardzo krótkie mapowanie i niszczenie okien.Do wskazania dokładnego błędu brakuje wyniku drugiego, poprawionego bloku z komentarza
#1284: sekcjiPROCESS / REVISION,DISPLAY ERRORS THIS BOOToraz pełnegoxwininfo -root -tree. Pierwszy przesłany blok obejmował tylko zarządzane klienty i nie pokazuje błęduOpen.Po wklejeniu tego jednego wyniku rozstrzygnę, czy problemem jest
BadCursor/BadPixmap, Xauth/reconnect, deployment starego binarium czy krótkotrwałe niszczenie okien. Do tego czasu nie dokładam kolejnej spekulacyjnej poprawki.Poprawka potwierdzonego root cause jest gotowa w PR #15
Nowy head:
b7e054e94913abe16292cf9e08d848ccf46acdd9.Log Orange Pi wskazał dokładny łańcuch błędu: blank cursor tworzył source/mask pixmapy z głębokością root window
24, choć X11CreateCursorwymaga bitmap depth1. NiesprawdzonyCreateCursorkończył się błędem, niepoprawny cursor unieważniał niesprawdzonyCreateWindow, a dopiero kolejny sprawdzany Shape zgłaszał wtórnyBadWindow. Dlatego oba okna GS nie istniały i display pozostawał w reconnect loop.Naprawa:
CreateWindowz dokładnym wskazaniem błędu;Niezależny review i pełna walidacja przeszły: focused/race tests,
go test ./...,go test -race ./..., vet, gofmt, oba buildy linux/arm64,git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 309completed / success.Po instalacji obu binariów z tego headu oczekiwane jest zniknięcie pętli
empty shape region 2: BadWindow, obecność obu okien GS od startu oraz widoczne OSD niezależnie od AUX/video. Pozostaje świeża akceptacja na Orange Pi.Its better. Not there is a black fullscreen whole time and it switches to wfb stream if exists. But there are still no ODS data on top
Aktualny trace kodu wyklucza dwie hipotezy: template zawsze generuje
NO DATA/VIDEO OFF, a po rysowaniu nie ma czyszczenia tekstu. Pusty początkowy Shape nie powinien blokować całości, bo OSD ma niezależny refresh 1 Hz.Najbardziej prawdopodobny jest teraz konflikt warstwy xfwm4: kombinacja OSD
DOCK + FULLSCREEN + ABOVEmoże przypisać je do globalnej warstwy, w której sibling restack nie przechodzi nad canvas/video. Drugą możliwością jest to, że 1 Hz redraw nie rozszerza bounding Shape na urządzeniu.Uruchom blok dwa razy — AUX/video OFF, potem ON. W każdej próbie wykonuje dwie próbki Shape oddzielone 2 sekundami. Nie odczytuje sekretów:
Interpretacja:
Poprawka potwierdzonego braku OSD jest gotowa w PR #15
Nowy head:
5d067ee82d7c0446efdd1ae2cffa40e208ec2843.Live pomiar wykazał, że okno OSD było zmapowane i topmost zarówno bez video, jak i nad fullscreen streamem, ale jego bounding Shape pozostawał
0x0+0+0w dwóch próbkach oddzielonych ponad jednym okresem refresh. To wykluczyło stacking.Root cause: pętla X11 opróżniała kolejkę zdarzeń w nieograniczonym inner loop. Ciągły strumień non-Expose root events nie pozwalał wrócić do timera 1 Hz; jedyny redraw mogący rozszerzyć początkowo pusty Shape nigdy się nie wykonywał.
Naprawa ogranicza partię do 32 przetworzonych zdarzeń, po czym zawsze obsługuje refresh, liveness i cancellation. Żadne zdarzenia nie są odrzucane; canvas pozostaje event-driven; wejściowy Shape OSD pozostaje pusty, a bounding Shape jest aktualizowany przez template ops.
Niezależny review i pełna walidacja przeszły: storm regression tests, focused/race tests,
go test ./...,go test -race ./..., vet, gofmt, oba buildy linux/arm64,git diff --check, przegląd zakresu i skan bezpieczeństwa. CI dla dokładnego SHA: run 321completed / success.Po instalacji obu binariów z tego headu OSD powinno rozszerzyć Shape w pierwszym cyklu refresh i pokazać co najmniej
NO DATA/VIDEO OFF, a następnie aktualne lubDATA STALEwartości. Pozostaje świeża akceptacja na Orange Pi.