diff --git a/core/toolbox/toolbox.ts b/core/toolbox/toolbox.ts index f34034d3399..6f4daf4ed71 100644 --- a/core/toolbox/toolbox.ts +++ b/core/toolbox/toolbox.ts @@ -108,6 +108,9 @@ export class Toolbox /** The workspace this toolbox is on. */ protected readonly workspace_: WorkspaceSvg; + /** Whether the mouse is currently being clicked. */ + private mouseDown = false; + /** @param workspace The workspace in which to create new blocks. */ constructor(workspace: WorkspaceSvg) { super(); @@ -243,6 +246,16 @@ export class Toolbox ); this.boundEvents_.push(clickEvent); + const mouseUpEvent = browserEvents.bind( + container, + 'pointerup', + this, + () => { + this.mouseDown = false; + }, + ); + this.boundEvents_.push(mouseUpEvent); + const keyDownEvent = browserEvents.conditionalBind( contentsContainer, 'keydown', @@ -259,6 +272,7 @@ export class Toolbox * @param e Click event to handle. */ protected onClick_(e: PointerEvent) { + this.mouseDown = true; if (browserEvents.isRightButton(e) || e.target === this.HtmlDiv) { // Close flyout. (common.getMainWorkspace() as WorkspaceSvg).hideChaff(false); @@ -1134,7 +1148,10 @@ export class Toolbox ): void { if (node !== this) { // Only select the item if it isn't already selected so as to not toggle. - if (this.getSelectedItem() !== node) { + // Also require that the mouse not be down, i.e. that the focusing of + // the toolbox was keyboard-driven, to avoid opening the flyout when + // clicking on an empty part of the toolbox. + if (this.getSelectedItem() !== node && !this.mouseDown) { this.setSelectedItem(node as IToolboxItem); } } else { diff --git a/tests/browser/test/toolbox_drag_test.mjs b/tests/browser/test/toolbox_drag_test.mjs index 66b74d9e2c5..5687febbb83 100644 --- a/tests/browser/test/toolbox_drag_test.mjs +++ b/tests/browser/test/toolbox_drag_test.mjs @@ -207,4 +207,13 @@ suite('Open toolbox categories', function () { ); await openCategories(this.browser, testCategories, screenDirection.RTL); }); + + test('clicking the toolbox itself does not open the flyout', async function () { + this.browser = await testSetup(testFileLocations.PLAYGROUND); + await this.browser.$('.blocklyToolbox').click(); + const flyoutOpen = await this.browser.execute(() => { + return Blockly.getMainWorkspace().getFlyout().isVisible(); + }); + chai.assert.isFalse(flyoutOpen); + }); });