mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 04:20:45 +08:00
Dedupe WebCRT command audit on double-fired Enter.
xterm and keydown can both emit carriage return for one keypress; skip duplicate Enter frames on the client and collapse identical audits within 450ms on the server. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7ca57278fe
commit
52424dce37
3 changed files with 58 additions and 1 deletions
|
|
@ -269,6 +269,8 @@ export const WebTerminal = forwardRef<WebTerminalHandle, Props>(function WebTerm
|
|||
const pasteBridgeOpenRef = useRef(false);
|
||||
pasteBridgeOpenRef.current = pasteBridgeOpen;
|
||||
const findInputRef = useRef<HTMLInputElement | null>(null);
|
||||
/** Suppress duplicate Enter frames (keydown + xterm onData both fire). */
|
||||
const enterHandledAtRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
onStatusRef.current = onStatus;
|
||||
|
|
@ -338,6 +340,16 @@ export const WebTerminal = forwardRef<WebTerminalHandle, Props>(function WebTerm
|
|||
sendJson(payload);
|
||||
};
|
||||
|
||||
const sendEnterStdin = (term: Terminal, explicitAuditLine?: string) => {
|
||||
enterHandledAtRef.current = performance.now();
|
||||
sendStdinWithAudit("\r", explicitAuditLine ?? auditLineForEnter(term));
|
||||
};
|
||||
|
||||
const isDuplicateEnterFrame = (data: string): boolean => {
|
||||
if (!/^[\r\n]+$/.test(data)) return false;
|
||||
return performance.now() - enterHandledAtRef.current < 120;
|
||||
};
|
||||
|
||||
const sendStdinImmediate = (data: string) => {
|
||||
sendStdinWithAudit(data);
|
||||
};
|
||||
|
|
@ -705,11 +717,15 @@ export const WebTerminal = forwardRef<WebTerminalHandle, Props>(function WebTerm
|
|||
|
||||
const dataDisposable = term.onData((data) => {
|
||||
const normalized = data.replace(/\x7f/g, "\x08");
|
||||
if (isDuplicateEnterFrame(normalized)) return;
|
||||
// Capture visible line before Enter moves the cursor to the next row.
|
||||
const auditLine =
|
||||
normalized.includes("\r") || normalized.includes("\n")
|
||||
? auditLineForEnter(term)
|
||||
: undefined;
|
||||
if (normalized.includes("\r") || normalized.includes("\n")) {
|
||||
enterHandledAtRef.current = performance.now();
|
||||
}
|
||||
// Large pastes from xterm arrive as one onData blob.
|
||||
if (normalized.length > 32 || normalized.includes("\r") || normalized.includes("\n")) {
|
||||
sendStdinThrottled(normalized, auditLine);
|
||||
|
|
@ -783,7 +799,7 @@ export const WebTerminal = forwardRef<WebTerminalHandle, Props>(function WebTerm
|
|||
e.stopPropagation();
|
||||
maybeFocus();
|
||||
if (e.key === "Enter") {
|
||||
sendStdinWithAudit("\r", auditLineForEnter(term));
|
||||
sendEnterStdin(term, auditLineForEnter(term));
|
||||
return;
|
||||
}
|
||||
sendStdinWithAudit(data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue