Yeah, I noticed the behaviour for vanilla screens too. In fact, setfps 10 is my litmus test, since I know at least some players run with at least gfps at 10 (not that it'd matter if actual fps is higher).
I initially went by modifying screen._native.parent.child or df.global.gview.view, but then I realized that screen._native.parent.child is screen._native, and tested that both poof it without blinking.
Shame it leaks memory, then - I'd have assumed that lua garbage collection would clean up the table that I don't know is being used anywhere, but I guess it is not so. (And yes, badly toying with this does indeed result in errors or even DF crashes. i.e. setting the parent.child to nil and then calling screen:dismiss() without waiting two frames in-between, amongst many, many, many other variants.)
For reference, code that seemed to work fine:
local myscreen = dfhack.gui.getCurViewscreen()-- df.global.gview.view.child.child
dfhack.timeout(100, "frames", function()
myscreen.parent.child = nil
dfhack.timeout(2, "frames", function()
newscreen:dismiss()
dfhack.println("screen is dismissed " .. tostring(newscreen:isDismissed()))
end)
end)
Tested it while running firefox in background (with slightly complicated screen object) by pasting 101 lines of screen-making into console and DF went from 383,3 MB to up to highest point 663 MB while using 1 CPU at full blow, then down to 628,2 MB after all were gone and game had returned to dwarfmode/Default - which averages to a 2,42 MB of RAM per screen.
However, doing that same test with just :dismiss() after 100 frames resulted in 384,0 MB → high of 900+ before even being done *killed at this point and reran with quit firefox RAM* - high of 508→ remained there after all were gone, an average of 1,23 MB. Unlike before threw a bunch of errors.
Then reran initial to be fair with also less demand on ram and got 381,3 → high of 431,1 → remained there, for average of 0,49 MB per screen.
It seems this has less of a memory leak, in both cases? Couldn't even run 101 screens with firefox eating vast majority of RAM with the default :dismiss().
*befuddled*
Anyway, it seems that one can improve on DF's cleanup. No crashes with that, but just few tests in dwarfmode. Though I do have the question of what is still left hanging with the above method?
(It'd be also nice if you could know if this was fine, but ain't nobody who knows that for sure.)
Hmm...Maybe screen object itself. *Tests with newscreen= nil after the line and fox restarted* 380,2 →429,5. 0,49 still.