ensure DF screens don't get "stuck" when DFHack tool windows are on top

develop
Myk Taylor 2023-01-28 08:05:37 -08:00
parent 277a37a12f
commit f12ca33c0b
No known key found for this signature in database
2 changed files with 37 additions and 4 deletions

@ -706,7 +706,7 @@ ZScreen.ATTRS{
function ZScreen:init()
self.saved_pause_state = df.global.pause_state
if self.initial_pause then
if self.initial_pause and dfhack.isMapLoaded() then
df.global.pause_state = true
end
self.defocused = false
@ -714,19 +714,30 @@ end
function ZScreen:dismiss()
ZScreen.super.dismiss(self)
if self.force_pause or self.initial_pause then
if (self.force_pause or self.initial_pause) and dfhack.isMapLoaded() then
-- never go from unpaused to paused, just from paused to unpaused
df.global.pause_state = df.global.pause_state and self.saved_pause_state
end
end
local NO_LOGIC_SCREENS = utils.invert{
'viewscreen_loadgamest',
'viewscreen_export_regionst',
'viewscreen_choose_game_typest',
}
-- this is necessary for middle-click map scrolling to function
function ZScreen:onIdle()
if self.force_pause then
if self.force_pause and dfhack.isMapLoaded() then
df.global.pause_state = true
end
if self._native and self._native.parent then
self._native.parent:logic()
local vs_name = getmetatable(dfhack.gui.getDFViewscreen(true))
if NO_LOGIC_SCREENS[vs_name] then
self.force_pause = true
else
self._native.parent:logic()
end
end
end

@ -710,6 +710,21 @@ void dfhack_viewscreen::logic()
// Various stuff works poorly unless always repainting
Screen::invalidate();
// if the DF screen immediately beneath the DFHack viewscreens is waiting to
// be dismissed, raise it to the top so DF never gets stuck
auto *p = parent;
while (p) {
bool is_df_screen = !is_instance(p);
auto *next_p = p->parent;
if (is_df_screen && Screen::isDismissed(p)) {
DEBUG(screen).print("raising dismissed DF viewscreen %p\n", p);
Screen::raise(p);
}
if (is_df_screen)
break;
p = next_p;
}
}
void dfhack_viewscreen::render()
@ -800,6 +815,13 @@ int dfhack_lua_viewscreen::do_destroy(lua_State *L)
auto self = get_self(L);
if (!self) return 0;
if (!Screen::isDismissed(self)) {
WARNING(screen).print("DFHack screen was destroyed before it was dismissed\n");
WARNING(screen).print("Please tell the DFHack team which DF screen you were just viewing\n");
// run skipped onDismiss cleanup logic
Screen::dismiss(self);
}
lua_pushnil(L);
lua_rawsetp(L, LUA_REGISTRYINDEX, self);