fix(material): make blur-overlay effect guard truly close-equivalent
The adversarial review found the ModalRenderGuard lagged the old PortfolioEditorActive() signal by one extra frame on CLOSE (a possible 1-frame "opaque panels" flash). Latch the overlay's open flag (already available via spec.p_open) — "drew this frame AND still open after Esc/Close/outside handling" — instead of just "drew last frame", so the guard drops and the acrylic re-capture fire on the same frame the overlay closes, matching the old inline behavior on both edges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1039,18 +1039,25 @@ inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col
|
||||
// "A blur overlay was drawn this frame" flag + a 1-frame latch. App::render builds its
|
||||
// effect-suppression guard at the TOP of the frame, before dialogs dispatch, so it reads the
|
||||
// LAST-frame latch (a stable signal) rather than this frame's in-progress state.
|
||||
inline bool& BlurOverlayDrawnThisFrameRef() { static bool v = false; return v; }
|
||||
inline bool& BlurOverlayActiveLastFrameRef() { static bool v = false; return v; }
|
||||
inline void MarkBlurOverlayDrawn() { BlurOverlayDrawnThisFrameRef() = true; }
|
||||
inline bool& BlurOverlayDrawnThisFrameRef() { static bool v = false; return v; }
|
||||
inline bool& BlurOverlayActiveLastFrameRef() { static bool v = false; return v; }
|
||||
inline bool*& BlurOverlayOpenFlagRef() { static bool* p = nullptr; return p; }
|
||||
// Record that a blur overlay drew this frame, along with its open flag (so the latch below can tell
|
||||
// "still open next frame" from "closed this frame" and match the modal's actual open state — no
|
||||
// extra frame of suppression on close).
|
||||
inline void MarkBlurOverlayDrawn(bool* openFlag) { BlurOverlayDrawnThisFrameRef() = true; BlurOverlayOpenFlagRef() = openFlag; }
|
||||
inline bool AnyBlurOverlayActiveLastFrame() { return BlurOverlayActiveLastFrameRef(); }
|
||||
// Latch this frame's state for the next frame's guard; on the open->closed transition, invalidate
|
||||
// the acrylic capture so the other glass panels re-capture the (overlay-free) background. Call once
|
||||
// at the end of App::render.
|
||||
// Latch whether an overlay will still be up next frame (drew this frame AND its open flag is still
|
||||
// set after this frame's Esc/Close/outside-click handling); on the open->closed transition,
|
||||
// invalidate the acrylic capture so the other glass panels re-capture the (overlay-free)
|
||||
// background. Call once at the end of App::render.
|
||||
inline void LatchBlurOverlayActive() {
|
||||
bool now = BlurOverlayDrawnThisFrameRef();
|
||||
if (BlurOverlayActiveLastFrameRef() && !now) effects::ImGuiAcrylic::InvalidateCapture();
|
||||
BlurOverlayActiveLastFrameRef() = now;
|
||||
bool* pf = BlurOverlayOpenFlagRef();
|
||||
bool stillOpen = BlurOverlayDrawnThisFrameRef() && (!pf || *pf);
|
||||
if (BlurOverlayActiveLastFrameRef() && !stillOpen) effects::ImGuiAcrylic::InvalidateCapture();
|
||||
BlurOverlayActiveLastFrameRef() = stillOpen;
|
||||
BlurOverlayDrawnThisFrameRef() = false;
|
||||
BlurOverlayOpenFlagRef() = nullptr;
|
||||
}
|
||||
|
||||
// True during the frames a blur overlay is (re)capturing the live backdrop — the scroll-fade shader
|
||||
@@ -1197,7 +1204,7 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
|
||||
// few frames on open/resize, then reuse the frozen blurred snapshot. Low-spec / acrylic-off falls
|
||||
// back to an opaque base inside DrawFullWindowBlurBackdrop (no blur cost).
|
||||
if (blur) {
|
||||
MarkBlurOverlayDrawn();
|
||||
MarkBlurOverlayDrawn(spec.p_open);
|
||||
BlurCaptureState& st = BlurCaptureStateFor(scrimId);
|
||||
int frame = ImGui::GetFrameCount();
|
||||
bool justOpened = (st.lastSeenFrame < frame - 1);
|
||||
|
||||
Reference in New Issue
Block a user