In the process we find a new bug. Scrolling with keyboard is overly
eager to clamp screen_top to bottom of screen when the top used to be
within the viewport.
Until recently, scrolling past the bottom when the margin was visible
would move the cursor correctly but pan the surface to the top of the
viewport. Slightly jarring, but good enough.
scenarios:
* Zoom = 1
* pan with mouse: ✓
* pan with up arrow: ✓
* pan with down arrow: ✓
* Zoom < 1
* pan with mouse: ✓
* pan with up arrow: ✓
* pan with down arrow: ✗
* Zoom > 1
* pan with mouse: ✓
* pan with up arrow: ✗
* pan with down arrow: ✓
What ✓ means:
* pan with mouse: lines don't slide relative to the surface
* will still slide relative to the surface when zooming in/out;
that's unavoidable because we want integer pixels for crisp text
* pan with keyboard: at least some part of cursor is always peeking within the viewport
* might still look ugly, with the line containing the cursor almost invisible,
but hitting the down arrow will never pan upwards, or vice versa
Still not working though. I'm pretty much guaranteeing by construction that if
Viewport.y was set from screen_top1, then screen_top1 will not be perturbed.
And yet using scale() inside update_editor_box is incorrect. Hmm..
Well, almost. I'm just reminding myself of the sort of plumbing I need,
not reintroducing the old logic that never worked right and had
undergone n iterations of corruption.
I don't know why this was so hard, but I don't need this variable
preserve_screen_top_of_cursor_node at all. We only set it when the
cursor is in some node, but we also only check for when the current node
is the cursor. Comparing with a nil cursor node works just as well.
I've also checked that driver.love doesn't need
preserve_screen_top_of_cursor_node. I think it came from pensieve.love,
where I've since taken it out. Did I ever need it even there?