diff --git a/apps/extension/src/changes/commitView.ts b/apps/extension/src/changes/commitView.ts index 6b1d604..fcf90fa 100644 --- a/apps/extension/src/changes/commitView.ts +++ b/apps/extension/src/changes/commitView.ts @@ -3763,6 +3763,7 @@ export class CommitViewProvider branchPill.setAttribute("aria-expanded", "false"); document.removeEventListener("mousedown", onBranchDocDown, true); document.removeEventListener("keydown", onBranchKey, true); + window.removeEventListener("blur", onBranchBlur, true); } function closeBranchSubmenu() { if (branchSubmenu) { branchSubmenu.remove(); branchSubmenu = null; } @@ -3775,6 +3776,19 @@ export class CommitViewProvider if (inSub || inMenu || onPill) return; closeBranchMenu(); } + // Clicks in the editor/main area never reach this webview; blur is the only + // signal that focus left it, so close the popover (JetBrains dismisses + // popovers on any click anywhere in the IDE). + // blur does NOT bubble, but capture starts at window — so clicking inside + // the menu (moving focus off the focused row) fires this too. Only close + // when focus has genuinely left the webview: the setTimeout lets the focus + // move settle first, and the branchMenu-null guard keeps a stale callback + // from closing a menu that was already dismissed. + function onBranchBlur() { + setTimeout(() => { + if (branchMenu && !document.hasFocus()) closeBranchMenu(); + }, 0); + } function onBranchKey(e) { if (e.key === "Escape") { if (branchSubmenu) { closeBranchSubmenu(); subMenuFor = null; return; } @@ -3898,10 +3912,19 @@ export class CommitViewProvider if (actionMenuEl) { actionMenuEl.remove(); actionMenuEl = null; } document.removeEventListener("mousedown", onActionDocDown, true); document.removeEventListener("keydown", onActionKey, true); + window.removeEventListener("blur", onActionBlur, true); } function onActionDocDown(e) { if (actionMenuEl && !actionMenuEl.contains(e.target)) closeActionMenu(); } + // The webview cannot see clicks in the editor/main area — those never reach + // this document. Blur is the only signal that focus left the webview, so + // treat it like a click-outside (JetBrains dismisses popovers on any click). + function onActionBlur() { + setTimeout(() => { + if (actionMenuEl && !document.hasFocus()) closeActionMenu(); + }, 0); + } function onActionKey(e) { if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); closeActionMenu(); } } @@ -3938,6 +3961,7 @@ export class CommitViewProvider menu.style.top = Math.round(top) + "px"; document.addEventListener("mousedown", onActionDocDown, true); document.addEventListener("keydown", onActionKey, true); + window.addEventListener("blur", onActionBlur, true); const first = list.querySelector(".bm-subaction"); if (first) first.focus(); } @@ -4766,6 +4790,7 @@ export class CommitViewProvider setTimeout(() => { document.addEventListener("mousedown", onBranchDocDown, true); document.addEventListener("keydown", onBranchKey, true); + window.addEventListener("blur", onBranchBlur, true); }, 0); } branchPill.addEventListener("click", openBranchMenu);