Closed bug report

desktop_demo_panel hide leaves the panel painted on screen (poll says stopped)

John Lauer · 2mo ago ·closed by John Lauer

Adom Bridge 2.1.33 on ConfRoomROG (also seen on AdomLapper 2.1.27, 2026-09-04: the Fusion tour's remote stayed on John's screen for nine minutes after the tour ended). Steps: show the panel (id fusion-tour), advance stages, then {action:"hide", id:"fusion-tour"} -> reply {hidden:true, success:true}; a following {action:"poll"} reports state "stopped". But the glass panel stays painted at its last stage (a full-screen capture 1 s after hide still shows 'Fusion bridge tour 8/8 - Cloud search over your hub' bottom-right; after a further hide it repainted to the last stage rather than vanishing). The ab process's main window title is 'Adom demo panel'. Expected: the overlay window is gone after hide (SW_HIDE, or destroy it as the idle_hide path does). The fusion bridge's tour hides, polls, retries and records 'panelHidden: stateAfter stopped', so the bridge side believes it is hidden while the user still sees it. Repro on any box: adom-bridge desktop_demo_panel '{"action":"show","id":"t","title":"T","stops":["a","b"],"stage":0,"reason":"repro of hide"}' then '{"action":"hide","id":"t"}' and take desktop_screenshot_screen.

2 Replies

John Lauer · 2mo ago

Reproduced your exact steps on AdomLapper at 2.1.37 and the panel DID vanish here, which points at a race rather than a dead hide: set visible=false and called ShowWindow(SW_HIDE) from the verb thread, but render() (called by WM_PAINT, the idle timer, and every show/update from the tour) never looked at - it always pushed a fresh layered bitmap with UpdateLayeredWindow, and a late paint or a stage update landing after the hide re-presented the window at its last stage. That matches 'after a further hide it repainted to the last stage' precisely: the second hide raced another paint.

Fix in ab 2.1.38 (insiders shortly): (1) render() returns early and hides when the panel is not visible, so nothing can paint it back; (2) hide also posts a hide request to the panel's OWN window thread, so it runs behind anything already queued there; (3) the hide reply no longer assumes - it polls IsWindowVisible on the panel window for up to 500 ms and answers hidden:true only when Windows agrees (verified:true), with SWP_HIDEWINDOW as the last resort and an explicit hint if the window still reports visible. Your bridge's 'hide, poll, retry' loop can key off from this version on.

John Lauer · 2mo ago

Shipped in ab 2.1.38 (insiders) and verified on AdomLapper under the race that reproduces your report: show the panel, fire a stage update and a hide at the same moment -> hide replied {hidden:true, verified:true}, a full-screen capture 1.5 s later shows no panel, poll reports stopped. The three changes: render() returns early and hides when the panel is not visible (nothing can paint it back), hide also runs on the panel's own window thread behind any queued paint, and the reply verifies with IsWindowVisible (SWP_HIDEWINDOW as the last resort, with an explicit hint if Windows still reports it visible). Your tour can trust hidden from this version on. Closing.

John Lauer closed this · 2mo ago

Log in to reply.