(data: string)
| 769 | } |
| 770 | |
| 771 | private handleInput(data: string): void { |
| 772 | if (this.consumeOsc11BackgroundResponse(data)) { |
| 773 | return; |
| 774 | } |
| 775 | if (this.consumeTerminalColorSchemeReport(data)) { |
| 776 | return; |
| 777 | } |
| 778 | |
| 779 | if (this.inputListeners.size > 0) { |
| 780 | let current = data; |
| 781 | for (const listener of this.inputListeners) { |
| 782 | const result = listener(current); |
| 783 | if (result?.consume) { |
| 784 | return; |
| 785 | } |
| 786 | if (result?.data !== undefined) { |
| 787 | current = result.data; |
| 788 | } |
| 789 | } |
| 790 | if (current.length === 0) { |
| 791 | return; |
| 792 | } |
| 793 | data = current; |
| 794 | } |
| 795 | |
| 796 | // Consume terminal cell size responses without blocking unrelated input. |
| 797 | if (this.consumeCellSizeResponse(data)) { |
| 798 | return; |
| 799 | } |
| 800 | |
| 801 | // Global debug key handler (Shift+Ctrl+D) |
| 802 | if (matchesKey(data, "shift+ctrl+d") && this.onDebug) { |
| 803 | this.onDebug(); |
| 804 | return; |
| 805 | } |
| 806 | |
| 807 | // If focused component is an overlay, verify it's still visible |
| 808 | // (visibility can change due to terminal resize or visible() callback) |
| 809 | const focusedOverlay = this.overlayStack.find((o) => o.component === this.focusedComponent); |
| 810 | if (focusedOverlay && !this.isOverlayVisible(focusedOverlay)) { |
| 811 | // Focused overlay is no longer visible, redirect to topmost visible overlay |
| 812 | const topVisible = this.getTopmostVisibleOverlay(); |
| 813 | if (topVisible) { |
| 814 | this.setFocus(topVisible.component); |
| 815 | } else { |
| 816 | this.setFocusInternal({ component: focusedOverlay.preFocus, overlayFocusRestore: "preserve" }); |
| 817 | } |
| 818 | } |
| 819 | |
| 820 | const focusIsOverlay = this.overlayStack.some((o) => o.component === this.focusedComponent); |
| 821 | if (!focusIsOverlay) { |
| 822 | const restoreState = this.getVisibleOverlayFocusRestore(); |
| 823 | if (restoreState.status === "eligible") { |
| 824 | this.setFocus(restoreState.overlay.component); |
| 825 | } else if (restoreState.status === "blocked" && restoreState.blockedBy !== this.focusedComponent) { |
| 826 | if (restoreState.resume.status === "restore-overlay") { |
| 827 | this.setFocus(restoreState.overlay.component); |
| 828 | } else { |
no test coverage detected