diff --git a/Common/UI/ScreenManager.cpp b/Common/UI/ScreenManager.cpp index 7f63bb7a91..3987a7594d 100644 --- a/Common/UI/ScreenManager.cpp +++ b/Common/UI/ScreenManager.cpp @@ -393,6 +393,15 @@ void ScreenManager::finishDialog(Screen *dialog, DialogResult result) { dialogResult_ = result; } +bool ScreenManager::HasScreenAbove(const Screen *screen) const { + for (size_t i = 0; i + 1 < stack_.size(); ++i) { + if (stack_[i].screen == screen) { + return true; + } + } + return false; +} + Screen *ScreenManager::dialogParent(const Screen *dialog) const { for (size_t i = 1; i < stack_.size(); ++i) { if (stack_[i].screen == dialog) { diff --git a/Common/UI/ScreenManager.h b/Common/UI/ScreenManager.h index bd02dce94b..e815c834c1 100644 --- a/Common/UI/ScreenManager.h +++ b/Common/UI/ScreenManager.h @@ -64,6 +64,8 @@ public: // Pops the dialog away. void finishDialog(Screen *dialog, DialogResult result = DR_OK); Screen *dialogParent(const Screen *dialog) const; + // True if the screen is in the stack, with something (like a popup) on top of it. + bool HasScreenAbove(const Screen *screen) const; void sendMessage(UIMessage message, const char *value); diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index d29d2dead9..bf77236647 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -128,7 +128,11 @@ Bounds UIScreen::GetLayoutBounds(UIContext &dc) const { } ScreenRenderFlags UIScreen::render(ScreenRenderMode mode) { - DoRecreateViews(); + // A screen rendered under a popup must keep its views: the popup's callbacks point into them (the choice + // that opened it, the value it writes to). update() recreates them once the screen is on top again. + if (!root_ || !screenManager()->HasScreenAbove(this)) { + DoRecreateViews(); + } UIContext &uiContext = *screenManager()->getUIContext(); if (root_) {