on.text_input = function(t) if Cursor_node and Cursor_node.editor.cursor_x then local old_top = {line=Cursor_node.editor.screen_top1.line, pos=Cursor_node.editor.screen_top1.pos} edit.text_input(Cursor_node.editor, t) if not eq(Cursor_node.editor.screen_top1, old_top) then Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1) -- Most of the time, we update the screen_top of nodes from Viewport.y. -- But here we went the other way. -- It's very important to avoid creating a recurrence, to avoid running -- both sides of this feedback loop in a single frame. These apps are -- not very numerically precise (e.g. we force text lines to start at -- integer pixels regardless of zoom, because that keeps text crisp), -- and the computations of Viewport.y and node.top will almost certainly -- not converge. The resulting bugs are extremely difficult to chase -- down. -- The optional skip_updating_screen_top_for arg ensures we don't run -- the other side of the feedback loop. A(--[[skip updating screen_top for]] Cursor_node) return end A() end end