mirror of
https://github.com/screentinker/screentinker.git
synced 2026-06-29 09:23:16 -06:00
fix(#109): image PiPs never painted — set slot token before decode
Emulator e2e of an image PiP (a QR PNG) found the image area always blank (box background + title only). Pre-existing defect, also on main, independent of the occlusion reparent. Root cause in PipOverlay.show(): teardown() clears `current` to null, then loadImageInto() captured `token = current` (null) as its drop-if-replaced guard, but `current` was set to the new pip_id AFTER the media was built. The image decode finishes on a background thread and posts back after show() returns, so `token != current` (null != pip_id) was always true and every decoded bitmap was dropped. Web PiPs and the box/title were unaffected, which masked it. Fix: set `current = pip_id` before building media so loadImageInto's token matches. Verified on emulator — a QR image PiP now renders over both a static image and live YouTube (hardware screencap + the app's software view.draw capture both show it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ce7b2948ae
commit
4528d07c53
|
|
@ -68,6 +68,13 @@ class PipOverlay(
|
|||
val w = p.optInt("width", 480).coerceIn(1, dm.widthPixels * 4)
|
||||
val h = p.optInt("height", 360).coerceIn(1, dm.heightPixels * 4)
|
||||
|
||||
// Set the slot token BEFORE building media: loadImageInto captures `current` as
|
||||
// its drop-if-replaced token, and its decode finishes on a background thread that
|
||||
// posts back AFTER show() returns. If current were still null here (teardown
|
||||
// clears it), that guard would always fail and the decoded bitmap would be
|
||||
// dropped — i.e. image PiPs never painted. (#109 follow-up.)
|
||||
current = p.optString("pip_id", "(anon)")
|
||||
|
||||
val box = LinearLayout(context).apply {
|
||||
orientation = LinearLayout.VERTICAL
|
||||
clipToOutline = true
|
||||
|
|
@ -129,7 +136,7 @@ class PipOverlay(
|
|||
|
||||
pipLayout.addView(box, lp)
|
||||
pipLayout.visibility = View.VISIBLE
|
||||
current = p.optString("pip_id", "(anon)")
|
||||
// current was set above (before media build) so loadImageInto's token matches.
|
||||
|
||||
// #109 fix (1)/(3): the pip layer is a top-level view above the WebView (reparented
|
||||
// to the window content in MainActivity), but make sure it composites last and is
|
||||
|
|
|
|||
|
|
@ -137,6 +137,22 @@ reproduce the Fire TV / Android TV hardware-overlay punch-through that is the
|
|||
strongest form of cause (1). That still needs the real signage device — use the
|
||||
`pipDebug` magenta box there to confirm.
|
||||
|
||||
### Follow-up bug found in emulator testing: image PiPs never painted the image
|
||||
|
||||
Verifying an **image** PiP (a QR PNG) surfaced a separate, pre-existing defect
|
||||
(present on `main`, unrelated to the occlusion reparent): the image area was
|
||||
always blank — only the box background + title showed. Root cause in
|
||||
`PipOverlay.show()`: `teardown()` clears `current` to null, then `loadImageInto`
|
||||
captured `token = current` (null) as its drop-if-replaced guard, but `current`
|
||||
was only set to the new `pip_id` *after* the media was built. The decode finishes
|
||||
on a background thread and posts back **after** `show()` returns — so the guard
|
||||
`token != current` (null ≠ pip_id) was always true and **every decoded bitmap was
|
||||
dropped**. (Web PiPs and the box/title were unaffected, which masked it.)
|
||||
|
||||
Fix: set `current = pip_id` **before** building the media (so `loadImageInto`'s
|
||||
token matches). Confirmed on the emulator — the QR now renders in the PiP box
|
||||
over both a static image and live YouTube.
|
||||
|
||||
## If the magenta box is STILL hidden over YouTube on the test device
|
||||
|
||||
Then it is the stronger form of cause (1): the WebView places its video on a
|
||||
|
|
|
|||
Loading…
Reference in a new issue