Skip to content

Guard against double activation of buttons on Enter key - #178

Open
devin-ai-integration[bot] wants to merge 1 commit into
bugfix/tv-remotefrom
devin/1787851470-tv-enter-double-activation
Open

Guard against double activation of buttons on Enter key#178
devin-ai-integration[bot] wants to merge 1 commit into
bugfix/tv-remotefrom
devin/1787851470-tv-enter-double-activation

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Now targets bugfix/tv-remote (#167), which already fixes the reported TV Enter/OK flicker by dropping the synthesized focusedChild.click() from UIContainer._onTvKeyDown. This adds one layer of defence on top of that, in Button itself, so a single activation key press can never invoke handleClick() twice regardless of who turns the key press into a click (the TV container, a browser's default action for Enter, or a remote's OK button):

 private readonly _onClick = () => {
+    this._clickedDuringKeyPress = true;
     this.handleClick();
 };

 _onKeyDown: if (isActivationKey(...)) {
+    this._clickedDuringKeyPress = false;
     addEventListener('keyup', ...)
 }

-_onKeyUp: if (isActivationKey(e.keyCode))
+_onKeyUp: if (isActivationKey(e.keyCode) && !this._clickedDuringKeyPress)
     this.handleClick();

The flag is reset when an activation key press starts, so keyup-only activation (the normal keyboard path, and any device whose OK key does not produce a click) is unaffected — it only suppresses the keyup activation when a click for the same key press already ran.

Verified in a browser with an instrumented harness before the rebase onto #167: one Enter press in device-type="tv" produced exactly one activation, the pre-fix double activation reproduced on main (two activations ~19 ms apart), and mouse/Space/Enter in desktop mode each activated once. Results and screenshots are in a comment below.

Link to Devin session: https://dolby.devinenterprise.com/sessions/7430bc65b800408a8e7989fa73f70548
Open in Devin Desktop: https://dolby.devinenterprise.com/desktop/session/7430bc65b800408a8e7989fa73f70548?variant=devin
Requested by: @jpestugia

@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@changeset-bot

changeset-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7485f7b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@theoplayer/web-ui Minor
@theoplayer/react-ui Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration

Copy link
Copy Markdown
Author

Runtime test results (Devin)

Tested the built UI in a desktop browser with an instrumented harness that logs play/pause/volumechange player events, shadow-DOM click events, keydown/keyup with the focused element path, and a per-keypress activation counter — a visual-only check would miss the ~19 ms double toggle.

TV mode (device-type="tv"): one activation per Enter press
Control Result
Play button (pause) ✅ 1 click, 1 pause, no keyup activation
Play button (resume) ✅ 1 click, 1 play
Mute button ✅ mute toggled exactly once
Settings menu button ✅ menu opens and stays open (no open-and-close)
Quality submenu + radio item ✅ each activates once; selection applied once
Fullscreen button ✅ enter once, exit once
Arrow-key focus navigation ✅ unchanged

Fix build: TV Enter pauses exactly once

Fix build: settings menu opens on Enter and stays open

Pre-fix reproduction on main

One Enter press on the TV play button produced two activations — the synthesized keydown click (pause) followed 19 ms later by the keyup activation (play), i.e. the reported flicker. Counter read activations since last key: 2.

Pre-fix main: two activations for one Enter

Regression: non-TV (desktop) UI
  • ✅ Mouse click on play: 1 click, 1 play event
  • ✅ Space on focused play button: 1 activation, 1 pause event
  • ✅ Enter on focused play button: 1 activation, 1 play event — the new _clickedDuringKeyPress flag does not swallow the only activation outside TV mode

Desktop Enter: exactly one activation

The harness pages, second build directory and test plan used for this run are local-only and are not part of this branch.

Written by Devin

@MattiasBuelens

Copy link
Copy Markdown
Collaborator

I am pretty sure I already fixed this in #167... specifically db711a8.

Would you mind reviewing and landing that PR first, and see if this is still needed?

@devin-ai-integration

Copy link
Copy Markdown
Author

@MattiasBuelens You're right — db711a8 removes the synthesized focusedChild.click() from _onTvKeyDown entirely, which kills the same double activation at the other end (only Button's keydown/keyup path remains). So #167 makes this PR redundant; happy to close it in favour of landing #167.

The only reason I fixed it in Button instead of removing the synthetic click is a hypothesis I haven't verified: that some older TV browsers don't deliver a usable keyup for the OK key, in which case Button's keyup-only activation would leave the UI unresponsive on those devices, whereas the flag in Button keeps the synthetic click working. If you already know keyup is reliable on the devices you care about, #167 is the cleaner fix and this can be dropped. If you'd rather be belt-and-braces, the _clickedDuringKeyPress guard also protects against a browser dispatching its own click for Enter, and applies cleanly on top of #167.

Your call — let me know and I'll either close this or rebase it onto #167.

@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1787851470-tv-enter-double-activation branch 2 times, most recently from b6b8731 to 802056e Compare August 27, 2026 18:10
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1787851470-tv-enter-double-activation branch from 802056e to 7485f7b Compare August 27, 2026 18:10
@devin-ai-integration
devin-ai-integration Bot changed the base branch from main to bugfix/tv-remote August 27, 2026 18:10
@devin-ai-integration devin-ai-integration Bot changed the title Fix double activation of buttons on Enter key Guard against double activation of buttons on Enter key Aug 27, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

Retargeted this at bugfix/tv-remote (#167) and reduced it to just the Button guard, so #167 stays the actual fix and this is only defence in depth on top of it (one activation key press can't invoke handleClick() twice, whoever synthesizes the click). The diff against #167 is now 2 files: src/components/Button.ts + a changeset.

If you'd rather not carry the extra state in Button, feel free to close this — #167 alone resolves the reported flicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants