Merge pull request #2744 from myk002/myk_no_inception

Solve the inception problem: prevent screens (e.g. gui/launcher) from hanging when they attempt to dismiss and show themselves simultaneously
develop
Myk 2023-01-29 00:38:17 -08:00 committed by GitHub
commit f420b4b77e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 26 deletions

@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## New Plugins ## New Plugins
## Fixes ## Fixes
-@ ``Screen``: allow `gui/launcher` and `gui/quickcmd` to launch themselves without hanging the game
-@ Fix issues with clicks "passing through" some DFHack window elements, like scrollbars -@ Fix issues with clicks "passing through" some DFHack window elements, like scrollbars
## Misc Improvements ## Misc Improvements

@ -318,9 +318,10 @@ namespace DFHack
static const int RESTORE_AT_TOP = 0x1; static const int RESTORE_AT_TOP = 0x1;
private: private:
void extract(df::viewscreen*); void extract();
void merge(df::viewscreen*); void merge();
df::viewscreen* screen; df::viewscreen* screen;
df::viewscreen* prev_parent;
int flags; int flags;
}; };
} }

@ -527,43 +527,49 @@ void Screen::raise(df::viewscreen *screen) {
namespace DFHack { namespace Screen { namespace DFHack { namespace Screen {
Hide::Hide(df::viewscreen* screen, int flags) : Hide::Hide(df::viewscreen* screen, int flags) :
screen{screen}, flags{flags} screen{screen}, prev_parent{nullptr}, flags{flags} {
{ if (!screen)
extract(screen); return;
// don't extract a screen that's not even in the stack
if (screen->parent)
extract();
} }
Hide::~Hide() Hide::~Hide() {
{
if (screen) if (screen)
merge(screen); merge();
} }
void Hide::extract(df::viewscreen* a) void Hide::extract() {
{ prev_parent = screen->parent;
df::viewscreen* ap = a->parent; df::viewscreen *prev_child = screen->child;
df::viewscreen* ac = a->child;
ap->child = ac; screen->parent = nullptr;
if (ac) ac->parent = ap; screen->child = nullptr;
else Core::getInstance().top_viewscreen = ap;
prev_parent->child = prev_child;
if (prev_child) prev_child->parent = prev_parent;
else Core::getInstance().top_viewscreen = prev_parent;
} }
void Hide::merge(df::viewscreen* a) void Hide::merge() {
{ if (screen->parent) {
// we're somehow back on the stack; do nothing
return;
}
if (flags & RESTORE_AT_TOP) { if (flags & RESTORE_AT_TOP) {
a->parent = NULL; Screen::show(std::unique_ptr<df::viewscreen>(screen));
a->child = NULL;
Screen::show(std::unique_ptr<df::viewscreen>(a));
return; return;
} }
df::viewscreen* ap = a->parent; df::viewscreen* new_child = prev_parent->child;
df::viewscreen* ac = a->parent->child;
ap->child = a; prev_parent->child = screen;
a->child = ac; screen->child = new_child;
if (ac) ac->parent = a; if (new_child) new_child->parent = screen;
else Core::getInstance().top_viewscreen = a; else Core::getInstance().top_viewscreen = screen;
} }
} } } }