From cfd48fddbe3a5f0a0f846931a3b13cda7f99378a Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Sat, 14 Oct 2023 13:18:59 -0400 Subject: [PATCH] Fix some keyboard inputs not being read by Bevy --- studio-frontend/src/app/app.element.ts | 27 +++++++++++++++++++++++ studio-frontend/src/app/button.element.ts | 6 +++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index 41acf99..8d14d5e 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -41,6 +41,33 @@ export class AppElement extends LitElement { studio.resize(new ViewportSize(width, height)); } + @on("keydown") + @on("keyup") + pipeKeyboardEvents(event: KeyboardEvent): void { + // When the user interacts with one of the web UI elements, the Bevy + // canvas will lose focus, preventing it from receiving keyboard events. + // As a workaround, we can listen for any events that have bubbled up to + // the app root and repeat them for the canvas. + // + // This does unfortunately burden the web front-end with some additional + // responsibility: when we handle a keyboard event and _don't_ want the + // Bevy app to receive it, we'll need to call `event.stopPropagation()` in + // the handler to prevent it from reaching this listener. + const { + type, + code, charCode, key, keyCode, location, repeat, + altKey, ctrlKey, metaKey, shiftKey, + } = event; + + this.#studioCanvas?.dispatchEvent(new KeyboardEvent(type, { + code, charCode, key, keyCode, location, repeat, + altKey, ctrlKey, metaKey, shiftKey, + bubbles: true, + cancelable: true, + composed: true, + })); + } + toggleHelp(): void { this.showHelp = !this.showHelp; } diff --git a/studio-frontend/src/app/button.element.ts b/studio-frontend/src/app/button.element.ts index 1328b84..080d9c9 100644 --- a/studio-frontend/src/app/button.element.ts +++ b/studio-frontend/src/app/button.element.ts @@ -14,9 +14,11 @@ export class ButtonElement extends LitElement { override tabIndex = 0; @on("keydown") - onKeyDown({ key }: KeyboardEvent) { - if (/^( |Enter)$/.test(key)) + onKeyDown(event: KeyboardEvent) { + if (/^( |Enter)$/.test(event.key)) { + event.stopPropagation(); this.click(); + } } protected override render = () => html`