From 1ffacae2fb203a35003670b7d2c3685ec965d855 Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Tue, 18 Aug 2026 21:57:47 +0200 Subject: [PATCH] put the modal up in the same frame as the dim behind it The layer was shown and painted before the modal it hosts was placed, so opening one -- the layout dialog from the shipyard panel, say -- painted a frame of bare dim over the world before the dialog appeared, which reads as a black flash. The modal is now placed and shown while the layer is still hidden, and showing the layer paints both at once. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x --- src/ui/ModalLayer.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ui/ModalLayer.cpp b/src/ui/ModalLayer.cpp index 1c0feea..c5a526b 100644 --- a/src/ui/ModalLayer.cpp +++ b/src/ui/ModalLayer.cpp @@ -53,11 +53,18 @@ int ModalLayer::execute(ModalDialog& content, const QRect& anchorRect) : m_stack.back().host->geometry()); m_stack.push_back(HostedModal{ &content, host }); - updateVisibility(); + + // Placed and shown before the layer itself is, so that the frame the layer first + // paints already carries the modal. Showing the layer first put the dim on screen a + // frame before anything stood on it, which read as a black flash + // (REQ-UI-MODAL-DIM). Placing works while the layer is hidden: its geometry is the + // window's whether or not it is shown, and a child shown under a hidden parent + // appears with it. raise(); place(*host, content, anchor); host->show(); content.show(); + updateVisibility(); // The modal's own focus widget where it has one -- a name dialog puts the caret in // its line edit -- and the modal itself otherwise, so keys reach it and not the game @@ -209,8 +216,9 @@ void ModalLayer::updateVisibility() { raise(); show(); - // Force an immediate synchronous paint so the dim is up before whatever the - // caller does next; no undimmed frame flashes through. + // Painted at once rather than at the next paint event, so no undimmed frame of + // the world flashes through in between. The modal standing on the layer is + // already placed and shown by now, so this one paint puts up both (execute()). repaint(); } else