From c12349d632714b9f210714188b93d91afc27c05c Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 16 Mar 2026 15:07:18 -0700 Subject: [PATCH 1/3] feat: Beep when attempting constrained move on top-level block --- packages/blockly/core/dragging/block_drag_strategy.ts | 1 + packages/blockly/tests/mocha/keyboard_movement_test.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index 39dff646ec2..c015ffc4f5a 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -380,6 +380,7 @@ export class BlockDragStrategy implements IDragStrategy { if (this.moveMode === MoveMode.CONSTRAINED) { showUnconstrainedMoveHint(this.workspace, true); + this.workspace.getAudioManager().beep(260); } } } diff --git a/packages/blockly/tests/mocha/keyboard_movement_test.js b/packages/blockly/tests/mocha/keyboard_movement_test.js index 9d6ac0cdddf..0dec798d91c 100644 --- a/packages/blockly/tests/mocha/keyboard_movement_test.js +++ b/packages/blockly/tests/mocha/keyboard_movement_test.js @@ -531,9 +531,10 @@ suite('Keyboard-driven movement', function () { testExemptedShortcutsAllowed(); }); - suite('in constrained mode', function () { + suite.only('in constrained mode', function () { test('prompts to use unconstrained mode when no destinations are available', function () { const toastSpy = sinon.spy(Blockly.Toast, 'show'); + const beepSpy = sinon.spy(this.workspace.getAudioManager(), 'beep'); Blockly.getFocusManager().focusNode(this.element); const originalBounds = this.element.getBoundingRectangle(); startMove(this.workspace); @@ -547,6 +548,8 @@ suite('Keyboard-driven movement', function () { ? 'Hold ⌘ Command and use arrow keys to move freely, then Enter to accept the position' : 'Hold Ctrl and use arrow keys to move freely, then Enter to accept the position', ); + sinon.assert.calledOnce(beepSpy); + beepSpy.restore(); toastSpy.restore(); }); From 5316182fdc6626eb640693e46c46862ebff3eb49 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 16 Mar 2026 15:08:35 -0700 Subject: [PATCH 2/3] chore: Remove errant `only` --- packages/blockly/tests/mocha/keyboard_movement_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blockly/tests/mocha/keyboard_movement_test.js b/packages/blockly/tests/mocha/keyboard_movement_test.js index 0dec798d91c..8374699eac1 100644 --- a/packages/blockly/tests/mocha/keyboard_movement_test.js +++ b/packages/blockly/tests/mocha/keyboard_movement_test.js @@ -531,7 +531,7 @@ suite('Keyboard-driven movement', function () { testExemptedShortcutsAllowed(); }); - suite.only('in constrained mode', function () { + suite('in constrained mode', function () { test('prompts to use unconstrained mode when no destinations are available', function () { const toastSpy = sinon.spy(Blockly.Toast, 'show'); const beepSpy = sinon.spy(this.workspace.getAudioManager(), 'beep'); From 138cfaae7c85309258721d1e2631bc4c6b60c3b9 Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Wed, 18 Mar 2026 12:41:04 -0700 Subject: [PATCH 3/3] refactor: Add and use `playErrorBeep()` --- packages/blockly/core/dragging/block_drag_strategy.ts | 2 +- packages/blockly/core/workspace_audio.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index c015ffc4f5a..b017eaf56fb 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -380,7 +380,7 @@ export class BlockDragStrategy implements IDragStrategy { if (this.moveMode === MoveMode.CONSTRAINED) { showUnconstrainedMoveHint(this.workspace, true); - this.workspace.getAudioManager().beep(260); + this.workspace.getAudioManager().playErrorBeep(); } } } diff --git a/packages/blockly/core/workspace_audio.ts b/packages/blockly/core/workspace_audio.ts index 7d27277a0ce..66d555cd44b 100644 --- a/packages/blockly/core/workspace_audio.ts +++ b/packages/blockly/core/workspace_audio.ts @@ -138,6 +138,13 @@ export class WorkspaceAudio { oscillator.stop(this.context.currentTime + duration); } + /** + * Plays a standard error beep. + */ + async playErrorBeep() { + return this.beep(260); + } + /** * Returns whether or not playing sounds is currently allowed. *