diff --git a/src/actions/move.ts b/src/actions/move.ts index 415fe40c..cc13ce23 100644 --- a/src/actions/move.ts +++ b/src/actions/move.ts @@ -7,6 +7,7 @@ import { BlockSvg, ContextMenuRegistry, + FocusManager, Msg, ShortcutRegistry, utils, @@ -25,6 +26,13 @@ const createSerializedKey = ShortcutRegistry.registry.createSerializedKey.bind( * Actions for moving blocks with keyboard shortcuts. */ export class MoveActions { + /** + * Stored to enable us to restore monkey patch. + */ + private oldShortcutRegistryOnKeyDown: + | typeof ShortcutRegistry.registry.onKeyDown + | null = null; + constructor(private mover: Mover) {} private shortcutNames: string[] = []; @@ -189,6 +197,42 @@ export class MoveActions { install() { this.registerShortcuts(); this.registerMenuItems(); + + // Monkey patch shortcut registry to: finish any in-progress move for all + // non-move-related actions and bail on actions other than "escape" during + // ephemeral focus. + this.oldShortcutRegistryOnKeyDown = ShortcutRegistry.registry.onKeyDown; + ShortcutRegistry.registry.onKeyDown = (workspace, e) => { + if (!this.oldShortcutRegistryOnKeyDown) return false; + // @ts-expect-error private method + const key = ShortcutRegistry.registry.serializeKeyEvent(e); + const shortcutNamesForKey = + ShortcutRegistry.registry.getShortcutNamesByKeyCode(key); + if ( + !this.shortcutNames.some((moveShortcutName) => + shortcutNamesForKey?.includes(moveShortcutName), + ) + ) { + if (this.mover.isMoving(workspace)) { + this.mover.finishMove(workspace); + } + } + + // @ts-expect-error private method + const {currentlyHoldsEphemeralFocus} = FocusManager.getFocusManager(); + if ( + currentlyHoldsEphemeralFocus && + !shortcutNamesForKey?.includes('escape') + ) { + return false; + } + + return this.oldShortcutRegistryOnKeyDown.call( + ShortcutRegistry.registry, + workspace, + e, + ); + }; } /** @@ -201,6 +245,10 @@ export class MoveActions { for (const menuItem of this.menuItemNames) { ContextMenuRegistry.registry.unregister(menuItem); } + + if (this.oldShortcutRegistryOnKeyDown) { + ShortcutRegistry.registry.onKeyDown = this.oldShortcutRegistryOnKeyDown; + } } /**