MCPcopy Create free account
hub / github.com/oboard/claude-code-rev / processKeysInBatch

Function processKeysInBatch

src/ink/components/App.tsx:471–539  ·  view source on GitHub ↗
(app: App, items: ParsedInput[], _unused1: undefined, _unused2: undefined)

Source from the content-addressed store, hash-verified

469// Helper to process all keys within a single discrete update context.
470// discreteUpdates expects (fn, a, b, c, d) -> fn(a, b, c, d)
471function processKeysInBatch(app: App, items: ParsedInput[], _unused1: undefined, _unused2: undefined): void {
472 // Update interaction time for notification timeout tracking.
473 // This is called from the central input handler to avoid having multiple
474 // stdin listeners that can cause race conditions and dropped input.
475 // Terminal responses (kind: 'response') are automated, not user input.
476 // Mode-1003 no-button motion is also excluded — passive cursor drift is
477 // not engagement (would suppress idle notifications + defer housekeeping).
478 if (items.some(i => i.kind === 'key' || i.kind === 'mouse' && !((i.button & 0x20) !== 0 && (i.button & 0x03) === 3))) {
479 updateLastInteractionTime();
480 }
481 for (const item of items) {
482 // Terminal responses (DECRPM, DA1, OSC replies, etc.) are not user
483 // input — route them to the querier to resolve pending promises.
484 if (item.kind === 'response') {
485 app.querier.onResponse(item.response);
486 continue;
487 }
488
489 // Mouse click/drag events update selection state (fullscreen only).
490 // Terminal sends 1-indexed col/row; convert to 0-indexed for the
491 // screen buffer. Button bit 0x20 = drag (motion while button held).
492 if (item.kind === 'mouse') {
493 handleMouseEvent(app, item);
494 continue;
495 }
496 const sequence = item.sequence;
497
498 // Handle terminal focus events (DECSET 1004)
499 if (sequence === FOCUS_IN) {
500 app.handleTerminalFocus(true);
501 const event = new TerminalFocusEvent('terminalfocus');
502 app.internal_eventEmitter.emit('terminalfocus', event);
503 continue;
504 }
505 if (sequence === FOCUS_OUT) {
506 app.handleTerminalFocus(false);
507 // Defensive: if we lost the release event (mouse released outside
508 // terminal window — some emulators drop it rather than capturing the
509 // pointer), focus-out is the next observable signal that the drag is
510 // over. Without this, drag-to-scroll's timer runs until the scroll
511 // boundary is hit.
512 if (app.props.selection.isDragging) {
513 finishSelection(app.props.selection);
514 app.props.onSelectionChange();
515 }
516 const event = new TerminalFocusEvent('terminalblur');
517 app.internal_eventEmitter.emit('terminalblur', event);
518 continue;
519 }
520
521 // Failsafe: if we receive input, the terminal must be focused
522 if (!getTerminalFocused()) {
523 setTerminalFocused(true);
524 }
525
526 // Handle Ctrl+Z (suspend) using parsed key to support both raw (\x1a) and
527 // CSI u format (\x1b[122;5u) from Kitty keyboard protocol terminals
528 if (item.name === 'z' && item.ctrl && SUPPORTS_SUSPEND) {

Callers

nothing calls this directly

Calls 8

handleMouseEventFunction · 0.85
finishSelectionFunction · 0.85
getTerminalFocusedFunction · 0.85
setTerminalFocusedFunction · 0.85
onResponseMethod · 0.80
emitMethod · 0.80
dispatchKeyboardEventMethod · 0.80

Tested by

no test coverage detected