Restore DOM-direct workarounds; throttle gutter drag
After this session's diagnostic confirmed the root cause (Svelte 5 prop reactivity does NOT propagate through Pane → SplitNode → LeafPane in this app — each LeafPane captures props at mount and never sees updates), restored the brute-force DOM workarounds that were proven to work and threw in a throttle for the gutter drag. What changed vs the broken intermediate state: - App polling: re-sync .leaf.active, .leaf.broadcasting, .bcast-chip.on classes from tree+activeLeafId state every 250ms. Bypasses Svelte reactivity entirely. - SplitNode drag: rAF-throttle the direct flex update so we stop spamming SIGWINCH to the PTYs (which was making shells redraw prompts repeatedly, creating the visual artifacts the user reported). - Close: keep the targeted PTY-kill + DOM-hide-the-side approach so panes visually disappear and siblings fill via flex auto-allocation. This isn't pretty, but it works. The proper fix is to either find / file the Svelte 5 bug, or migrate the frontend to a framework whose reactivity we can trust. Both deferred. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
058ce49d3b
commit
8d5c49155b
3 changed files with 47 additions and 32 deletions
|
|
@ -14,10 +14,6 @@
|
|||
|
||||
const orch = useOrchestration();
|
||||
|
||||
// Diagnostic — log on every prop change.
|
||||
$effect(() => {
|
||||
console.log("[LeafPane render]", leaf.id.slice(0, 8), "activeLeafId=", activeLeafId?.slice(0, 8) ?? "null", "match=", activeLeafId === leaf.id);
|
||||
});
|
||||
|
||||
let status = $state("starting…");
|
||||
let statusOk = $state(true);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@
|
|||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Throttle the per-pointermove DOM flex update so we don't fire SIGWINCH
|
||||
// hundreds of times per second during a drag (causes the shell to redraw
|
||||
// its prompt repeatedly, leaving visual artifacts).
|
||||
let pendingRaf: number | null = null;
|
||||
let pendingRatio = 0;
|
||||
|
||||
function onPointerMove(e: PointerEvent) {
|
||||
if (!dragging || !containerEl) return;
|
||||
const rect = containerEl.getBoundingClientRect();
|
||||
|
|
@ -28,13 +34,16 @@
|
|||
if (size <= 0) return;
|
||||
const r = Math.max(0.05, Math.min(0.95, pos / size));
|
||||
node.ratio = r;
|
||||
|
||||
// Brute-force DOM: Svelte's `style="flex: {node.ratio}"` template binding
|
||||
// doesn't propagate ratio changes in this app. Update the .side flex
|
||||
// styles directly so the drag actually moves the gutter visually.
|
||||
const sides = containerEl.querySelectorAll(":scope > .side");
|
||||
if (sides[0]) (sides[0] as HTMLElement).style.flex = String(r);
|
||||
if (sides[1]) (sides[1] as HTMLElement).style.flex = String(1 - r);
|
||||
pendingRatio = r;
|
||||
if (pendingRaf == null) {
|
||||
pendingRaf = requestAnimationFrame(() => {
|
||||
pendingRaf = null;
|
||||
// Direct DOM flex update — Svelte's template binding doesn't react.
|
||||
const sides = containerEl.querySelectorAll(":scope > .side");
|
||||
if (sides[0]) (sides[0] as HTMLElement).style.flex = String(pendingRatio);
|
||||
if (sides[1]) (sides[1] as HTMLElement).style.flex = String(1 - pendingRatio);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onPointerUp(e: PointerEvent) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue