8000 Split-tree changes rebuild every affected terminal; consider keeping xterm instances alive · Issue #346 · amirlehmam/wmux · GitHub
[go: up one dir, main page]

Skip to content

Split-tree changes rebuild every affected terminal; consider keeping xterm instances alive #346

Closed

Description

@jpstratman

What happens

When the split tree changes shape, React remounts every pane whose position in the tree changed, and useTerminal disposes that pane's xterm instance and builds a new one. The PTY and the program in it keep running. Each piece of terminal state then has to be carried across by hand:

Some state still does not survive. Prompt markers are lost, which CLAUDE.md already documents ("Markers do not survive a split-tree restructure"). SerializeAddon also does not carry cursor visibility, cursor style or the scroll region.

Each of these was found the same way: a user hit a broken pane after a layout change, and a new piece of state was added to the replay. The list will keep growing as long as a remount means a new terminal.

What triggers a remount (from reading the code):

  • SplitContainer.tsx keys each branch child by getTreeKey(subtree), so splitting a pane, closing its sibling or moving a tab between panes remounts the panes under the changed branch.
  • App.tsx renders findLeaf(ws.splitTree, zoomedPaneId) as the root while a pane is zoomed, so zooming and unzooming remount panes.
  • wmux browser open in a workspace with no browser pane splits the first pane. For an agent running in a one-pane workspace, that pane is its own.

Suggestion

Keep one xterm instance per surface for the surface's whole life, in a module-level registry keyed by surface id. A remount then moves the existing terminal's DOM element into the new container (container.appendChild(terminal.element) followed by a fit) instead of disposing it. Nothing has to be serialized or replayed, and every mode, marker and decoration survives because the emulator never changes.

Things this would need to handle:

  • disposing the terminal only on a real surface close (handleCloseSurface), not on unmount
  • re-attaching or recreating the WebGL renderer when the element moves, if its context does not survive the move
  • the ReplayHold and ConPTY-anchor logic becoming unnecessary for remounts, though a resize after the move still needs the existing ConPTY handling

This is a larger change than a bug fix, so I'm opening it as a proposal. I haven't prototyped it.

wmux version

2.39.0

Anything else

Related: #49, #164, #216, #256, #345. Browser panes have the same remount problem from the other side (#315).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0