Design: the status chip goes away with the window, not just with the page

Found by minimising the app on the rig with a face selected: the whole screen goes
black and the chip is still drawn on the bare desktop. A wxPopupWindow is
override-redirect — the window manager does not own it — so it neither iconises with
its frame nor stacks behind other applications. IsShownOnScreen does not catch this
either: an iconised frame still counts as shown, which is why the guard added for the
tab case sails straight past it.

So the frame has to say so itself: ICONIZE and ACTIVATE, both routed through the same
show_status_hud the page change already uses. Restoring is safe — a popup cannot take
focus, so our own Show() cannot re-trigger either event — and restoring while some
other page is up still leaves the chip down, because show_status_hud(true) goes
through place_status_hud's IsShownOnScreen guard.

Verified on both rigs: chip up, minimise -> screen black and empty, restore -> chip
back with its text and the face still selected. Restore while on Prepare -> chip stays
down.

This is the fourth defect from the same root, so snaporca-lcq now asks the question
these binds keep deferring: whether the line should be canvas content, like the view
cube and the round view buttons, rather than a window that has to be told about every
way a window can stop being visible.

Fork parity unchanged: DesignCanvas.cpp 16.
This commit is contained in:
Tommaso Bianchi
2026-08-03 13:36:09 +02:00
parent 9c3ce9b45e
commit 6d1a4078ca
+16
View File
@@ -161,6 +161,22 @@ DesignCanvas::DesignCanvas(wxWindow* parent)
// the canvas changes size. The readout HUD gets away without this because it is transient;
// the status line is on screen almost permanently and would visibly detach.
m_canvas_widget->Bind(wxEVT_SIZE, [this](wxSizeEvent& e) { place_status_hud(); e.Skip(); });
// ...and it does not follow the WINDOW either. A popup is override-redirect: the window
// manager does not own it, so minimising the app leaves the chip sitting on the bare desktop
// (seen on the rig: whole screen black, chip still there), and it stacks above other
// applications rather than behind them. IsShownOnScreen does not catch this — an iconised
// frame still counts as shown — so the frame has to say so itself. Deactivating the app is
// the same case one step weaker: the chip belongs to a viewport the user is no longer
// looking at. Showing it back is safe because a popup cannot take focus, so neither event
// can be re-triggered by our own Show().
if (wxWindow* top = wxGetTopLevelParent(m_canvas_widget)) {
top->Bind(wxEVT_ICONIZE, [this](wxIconizeEvent& e) {
show_status_hud(!e.IsIconized()); e.Skip();
});
top->Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& e) {
show_status_hud(e.GetActive()); e.Skip();
});
}
refresh_bed();