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
|
// "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
|
// 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.
|
// 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& BlurOverlayDrawnThisFrameRef() { static bool v = false; return v; }
|
||||||
inline bool& BlurOverlayActiveLastFrameRef() { static bool v = false; return v; }
|
inline bool& BlurOverlayActiveLastFrameRef() { static bool v = false; return v; }
|
||||||
inline void MarkBlurOverlayDrawn() { BlurOverlayDrawnThisFrameRef() = true; }
|
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(); }
|
inline bool AnyBlurOverlayActiveLastFrame() { return BlurOverlayActiveLastFrameRef(); }
|
||||||
// Latch this frame's state for the next frame's guard; on the open->closed transition, invalidate
|
// Latch whether an overlay will still be up next frame (drew this frame AND its open flag is still
|
||||||
// the acrylic capture so the other glass panels re-capture the (overlay-free) background. Call once
|
// set after this frame's Esc/Close/outside-click handling); on the open->closed transition,
|
||||||
// at the end of App::render.
|
// 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() {
|
inline void LatchBlurOverlayActive() {
|
||||||
bool now = BlurOverlayDrawnThisFrameRef();
|
bool* pf = BlurOverlayOpenFlagRef();
|
||||||
if (BlurOverlayActiveLastFrameRef() && !now) effects::ImGuiAcrylic::InvalidateCapture();
|
bool stillOpen = BlurOverlayDrawnThisFrameRef() && (!pf || *pf);
|
||||||
BlurOverlayActiveLastFrameRef() = now;
|
if (BlurOverlayActiveLastFrameRef() && !stillOpen) effects::ImGuiAcrylic::InvalidateCapture();
|
||||||
|
BlurOverlayActiveLastFrameRef() = stillOpen;
|
||||||
BlurOverlayDrawnThisFrameRef() = false;
|
BlurOverlayDrawnThisFrameRef() = false;
|
||||||
|
BlurOverlayOpenFlagRef() = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// True during the frames a blur overlay is (re)capturing the live backdrop — the scroll-fade shader
|
// 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
|
// 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).
|
// back to an opaque base inside DrawFullWindowBlurBackdrop (no blur cost).
|
||||||
if (blur) {
|
if (blur) {
|
||||||
MarkBlurOverlayDrawn();
|
MarkBlurOverlayDrawn(spec.p_open);
|
||||||
BlurCaptureState& st = BlurCaptureStateFor(scrimId);
|
BlurCaptureState& st = BlurCaptureStateFor(scrimId);
|
||||||
int frame = ImGui::GetFrameCount();
|
int frame = ImGui::GetFrameCount();
|
||||||
bool justOpened = (st.lastSeenFrame < frame - 1);
|
bool justOpened = (st.lastSeenFrame < frame - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user