fix(ui): attach settings menu keydown synchronously

Caught by Copilot on PR #514.  openSettingsMenu sets _settingsMenu
synchronously, but the menu's keydown handler was registered inside
setTimeout(0).  The previous-commit guard in the global keydown
handler returns early when _settingsMenu is set (so dashboard isn't
hidden by Escape over the menu), which created a window where
Escape had no handler at all — the global skipped, the menu's own
listener wasn't ready yet, and the menu got stuck open until the
next interaction.

Attach keydown synchronously; keep mousedown + initial focus in
setTimeout (mousedown to avoid the opening click triggering its own
outside-click close, focus because the menu DOM needs a tick to
settle layout).
This commit is contained in:
Patrick Buckley
2026-05-11 18:35:56 -07:00
parent f1cf516eb6
commit 8eec44d809
+11 -3
View File
@@ -6090,14 +6090,22 @@ function openSettingsMenu(triggerEl) {
}
};
// Defer listener wiring + focus so the click that opened the menu
// doesn't immediately trigger the mousedown-close path.
// Attach the keydown listener synchronously so an Escape press
// queued behind the opening click isn't silently dropped: the
// global keydown handler at the bottom of this file returns early
// when _settingsMenu is set (the dashboard-Escape-wipes-composer
// guard), so without a synchronous menu-side listener there's a
// brief window where Escape has no handler at all. Mousedown +
// initial focus stay deferred — mousedown to avoid the click that
// opened the menu firing its own outside-click close, initial
// focus because the menu DOM needs a tick to settle layout before
// we call focus() on its first item.
document.addEventListener("keydown", _settingsMenuCloseHandler);
var activeMenu = menu;
var closeHandler = _settingsMenuCloseHandler;
setTimeout(function () {
if (_settingsMenu !== activeMenu || !closeHandler) return;
document.addEventListener("mousedown", closeHandler);
document.addEventListener("keydown", closeHandler);
var first = activeMenu.querySelector(".ws-tab-dropdown-item");
if (first) first.focus();
}, 0);