From f12ca33c0b801f095f9ca9e7f6d7755e60dbe3c5 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 28 Jan 2023 08:05:37 -0800 Subject: [PATCH 1/5] ensure DF screens don't get "stuck" when DFHack tool windows are on top --- library/lua/gui.lua | 19 +++++++++++++++---- library/modules/Screen.cpp | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/library/lua/gui.lua b/library/lua/gui.lua index d870399a3..cf25b50cf 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -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 diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 3ece27b78..00a98e489 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -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); From 65aa772a5b82eb6086d5b6e389f64e6f1dbcb830 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 28 Jan 2023 08:07:29 -0800 Subject: [PATCH 2/5] update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 8d84e3cff..d10787f13 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## New Plugins ## Fixes +-@ Ensure DF windows don't get "stuck" on transitions when DFHack tool windows are visible. Instead, those DF screens are force-paused while DFHack windows are visible so the player can close them first and not corrupt the screen sequence. The "force pause" indicator will appear on these DFHack windows to indicate what is happening. - Fix issues with clicks "passing through" some DFHack window elements, like scrollbars ## Misc Improvements From a931ca692da906f9f25a365af0602239aa88ddfb Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 28 Jan 2023 08:20:55 -0800 Subject: [PATCH 3/5] Fix debug level typo --- library/modules/Screen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 00a98e489..7a5cbd161 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -816,8 +816,8 @@ int dfhack_lua_viewscreen::do_destroy(lua_State *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"); + WARN(screen).print("DFHack screen was destroyed before it was dismissed\n"); + WARN(screen).print("Please tell the DFHack team which DF screen you were just viewing\n"); // run skipped onDismiss cleanup logic Screen::dismiss(self); } From 114bc2a576bc5d32be0ab4381689a0de667c29c9 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 28 Jan 2023 08:57:24 -0800 Subject: [PATCH 4/5] also lock down the world map --- library/lua/gui.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/lua/gui.lua b/library/lua/gui.lua index cf25b50cf..339894f2f 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -724,6 +724,7 @@ local NO_LOGIC_SCREENS = utils.invert{ 'viewscreen_loadgamest', 'viewscreen_export_regionst', 'viewscreen_choose_game_typest', + 'viewscreen_worldst', } -- this is necessary for middle-click map scrolling to function @@ -735,6 +736,8 @@ function ZScreen:onIdle() local vs_name = getmetatable(dfhack.gui.getDFViewscreen(true)) if NO_LOGIC_SCREENS[vs_name] then self.force_pause = true + self.pass_movement_keys = false + self.pass_mouse_clicks = false else self._native.parent:logic() end From 211d18717ce07401adfe97ab298a68089b530e2a Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 28 Jan 2023 23:34:23 -0800 Subject: [PATCH 5/5] test against type instead of string --- library/lua/gui.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/library/lua/gui.lua b/library/lua/gui.lua index c44acee9e..6630f9cba 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -720,12 +720,18 @@ function ZScreen:dismiss() end end -local NO_LOGIC_SCREENS = utils.invert{ +local NO_LOGIC_SCREENS = { 'viewscreen_loadgamest', 'viewscreen_export_regionst', 'viewscreen_choose_game_typest', 'viewscreen_worldst', } +for _,v in ipairs(NO_LOGIC_SCREENS) do + if not df[v] then + error('invalid class name: ' .. v) + end + NO_LOGIC_SCREENS[df[v]] = true +end -- this is necessary for middle-click map scrolling to function function ZScreen:onIdle() @@ -733,8 +739,8 @@ function ZScreen:onIdle() df.global.pause_state = true end if self._native and self._native.parent then - local vs_name = getmetatable(dfhack.gui.getDFViewscreen(true)) - if NO_LOGIC_SCREENS[vs_name] then + local vs_type = dfhack.gui.getDFViewscreen(true)._type + if NO_LOGIC_SCREENS[vs_type] then self.force_pause = true self.pass_movement_keys = false self.pass_mouse_clicks = false