From 0cc4655f9fc43e13f0a2f307b81bb7ac65486c05 Mon Sep 17 00:00:00 2001 From: h Date: Tue, 1 Sep 2026 00:11:09 +0200 Subject: [PATCH] fix(ui): read panel keys at window capture so tasks cannot eat tab --- src/ui/anchored-panel.svelte | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ui/anchored-panel.svelte b/src/ui/anchored-panel.svelte index ac1f17e..1bef234 100644 --- a/src/ui/anchored-panel.svelte +++ b/src/ui/anchored-panel.svelte @@ -51,6 +51,7 @@ function mount(node: HTMLElement) { panel = node; + const win = node.ownerDocument.defaultView ?? window; measure(); if (autofocus) { (node.querySelector("input") ?? node).focus({ @@ -64,17 +65,27 @@ const reflow = (): void => measure(); document.addEventListener("pointerdown", outside, true); window.addEventListener("resize", reflow); + win.addEventListener("keydown", keys, true); return { destroy() { document.removeEventListener("pointerdown", outside, true); window.removeEventListener("resize", reflow); + win.removeEventListener("keydown", keys, true); panel = null; }, }; } + /** + * Read at the window's capture phase rather than on the panel itself. + * Obsidian's keymap listens there first, and a plugin that claims a key + * through `app.scope` — Tasks claims Tab — stops the event before it ever + * reaches an element handler. A listener on the same node still runs after + * that, so this is the one place the panel's keys cannot be taken away. + */ function keys(event: KeyboardEvent): void { + if (!panel?.contains(event.target as Node)) return; event.stopPropagation(); if (event.key === "Escape" && !event.defaultPrevented) { event.preventDefault(); @@ -91,13 +102,11 @@ -