From 616973b0fa5d9fa8593482b51e2658faac9927e3 Mon Sep 17 00:00:00 2001 From: th Date: Mon, 20 Apr 2026 22:20:58 +0200 Subject: [PATCH] feat: click-outside deselects a selected marker Esc was already wired but nobody stumbles onto it. A capture-phase pointerdown listener is installed while selectedMarkerId is set; any click that doesn't land on a .timeline-marker (or on an open dialog/menu) clears the selection. Listener is torn down automatically when selection clears or the component unmounts. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/Timeline.vue | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index 9a96e7c..28fb129 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -412,6 +412,23 @@ function onOutBracketPointerUp(e: PointerEvent) { const selectedMarkerId = ref(null) const markerDrag = ref<{ id: string; startX: number; moved: boolean } | null>(null) +function onOutsideMarkerPointerDown(e: PointerEvent) { + const el = e.target as HTMLElement | null + // Leave selection alone when the click lands on the marker itself + // (or any menu/dialog — treat anything inside a popup as "not outside"). + if (el?.closest('.timeline-marker')) return + if (el?.closest('.dialog, .kf-menu, .track-menu')) return + selectedMarkerId.value = null +} + +watch(selectedMarkerId, (id) => { + if (id) { + document.addEventListener('pointerdown', onOutsideMarkerPointerDown, true) + } else { + document.removeEventListener('pointerdown', onOutsideMarkerPointerDown, true) + } +}) + function markerTimeFromEvent(e: PointerEvent, markerEl: HTMLElement): number { const ruler = markerEl.parentElement as HTMLElement | null if (!ruler) return 0 @@ -1878,6 +1895,7 @@ onBeforeUnmount(() => { ro?.disconnect() ro = null document.removeEventListener('pointerdown', onDocumentPointerDown, true) + document.removeEventListener('pointerdown', onOutsideMarkerPointerDown, true) document.removeEventListener('keydown', onKeyDown) document.removeEventListener('keydown', onDocumentKeyDown) })