vt: Textual apps crash on the first mouse event because ?2048 reports 0 pixel extents #143
Labels
No labels
Area/ci
Area/cli
Area/client
Area/client-core
Area/daemon
Area/deps
Area/docs
Area/grid
Area/manual
Area/nix
Area/protocol
Area/pty
Area/render
Area/shaping
Area/skills
Area/transport
Area/vt
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Performance
Kind/Security
Kind/Testing
perf-regression-accepted
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Blocked
Status
Need More Info
Status
Upstream
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
felis-terminal/felis#143
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Every Textual app with mouse support crashes on its first mouse event under felis.
Textual turns on SGR-pixel mouse reporting (
?1016) whenever the terminal answers?2048as supported (textual/drivers/linux_driver.pyprocess_message,_enable_mouse_pixels). It then converts each report back to cells with the pixel extents from theCSI 48 ; rows ; cols ; height ; width tnotification (textual/_xterm_parser.pyparse_mouse_code:x /= pixel_width / width). felis sends0for both pixel axes (felis-gridresize_notify_report_bytes), so the division raisesZeroDivisionErrorand the app exits.Reproduced on
main(debug build, isolated daemon, Textual 8.2.8): a one-button Textual app spawned withfelis sessions spawn, then one SGR click sent withfelis sessions send --raw:Not run with a window, but a window's clicks take the same path: the client fills
?1016reports with real pixels, while the?2048report is0;0whatever the window supplied, so the division is the same whoever sends the click.The recorded decision and why it does not hold
docs/explanation/protocols/landscape.md"CSI" keeps the pixel axes at the0stubCSI 14 tanswers "so the push never widens what a program can learn about the host". But the session's PTY already carries the window-supplied pixel extents inTIOCGWINSZ(ws_xpixel/ws_ypixel, set from the attach/resize dims insession_task.rs; vt-compliance.md's own table namesTIOCGWINSZas the path to a window's pixels). Reporting those same values inCSI 48 ttells a program nothing it cannot already read, so the rationale coversCSI 14 t(a pull of the host window's extents) but not?2048.Direction to settle
?2048reports the PTY's ownws_ypixel/ws_xpixel, so the notification andTIOCGWINSZagree.CSI 14 / 15 / 16 tstay stubbed; the landscape.md paragraph is reworded to draw the line at "nothing beyondTIOCGWINSZ" rather than at "no pixels".0pixel extents in both places, so a Textual app there still divides by zero on the first click. The daemon gives a windowless session a nominal cell size, applied toTIOCGWINSZand the report alike: #131 (send --mouse) derives?1016pixels from this geometry and mostly drives headlesssessions spawnsessions, so it depends on this. A window's first resize replaces the nominal size.0pixel extents should not crash the app.