MCPcopy Create free account
hub / github.com/Noumena-Network/code / processKeysInBatch

Function processKeysInBatch

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

Source from the content-addressed store, hash-verified

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