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
## 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
## Misc Improvements

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

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