fix(daemon): follow-active-buffer snapshots are semantic-sessions only
Round-2 regression (TUI could not attach): the follow path fired for
every crdt_replica session, and its first-tick send delivered a
GUARANTEED duplicate BufferSnapshot right after the attach sweep. The
grid TUI's BufferMirror is init-once -- the duplicate errored ('buffer
already has a CRDT snapshot applied') on every attach, and every TUI
buffer switch would have produced another. Display-follows-snapshot is
a grid-less-frontend concept: the GPU rebuilds its replica wholesale
on every snapshot and is the only consumer that needs the follow. The
send is now gated on negotiated_capabilities.semantic_render -- TUI
sessions get zero follow-sends, byte-identical wire behavior to main.
Verified: PTY-doubled real-binary attach tests pass with the gate;
the one failing PTY test (m10_11_doubled_pty_fixture_propagates_
keystrokes_from_both_sides, 'AXYB' interleaving) fails identically on
main 3/3 -- pre-existing, tracked separately, not this branch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5c5caa9482
commit
157358c57e
|
|
@ -992,15 +992,29 @@ fn dispatcher_loop(
|
|||
// typing-into-a-buffer-you-can't-see hazard. Ship the
|
||||
// now-active buffer's snapshot to THIS frontend only
|
||||
// (its own view changed; nobody else's did).
|
||||
let active_now = {
|
||||
let core = editor.core.borrow();
|
||||
core.active_window_for(*fid).map(|w| w.buffer_id)
|
||||
};
|
||||
if let Some(active_now) = active_now
|
||||
&& last_active_buffer_sent.get(fid) != Some(&active_now)
|
||||
//
|
||||
// SEMANTIC sessions only: display-follows-snapshot is
|
||||
// a grid-less-frontend concept, and the GPU rebuilds
|
||||
// its replica wholesale on every snapshot. The grid
|
||||
// TUI renders via CellDelta and its `BufferMirror` is
|
||||
// init-once — a follow send there is a guaranteed
|
||||
// duplicate that errors ("already has a CRDT snapshot
|
||||
// applied") on every attach and every buffer switch
|
||||
// (the PR #94 round-2 startup regression).
|
||||
if session_registry
|
||||
.session_state(*fid)
|
||||
.is_some_and(|s| s.negotiated_capabilities.semantic_render)
|
||||
{
|
||||
send_buffer_snapshot_to_frontend(editor, active_now, *fid, &mut streams);
|
||||
last_active_buffer_sent.insert(*fid, active_now);
|
||||
let active_now = {
|
||||
let core = editor.core.borrow();
|
||||
core.active_window_for(*fid).map(|w| w.buffer_id)
|
||||
};
|
||||
if let Some(active_now) = active_now
|
||||
&& last_active_buffer_sent.get(fid) != Some(&active_now)
|
||||
{
|
||||
send_buffer_snapshot_to_frontend(editor, active_now, *fid, &mut streams);
|
||||
last_active_buffer_sent.insert(*fid, active_now);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "crdt"))]
|
||||
|
|
|
|||
Loading…
Reference in New Issue