Repository navigation
fix mouse char bug on bwopencode exit - #23
Draft
Matt Snyder (maatthias) wants to merge 2 commits into
Draft
Matt Snyder (maatthias) wants to merge 2 commits into
Matt Snyder (maatthias) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Signal handling and background cleanup can disrupt termination or terminal state, while continued input can delay exit for minutes.
4 open issues
What changed in this PR
Prevents stray mouse reports from reaching the shell after sandboxed TUI tools exit.
Changes:
- Keeps wrappers running to restore terminal modes and drain delayed input.
- Adds a configurable drain timeout and documents exit cleanup.
- Updates dry-run output to match the foreground-child launch.
| File | Description |
|---|---|
lib/bwrap_sandbox_lib.sh |
Adds terminal cleanup and changes sandbox launch handling. |
docs/bw-wrappers.md |
Documents terminal restoration and timeout configuration. |
Review effort: Balanced
| exec "${_ENV_BIN}" -i \ | ||
| trap ':' INT | ||
| trap - TERM | ||
| "${_ENV_BIN}" -i \ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Fix stray mouse-report characters (e.g.
51;97;30M) landing on the shellprompt when exiting
bwopencode(and the otherbw*wrappers) from a GTK4terminal such as Ptyxis over SSH.
Description
Root cause
TUI tools enable all-motion mouse tracking (
ESC[?1003h) and, on exit, send"leave alternate screen" (
ESC[?1049l) before "mouse tracking off"(
ESC[?1003l).GTK4 synthesises a pointer-motion event whenever a window's layout changes,
even if the pointer has not moved (
gtk/gtkwindow.c: "This fake motionevent is needed ... when the pointer didn't move but the layout changed").
Leaving the alternate screen is such a layout change in Ptyxis. VTE, still in
?1003mode at that instant, encodes the synthetic event as an SGR mousereport (
ESC[<35;x;yM, or51if Ctrl is still held from Ctrl-D) and sendsit back over the two SSH hops. By the time it arrives, opencode has exited.
Because
launch_sandbox()exec'd bwrap, the wrapper no longer existedeither, so the report was read by the login shell: the tty echoed
^[[<,readline consumed the escape prefix, and
51;97;30Mwas left on the prompt.This is not device-specific (reproduced with no mouse attached and hands off
the trackpad) and affects any GTK4/VTE terminal (Ptyxis, GNOME Terminal,
Black Box) over a link with non-trivial latency.
Fix
lib/bwrap_sandbox_lib.sh:launch_sandbox()now runsenv -i ... bwrap ...as a foreground childinstead of
exec, captures the exit status and propagates it unchanged viaexit "$_rc"._restore_terminal()runs after the child exits, only when stdin andstdout are a tty:
events (1004) off, bracketed paste (2004) off, pop kitty keyboard flags
(
CSI < u), show cursor (all no-ops if already in the default state, sosafe after
--execcommands);stty -echo, then read-and-discard stdin until it has been quiet forBWRAP_TTY_DRAIN_SECS(default 0.3 s, host-env overridable forhigh-latency links), with an iteration cap so a misbehaving terminal
cannot hang the wrapper;
stty saneif the tool crashedwhile in raw mode.
trap ':' INTaround the wait so a Ctrl-C that kills the child does notalso kill the wrapper before the terminal is restored. Children still
receive SIGINT normally (trapped signals reset to default on exec).
print_dry_runoutput drops the leadingexecto match the realinvocation; comments updated accordingly.
docs/bw-wrappers.md: new "Terminal restoration on exit" section.Side effects / notes for reviewers
--die-with-parentis now anchored to the wrapper rather than the loginshell. Equivalent in practice: the wrapper lives exactly as long as bwrap.
bwcodex'strap ... EXITthat removes the stagedconfig.toml(
bin/bwcodex:372) never fired underexec; it will now.bwopencode,bwclaude,bwcodex,bwcopilot) since they share the library.mouse-off before leaving the alt screen (or use
?1002, which VTE dedups).That would fix the root cause for everyone, but the wrapper fix is still
worthwhile as defence in depth for all four tools.
Testing
Tested with gnome/ptyxis terminal on
runansible3Need more tests on other OS/terminals
Checklist
pixi run -e dev lintlocally (or wait for CI) — see.github/workflows/lint.ymlrunansibledeployment)