erkyrath / glkote

A Javascript display library for IF interfaces
http://eblong.com/zarf/glk/glkote.html
MIT License
26 stars 11 forks source link

A text buffer status window keeps wanting to be scrolled #42

Closed curiousdannii closed 2 months ago

curiousdannii commented 4 years ago

https://github.com/curiousdannii/parchment/tree/glkote-test

I've rejigged Parchment to use the code from the master branch of glkote. You'll need to ensure your checkout has retrieved all the submodules, but you won't need to run any build step. It will need to run from a webserver (not just a "file:" URL).

screenshot of the problem

So TADS creates a two line text buffer status window, and something must be up with the measurements because it keeps trying to scroll and putting up the More indicator.

erkyrath commented 4 years ago

This is a common problem whenever people try to use a buffer window for formatted output (inventory, stats, etc). I agree that glkote should handle this case better.

Related: sometimes people try to hide a buffer window (while preserving its contents) by setting it to zero height. That causes problems too -- it captures keystrokes trying to scroll. Handle that too.

curiousdannii commented 4 years ago

Found what causes the scrolling: it's the InvisibleCursor with its 14px padding-bottom. Not sure what to do to fix it though.

Edit: As a temporary solution I'm commenting out the padding.

erkyrath commented 4 years ago

The correct solution is to add an InvisibleCursor to the #layout_test_pane and account for its size. I'll whip up a patch soon.

erkyrath commented 4 years ago

This situation seems more complicated than I thought.

I created a test I6 game which uses a buffer-style status window: https://github.com/erkyrath/glk-dev/blob/master/unittests/statusbufferwin.ulx

In this test, there's a third window (a textbuffer) which shows your inventory. The height is always N+1, where N is your inventory count, so it can say "You are carrying N items / Item 1 / Item 2 / Item 3 / ..."

This works without any scrolling or MORE prompt if I am careful to never print a newline at the end of the last line. You can see this in the source (https://github.com/erkyrath/glk-dev/blob/master/unittests/statusbufferwin.inf) -- for N lines, the AfterPrompt routine prints exactly N-1 newlines.

If I change the code to the (less awkward) form where every line ends with a newline, then it does show a MORE prompt. The displayed text has a blank line at the end, which means N+1 displayed lines, so there is scrolling.

But this is not interpreter-specific. For the same test, Gargoyle also puts a blank line at the end and causes scrolling problems (~although no MORE prompt~). EDIT: I was wrong, Gargoyle has the MORE problem also.

So, what's the right behavior here?

I assume that your TADS setup is putting a newline at the end of each line. (Otherwise the problem would never have arisen.) Why does removing the InvisibleCursor suppress the problem? Is the blank line collapsing in the HTML?

erkyrath commented 4 years ago

I updated statusbufferwin.ulx to support both newline modes, for testing. Type TURN SWITCH.

curiousdannii commented 4 years ago

I'm not sure if a final newline is being sent; the JSON sent to GlkOte just has the two lines, so I think probably not.

Why does removing the InvisibleCursor suppress the problem?

Because it's not an extra line, it's the extra padding that's the problem. The invisible cursor is added to the final line, and it's 14px padding doesn't fit within the 6px padding of the window, but it doesn't get clipped, so it forces the window to be scrollable.

I tried your test file in Quixe, and turning the switch to start doesn't prevent the problem.

erkyrath commented 4 years ago

Hm, okay. I have only tested in Lectrote. There must be some sneaky CSS difference. Will check further.

erkyrath commented 3 years ago

I added some extra margin space for the InvisibleCursor, but this is insufficient. I also have to deal with the final newline.

erkyrath commented 3 years ago

Okay, I think I have a solution.

The InvisibleCursor no longer has padding. In fact it no longer has any layout effect. I should remove it, but that would require unpicking more glkote.js code than I want to deal with right now.

Bottom margin is now created by this CSS:

.BufferLine:last-child { margin-bottom: 14px; }

This gets correctly measured by the test pane, so a fixed-height buffer window will include the margin space.

Then, on the flip side, there's CSS which suppresses an entirely blank BufferLine if it's the last line in the window and no line/char input is occurring in the window. This fixes the "extra newline" problem.

Tested with statusbufferwin.ulx and Thaumistry.t3 (which uses a buffer status window).

erkyrath commented 3 years ago

Still not done! Turns out the T3 status windows scroll just a little bit due to the difference between normal and bold font.

If "a little bit" exceeds one pixel, we're back to the MORE prompt.

I think I'm going back to Dannii's earlier suggestion of dropping the bottom-margin declaration for fixed-height windows.

erkyrath commented 3 years ago

dropping the bottom-margin declaration for fixed-height windows.

Unfortunately not possible because glkote doesn't know which windows are fixed-height.

I may have to just leave a few more pixels of slop.

erkyrath commented 3 years ago

Taking another shot.

erkyrath commented 2 months ago

I think this was fixed by my Nov-2020 change.