From 9b6781f0f284a40b14cf5a6cd4173fa6dd021f68 Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 20 Jun 2018 20:08:35 +0300 Subject: [PATCH] Temporary lower command-prompt when executing the command command-prompt viewscreen may affect command execution if they are looking for UI state. To make commands execute simillary to hotkeys or console commands the viewscreen needs to removed from the top position. Fixes #1194 --- library/include/Core.h | 6 ++++++ library/include/modules/Screen.h | 10 +++++++++ library/modules/Screen.cpp | 36 ++++++++++++++++++++++++++++++++ plugins/command-prompt.cpp | 5 ++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/library/include/Core.h b/library/include/Core.h index fa65645a1..2c55f8b3a 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -70,6 +70,11 @@ namespace DFHack class df_window; } + namespace Screen + { + struct Hide; + } + enum state_change_event { SC_UNKNOWN = -1, @@ -273,6 +278,7 @@ namespace DFHack void *last_world_data_ptr; // for state change tracking void *last_local_map_ptr; + friend struct Screen::Hide; df::viewscreen *top_viewscreen; bool last_pause_state; // Very important! diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 673533f3e..76a331eb6 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -301,6 +301,15 @@ namespace DFHack GUI_HOOK_DECLARE(set_tile, bool, (const Pen &pen, int x, int y, bool map)); } + //! Temporary hide a screen until destructor is called + struct DFHACK_EXPORT Hide { + Hide(df::viewscreen* screen); + ~Hide(); + private: + void extract(df::viewscreen*); + void merge(df::viewscreen*); + df::viewscreen* screen_; + }; } class DFHACK_EXPORT dfhack_viewscreen : public df::viewscreen { @@ -374,4 +383,5 @@ namespace DFHack virtual df::building *getSelectedBuilding(); virtual df::plant *getSelectedPlant(); }; + } diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 6ac39aa05..ee68a0fe5 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -371,6 +371,42 @@ bool Screen::hasActiveScreens(Plugin *plugin) return false; } +namespace DFHack { namespace Screen { + +Hide::Hide(df::viewscreen* screen) : + screen_{screen} +{ + extract(screen_); +} + +Hide::~Hide() +{ + if (screen_) + merge(screen_); +} + +void Hide::extract(df::viewscreen* a) +{ + df::viewscreen* ap = a->parent; + df::viewscreen* ac = a->child; + + ap->child = ac; + if (ac) ac->parent = ap; + else Core::getInstance().top_viewscreen = ap; +} + +void Hide::merge(df::viewscreen* a) +{ + df::viewscreen* ap = a->parent; + df::viewscreen* ac = a->parent->child; + + ap->child = a; + a->child = ac; + if (ac) ac->parent = a; + else Core::getInstance().top_viewscreen = a; +} +} } + #ifdef _LINUX class DFHACK_EXPORT renderer { unsigned char *screen; diff --git a/plugins/command-prompt.cpp b/plugins/command-prompt.cpp index 449da0e80..c53132486 100644 --- a/plugins/command-prompt.cpp +++ b/plugins/command-prompt.cpp @@ -200,7 +200,10 @@ void viewscreen_commandpromptst::submit() return; submitted = true; prompt_ostream out(this); - Core::getInstance().runCommand(out, get_entry()); + { + Screen::Hide hide_guard(this); + Core::getInstance().runCommand(out, get_entry()); + } if(out.empty() && responses.empty()) Screen::dismiss(this); else