From 59b023c71d3f275becc5ae47280666c8053c37de Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 21 Mar 2021 20:42:50 -0400 Subject: [PATCH] Ensure that command-prompt is dismissed after a command creates a new screen Fixes #1803 Running a command that created a new screen would previously result in a screen order that looked like this, due to how `Screen::Hide` works: - DF screen - `command-prompt` screen (dismissed) - New screen The `command-prompt` screen remained on the stack until the new screen was dismissed, so it would intercept viewscreen vmethod calls intended for the DF screen. This change adds a new behavior to `Screen::Hide` that results in this screen order after running a command: - DF screen - New screen - `command-prompt` screen (dismissed) - DF removes this screen immediately --- docs/changelog.txt | 3 +++ library/include/modules/Screen.h | 7 +++++-- library/modules/Screen.cpp | 17 ++++++++++++----- plugins/command-prompt.cpp | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index ee509e9df..cb57be30d 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -33,6 +33,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future +## Fixes +- `command-prompt`: fixed issues where overlays created by running certain commands (e.g. `gui/liquids`, `gui/teleport`) would not update the parent screen correctly + ## Documentation - Added more client library implementations to the `remote interface docs ` diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 68c505670..a91de875c 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -308,12 +308,15 @@ namespace DFHack //! Temporary hide a screen until destructor is called struct DFHACK_EXPORT Hide { - Hide(df::viewscreen* screen); + Hide(df::viewscreen* screen, int flags = 0); ~Hide(); + + static const int RESTORE_AT_TOP = 0x1; private: void extract(df::viewscreen*); void merge(df::viewscreen*); - df::viewscreen* screen_; + df::viewscreen* screen; + int flags; }; } diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index d119fa2f8..5001a34c0 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -378,16 +378,16 @@ bool Screen::hasActiveScreens(Plugin *plugin) namespace DFHack { namespace Screen { -Hide::Hide(df::viewscreen* screen) : - screen_{screen} +Hide::Hide(df::viewscreen* screen, int flags) : + screen{screen}, flags{flags} { - extract(screen_); + extract(screen); } Hide::~Hide() { - if (screen_) - merge(screen_); + if (screen) + merge(screen); } void Hide::extract(df::viewscreen* a) @@ -402,6 +402,13 @@ void Hide::extract(df::viewscreen* a) void Hide::merge(df::viewscreen* a) { + if (flags & RESTORE_AT_TOP) { + a->parent = NULL; + a->child = NULL; + Screen::show(std::unique_ptr(a)); + return; + } + df::viewscreen* ap = a->parent; df::viewscreen* ac = a->parent->child; diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 1c68a8fbb..a987ea829 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -201,7 +201,7 @@ void viewscreen_commandpromptst::submit() submitted = true; prompt_ostream out(this); { - Screen::Hide hide_guard(this); + Screen::Hide hide_guard(this, Screen::Hide::RESTORE_AT_TOP); Core::getInstance().runCommand(out, get_entry()); } if(out.empty() && responses.empty())