mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 01:09:43 +02:00
fix(tiles): send a tile's click report ephemeral, review follow-up
The tile's hand-encoded click report went through _handleDesktopTerminalClick and _sendSyntheticSgrTap to _sendInputAsync, so it took a seq, was persisted and would be redelivered after a reload. The documented TerminalTile rule (CLAUDE.md, Split-pane sessions) is that only typed input enters that queue and focus/mouse reports go out ephemeral, and the tile's own _onTerminalData says the same. Before #555 an opencode tile's click went through xterm's encoder and that ephemeral path. A click still unacknowledged when the page reloads, or sent during a server restart, could be replayed onto a later screen, where a press+release can pick a dialog option. _sendSyntheticSgrTap now takes an opt-in `ephemeral` field on its target and sends through _sendInputEphemeral when it is set; _handleDesktopTerminalClick passes the target through unchanged, and TerminalTile._installClickListener sets it. Without the flag nothing changes, so the primary pane's own click and touch tap reports stay on _sendInputAsync exactly as before (whether the primary pane should also go ephemeral is a separate question, out of scope here). Tests: the tile case now requires a frame with no seq and nothing pending in the reliable queue, and the targeted-click case in terminal-touch-tap spies on both send paths: a target with the flag goes ephemeral, an untargeted click and an untargeted tap stay durable. Dropping `ephemeral: true` from the tile, or the branch in _sendSyntheticSgrTap, turns the matching test red. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -514,13 +514,16 @@ describe('a tile reports a plain click to a CLI with mouse tracking on', () => {
|
||||
});
|
||||
const TAP = '\x1b[<0;21;6M\x1b[<0;21;6m';
|
||||
|
||||
it("sends one seq-tagged SGR press+release on the tile's socket, from the tile's own geometry", async () => {
|
||||
it("sends one ephemeral SGR press+release on the tile's socket, from the tile's own geometry", async () => {
|
||||
const app = makeApp({ other: { mode: 'shell' }, 's-tile': { mode: 'opencode', cliMouseTracking: true } });
|
||||
const { ws, mount } = await connectTile(app);
|
||||
|
||||
mount.fire('click', click());
|
||||
|
||||
expect(ws.inputFrames().map((f) => [f.d, typeof f.seq])).toEqual([[TAP, 'number']]);
|
||||
// No seq: like every mouse report from a tile, it never enters the
|
||||
// persisted exactly-once queue, so a reload cannot replay it.
|
||||
expect(ws.inputFrames().map((f) => [f.d, typeof f.seq])).toEqual([[TAP, 'undefined']]);
|
||||
expect((app._pendingDeliveries as Map<string, unknown[]>).get('s-tile')?.length ?? 0).toBe(0);
|
||||
});
|
||||
|
||||
it('sends nothing without the flag, over a selection, over its own hovered link, or scrolled up', async () => {
|
||||
|
||||
Reference in New Issue
Block a user