fix(ui): prevent Ctrl+right-click from closing context menu immediately on macOS

Root cause: macOS emits a synthetic click event when the right mouse
button is released while holding Control. The outside-dismiss handler
was listening for click events in capture phase, which caught this
synthetic event and closed the menu right after it opened.

Fix: switch from click to pointerdown (with event.button === 0 guard)
for outside-dismiss detection. pointerdown fires on press before
contextmenu, so the right-button event (button:2) is filtered out
before the menu even opens, and the synthetic click is never seen.
This commit is contained in:
lexmin0412 2026-06-09 16:22:52 +08:00 committed by GitHub
parent efb0dba0ae
commit 20f4a4a5ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 9 additions and 4 deletions

View File

@ -54,7 +54,12 @@ function close() {
show.value = false;
}
function onClickOutside(e: MouseEvent) {
function onPointerDownOutside(e: PointerEvent) {
// Only respond to primary (left) button presses. This avoids a macOS
// issue where Ctrl+right-click generates a synthetic click event on
// mouseup. By using pointerdown (which fires on press, before
// contextmenu) instead of click, we never see that synthetic event.
if (e.button !== 0) return;
const target = e.target as Node;
const inMenu = menuRef.value?.contains(target);
const inSub = subRef.value?.contains(target);
@ -78,13 +83,13 @@ function onResize() {
watch(show, (val) => {
if (val) {
openMenus.add(close);
document.addEventListener("click", onClickOutside, true);
document.addEventListener("pointerdown", onPointerDownOutside, true);
document.addEventListener("keydown", onKeydown);
document.addEventListener("scroll", onScroll, true);
window.addEventListener("resize", onResize);
} else {
openMenus.delete(close);
document.removeEventListener("click", onClickOutside, true);
document.removeEventListener("pointerdown", onPointerDownOutside, true);
document.removeEventListener("keydown", onKeydown);
document.removeEventListener("scroll", onScroll, true);
window.removeEventListener("resize", onResize);
@ -229,7 +234,7 @@ function shortcutKeys(shortcut?: string): string[] {
onBeforeUnmount(() => {
openMenus.delete(close);
document.removeEventListener("click", onClickOutside, true);
document.removeEventListener("pointerdown", onPointerDownOutside, true);
document.removeEventListener("keydown", onKeydown);
document.removeEventListener("scroll", onScroll, true);
window.removeEventListener("resize", onResize);