Closed lethosor closed 3 years ago
From an initial inspection, the issue is that the command-prompt screen is re-added to the screen stack after the command (gui/liquids in this case) is run:
[DFHack]# devel/list-screens
<viewscreen: 0x232a668>
<viewscreen_dwarfmodest: 0x7fff9e993b70>
<viewscreen: 0x7fffb4000e40> # created by command-prompt
<viewscreen: 0x7fffd18c3f90> # created by gui/liquids
My understanding of how command-prompt
works after #1319:
command-prompt
screen is removed from the screen stack entirelycommand-prompt
screen is re-added in the stack, underneath its previous parent screen - this matches the abovecommand-prompt
screen is dismissed with Screen::dismiss()
. However, as with all screens, the screen is not actually removed from the stack until it is the topmost screen. In this case, gui/liquids
ends up on top somehow.My best guess is that gui/liquids
is attempting to pass keys to the command-prompt screen. This confuses me a bit because in step 3, the gui/liquids
screen should identify the fortress mode screen as its parent when it is created. I may be misunderstanding when the screen is actually added, though. Another possibility is that gui/liquids
is passing keys to the fortress mode screen successfully, but that screen is not re-rendering due to the intermediate command-prompt screen.
Possible solutions:
command-prompt
screen to unconditionally pass through calls to logic(), feed(), and render() if it is dismissed. (I'm not sure if these functions are actually called on dismissed screens, though.)Screen::Hide
to (optionally?) re-add screens at the top of the screen stack. This may cause undesired effects. command-prompt
appears to be the sole user of Screen::HIde
, however.command-prompt
to forcibly remove its screen from the screen stack instead of just calling dismiss()
. This could crash DF if done in a method of that screen, which is where dismiss()
is currently called from.It turns out that keys are being passed to the command-prompt
screen, which does not propagate them to its parent, and also ignores most keys entirely if is_response
is set (i.e. after a command has been run). In the case of gui/teleport
, cursor keys are passed through propagateMoveKeys()
, which checks screen._native.parent
every time, usually after it has been changed by Screen::Hide
.
I think the best solution here is to move the command-prompt
screen to the top of the stack when it is shown again, which will cause it to be dismissed right away. This appears to work for gui/liquids
and gui/teleport
, at least.
Reported by Bumber here: http://www.bay12forums.com/smf/index.php?topic=164123.msg8261345#msg8261345
To reproduce:
command-prompt
, e.g. with Ctrl-Shift-Pgui/liquids
and press Enter