From b0ded528b161066a4aec8c6a80695a1ad0c3cc60 Mon Sep 17 00:00:00 2001 From: DanS Date: Fri, 3 Jul 2026 01:02:18 -0500 Subject: [PATCH] fix(dialogs): let Combo dropdowns / popups work inside overlay dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BeginOverlayDialog called ImGui::SetNextWindowFocus() every frame to keep the dialog on top. That forced the scrim back to the front each frame and closed any popup opened from inside the dialog — so the portfolio editor's price-basis Combo and the custom color-picker popup flashed open then vanished, and clicking a dropdown item that overhung the card could trip the outside-click-dismiss and close the whole dialog. Make the overlay popup-aware: compute overlayPopupOpen (IsPopupOpen with AnyPopupId|AnyPopupLevel) and (1) skip SetNextWindowFocus while a popup is showing so it stays focused/on-top, and (2) skip the outside-click-dismiss while a popup is open so clicks inside it don't close the dialog. No change when no popup is open, so existing dialogs are unaffected. Full-node + Lite build clean; ctest 1/1; hygiene clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/material/draw_helpers.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ui/material/draw_helpers.h b/src/ui/material/draw_helpers.h index 56410ad..db65d38 100644 --- a/src/ui/material/draw_helpers.h +++ b/src/ui/material/draw_helpers.h @@ -1026,7 +1026,12 @@ inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth // Fullscreen scrim overlay ImGui::SetNextWindowPos(vp_pos); ImGui::SetNextWindowSize(vp_size); - ImGui::SetNextWindowFocus(); + // Focus the scrim so the dialog owns input — but NOT while a popup (a Combo dropdown, + // color picker, etc.) opened from the dialog is showing, or forcing focus back to the + // scrim every frame would immediately close that popup. + const bool overlayPopupOpen = + ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel); + if (!overlayPopupOpen) ImGui::SetNextWindowFocus(); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.04f, 0.04f, 0.06f, scrimOpacity)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); @@ -1094,8 +1099,11 @@ inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth // Click outside the card dismisses the dialog — but NOT on the frame it first appears, otherwise // the very click that opened it (a button fired the same frame) is read as an outside-click and - // the dialog flashes open then instantly closes. - if (p_open && !ImGui::IsWindowAppearing() && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && + // the dialog flashes open then instantly closes. Also skip while a popup opened from the dialog + // is showing: a click inside a Combo dropdown / color picker that overhangs the card would + // otherwise be read as an outside-click and close the whole dialog. + if (p_open && !overlayPopupOpen && !ImGui::IsWindowAppearing() && + ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseHoveringRect(cardMin, cardMax, false)) { *p_open = false; }