From fa6e76254bf85a9c800132b35e7ff473231a842e Mon Sep 17 00:00:00 2001 From: jelveh Date: Thu, 1 Oct 2026 22:19:44 -0700 Subject: [PATCH] Don't pull focus back into the toolbar when the host page closes its menu Clicking a host text field while a toolbar menu was open closed the menu and then refocused the toolbar button, so the host field lost focus and typing went nowhere. Focus is now restored only while the toolbar document has it. --- .../src/UI/Dashboard/AppBrowser.browser.test.js | 16 ++++++++++++++++ src/gui/src/toolbarEmbed.js | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/gui/src/UI/Dashboard/AppBrowser.browser.test.js b/src/gui/src/UI/Dashboard/AppBrowser.browser.test.js index f80afcde5..5660ec3b7 100644 --- a/src/gui/src/UI/Dashboard/AppBrowser.browser.test.js +++ b/src/gui/src/UI/Dashboard/AppBrowser.browser.test.js @@ -267,6 +267,22 @@ describe('embedded toolbar', () => { } finally { await context.close(); } }); + it('leaves focus on the host page that closed the menu, and returns it to the toggle on Escape', async () => { + const { context, page, toolbar } = await openToolbar(); + try { + await toolbar.getByRole('button', { name: 'Account', exact: true }).click(); + await toolbar.locator('.toolbar-panel').waitFor(); + await page.locator('#outside').click(); + await toolbar.locator('.toolbar-panel').waitFor({ state: 'detached' }); + await page.waitForTimeout(100); + expect(await page.evaluate(() => document.activeElement.id)).toBe('outside'); + await toolbar.getByRole('button', { name: 'Account', exact: true }).click(); + await toolbar.locator('.toolbar-close').press('Escape'); + await toolbar.locator('.toolbar-panel').waitFor({ state: 'detached' }); + expect(await toolbar.locator('body').evaluate(() => document.activeElement.dataset.panel)).toBe('account'); + } finally { await context.close(); } + }); + it('labels controls with translated text encoded once', async () => { const { context, toolbar } = await openToolbar(undefined, sessionToken, [{ name: 'user_preferences', value: '{"language":"de"}' }]); try { diff --git a/src/gui/src/toolbarEmbed.js b/src/gui/src/toolbarEmbed.js index 8d80c7459..3dff7ad95 100644 --- a/src/gui/src/toolbarEmbed.js +++ b/src/gui/src/toolbarEmbed.js @@ -50,7 +50,8 @@ function closePanel () { panel = null; $root.find('.toolbar-panel').remove(); $root.find('[aria-expanded]').attr('aria-expanded', 'false'); - if ( previous ) $root.find(`[data-panel="${previous}"]`)[0]?.focus({ preventScroll: true }); + // A close the host started by focusing its own page must not pull focus back. + if ( previous && document.hasFocus() ) $root.find(`[data-panel="${previous}"]`)[0]?.focus({ preventScroll: true }); notify('panel', { panel }); }