Ugh, it's been in front of my eyes all along. The logs have been repeatedly showing a recurrence within a single frame:
key press -> update Viewport.y from screen_top -> A -> B -> update_editor_box -> update screen_top from Viewport.y
We need both those updates, but both should never occur at the same time to the same node.
I think this is why screen panning works if I take out the scale inside update_editor_box: the scale has already happened "once" in updating Viewport.y, and it doesn't converge if we perform it a second time in a frame. But the solution is just to do one or the other to a node, never both.
I knew this (learned it the hard way) when I first built pensieve.love, and I had an assertion to avoid it. But my assertion was brittle, and it kept failing, and I took it out, and then I slowly took out all the code that prevented this recurrence.
TZNPEHB3BRUHATVYAODURZUR45TYV62HYWQK5SUXHAOLVGYJVP7AC F5BF4M6KKVFYOO65BMF3TNRTYIOHNVVMPLEQSSX6UCNOOEQMKIIAC QJAYOFWY7V4BWVLJMEDCCBC2HX4BDAZI6PQVLWCLYRHWGMOBFTVAC SY5SNGKD3JUF3S6Q3RVOWEXMKOEQUXFKFRLMSLBPE6RN4YU7DAZQC P36KIMZCWGBG6CZQE3W5SVTCJMYZOVEZ3U3FAF46SO5ZMMM42PHQC WKMW7PCE75A5CFXF5GPL5HQ4ZNASFOFQFHASOQ7LABSQKWU3KEGAC PPVABNGQTQMPYILHDNSNXBI5IOCBSIYO45NIHUR4LYPABQZE6PAQC TK73HJVXQCBEEN4ATMLSSG4DI2XZJAQEJICJ472E3YAW55EFAT5AC KAGTD334AIWFI34VE34OARC44BZDUJRP5R3ZTT6JCQGSYYC3GTVQC JIBCE66ZTWM5WEHEHNKKTRWBJQSQWBDDWPMOJIJR5Q676OSHYCNAC 6KFND4SU2O7UDJVSS74YI3PI453ZFCBM72P6TWLI7DSKFEVUQVFQC AYUZF67YZY2GQBYJJLHU6LI7KJUTBRPYY46WOD4MBVE3DIGSLM2QC TTMMK6S6ILBQ6YN6H2DR5I5PH4ZUITWAGG72AJWLKLKGO5AATT2AC print('viewport', Viewport.y)print('node', Page.data[1].y)print('node renders from', Page.data[1].editor.top)print('screen top', Page.data[1].editor.screen_top1.line)
print('viewport', Viewport.y, 'spx')local node = Page.data[1]print('node', node.y, 'spx')print('line height', node.editor.line_height, 'vpx')print('node renders from', node.editor.top, 'vpx')print('screen top', node.editor.screen_top1.line)print('invariant', Viewport.y-node.y+node.editor.top - y_of_schema1(node.editor, node.editor.screen_top1))
-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,2000,300 dofor y=-10000,10000,200 doadd_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)red = not redendend
Surface = {}