Frozen on another monitor
Published by Gonzalo Tudela Chavero
The bug
Dragging the browser window from one monitor to another froze this site: no redraw, no keyboard, no tabs. Only on screens with a different scaling (100% to 150%, for example), and only sometimes.
Reproducing it
Headless Chrome can change the device pixel ratio of a running page through the DevTools protocol, so the bug could be triggered on demand. The console showed a single line: RuntimeError: unreachable. With panic = "abort" a Rust panic in WebAssembly ends up as exactly that, with no message, and the whole module stops: the animation loop dies with it.
A one-line panic hook that writes the message to the console turned the mystery into a location: tachyonfx/src/fx/glitch.rs:130, an unwrap() on a cell that did not exist.
The cause
The terminal grid is sized from the canvas in physical pixels. When the pixel ratio changes, the WebGL backend recalculates the grid on its own, in the middle of a frame. Visual effects, like the glitch that fires every 10-25 seconds, keep the area they were created with. A glitch created on the old grid then tried to write a cell outside the new one.
The fix
- If the grid size changes, effects in flight are dropped. They last a fraction of a second; nobody misses them.
- The panic hook stays: the next failure will say where it happened.
Tested by switching the ratio between 1, 1.25, 1.5 and 2, with a glitch running at the same time.