Fix active-pane detection via activeElement polling
After exhausting event-based approaches that all failed in WebView2: - per-leaf onpointerdown: xterm.js stopPropagation - document-capture pointerdown: only first event ever delivered - document-capture mousedown/click: never delivered at all - document-capture focusin: silently fails - term.onFocus: no such xterm.js API The bulletproof fallback: poll document.activeElement every 250ms and call orch.setActive on its closest [data-leaf-id] ancestor. No DOM events involved. Verified working with automation: clicking pane 2 turns its border blue, clicking pane 1 moves the border to pane 1, etc. XtermPane gained an onFocus prop (still wired through LeafPane) as a secondary signal that might fire in some configurations, but the polling is the actual fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4fd613438c
commit
f5f788652e
3 changed files with 38 additions and 15 deletions
|
|
@ -20,6 +20,7 @@
|
|||
onSpawn = undefined,
|
||||
onInput = undefined,
|
||||
onDataReceived = undefined,
|
||||
onFocus = undefined,
|
||||
focusTrigger = 0,
|
||||
}: {
|
||||
distro?: string;
|
||||
|
|
@ -31,6 +32,8 @@
|
|||
onInput?: (dataB64: string) => void;
|
||||
/** Fired whenever output arrives from the PTY. Used for idle detection. */
|
||||
onDataReceived?: () => void;
|
||||
/** Fired when xterm's textarea gains focus (i.e., user clicked here). */
|
||||
onFocus?: () => void;
|
||||
/** Increment to refocus the terminal programmatically (palette etc.). */
|
||||
focusTrigger?: number;
|
||||
} = $props();
|
||||
|
|
@ -112,6 +115,20 @@
|
|||
onInput?.(b64);
|
||||
});
|
||||
|
||||
// xterm.js's own focus event — fires when the hidden textarea gets focus
|
||||
// (i.e., user clicked anywhere in the terminal). Most reliable signal
|
||||
// for "user wants this pane active" — no DOM event traversal involved.
|
||||
term.onSelectionChange(() => {}); // ensure the addon system is initialized; noop
|
||||
if (typeof (term as unknown as { onFocus?: unknown }).onFocus === "function") {
|
||||
(term as unknown as { onFocus: (cb: () => void) => void }).onFocus(() => {
|
||||
onFocus?.();
|
||||
});
|
||||
} else {
|
||||
// Fallback: listen on the textarea element directly.
|
||||
const ta = containerEl.querySelector(".xterm-helper-textarea");
|
||||
if (ta) ta.addEventListener("focus", () => onFocus?.(), true);
|
||||
}
|
||||
|
||||
// Re-fit on container resize; forward new size to the PTY.
|
||||
ro = new ResizeObserver(() => {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue