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
develop
lethosor 2021-03-21 20:42:50 -04:00
parent e7cf5e2079
commit 59b023c71d
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
4 changed files with 21 additions and 8 deletions

@ -33,6 +33,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future # 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 ## Documentation
- Added more client library implementations to the `remote interface docs <remote-client-libs>` - Added more client library implementations to the `remote interface docs <remote-client-libs>`

@ -308,12 +308,15 @@ namespace DFHack
//! Temporary hide a screen until destructor is called //! Temporary hide a screen until destructor is called
struct DFHACK_EXPORT Hide { struct DFHACK_EXPORT Hide {
Hide(df::viewscreen* screen); Hide(df::viewscreen* screen, int flags = 0);
~Hide(); ~Hide();
static const int RESTORE_AT_TOP = 0x1;
private: private:
void extract(df::viewscreen*); void extract(df::viewscreen*);
void merge(df::viewscreen*); void merge(df::viewscreen*);
df::viewscreen* screen_; df::viewscreen* screen;
int flags;
}; };
} }

@ -378,16 +378,16 @@ bool Screen::hasActiveScreens(Plugin *plugin)
namespace DFHack { namespace Screen { namespace DFHack { namespace Screen {
Hide::Hide(df::viewscreen* screen) : Hide::Hide(df::viewscreen* screen, int flags) :
screen_{screen} screen{screen}, flags{flags}
{ {
extract(screen_); extract(screen);
} }
Hide::~Hide() Hide::~Hide()
{ {
if (screen_) if (screen)
merge(screen_); merge(screen);
} }
void Hide::extract(df::viewscreen* a) void Hide::extract(df::viewscreen* a)
@ -402,6 +402,13 @@ void Hide::extract(df::viewscreen* a)
void Hide::merge(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<df::viewscreen>(a));
return;
}
df::viewscreen* ap = a->parent; df::viewscreen* ap = a->parent;
df::viewscreen* ac = a->parent->child; df::viewscreen* ac = a->parent->child;

@ -201,7 +201,7 @@ void viewscreen_commandpromptst::submit()
submitted = true; submitted = true;
prompt_ostream out(this); 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()); Core::getInstance().runCommand(out, get_entry());
} }
if(out.empty() && responses.empty()) if(out.empty() && responses.empty())