Skip to content

Conversation

@BenHenning
Copy link
Collaborator

@BenHenning BenHenning commented Jun 27, 2025

The basics

The details

Resolves

Fixes #9106
Fixes #9122

Proposed Changes

This ensures Flyout doesn't close when it shouldn't (i.e. when creating or renaming variables).

Reason for Changes

The main issue is that the window prompt takes focus away from Blockly entirely, so ephemeral focus is now being used for variable creation and renaming to restore focus back to the original node.

However, that's not a complete solution since creating a variable causes the flyout to fully be laid out again. As a result, there's no trivial way to track and restore focus back to the element that had held focus previously (or to use the ephemerally-restored focus to even realize that focus should be restored). To make this work reasonably well, when the Flyout is re-laid out it will now check if it had focus before and, if it did, will focus the first new element it creates after being relaid out. It's not a perfect solution, but it seems like a reasonable medium or long-term solution.

Test Coverage

TODO: Tests need to be added yet.

Documentation

No new documentation changes should be needed.

Additional Information

Note that this PR is not production ready yet as it completely disables auto-flyout closing. The main issue here is that there's a moment either due to the prompt or due to elements with focus being deleted that eventually lead to the flyout's workspace being blurred and attempts to restore focus after that completely fail since it's been closed and the nodes no longer exist. It's unclear at the moment how to solve this problem.

This isn't a complete solution, but is a decent start toward one. It
also builds resilience into Flyout itself for recreation cases.
@github-actions github-actions bot added the PR: fix Fixes a bug label Jun 27, 2025
@maribethb
Copy link
Contributor

@BenHenning this is a quite old draft, do you plan on updating this to be able to get it merged before the user testing deadline?

@github-actions github-actions bot added PR: fix Fixes a bug and removed PR: fix Fixes a bug labels Dec 8, 2025
@BenHenning
Copy link
Collaborator Author

@BenHenning this is a quite old draft, do you plan on updating this to be able to get it merged before the user testing deadline?

For posterity we're trying to figure out whether this is an actual blocker for January testing, though it would be nice to find a solution.

To that end I have investigated this more and found that it's very much still an issue. I was wondering a bit whether #9245 might affect this because it changed a bit with auto hiding behavior, but the alert dialog situation is still very much broken.

Fundamentally what's happening here is that the browser seems to send a focusout event asynchronously after execution resumes when the dialog is closed. This produces a rather tricky situation because it's not clear how long (or if to ever) to ignore signals of lost focus after the dialog closes. From discussion in the team meeting this week, one option was to replace alert() and other system dialogs with a custom implementation (like we use for toast now) since that could be advantageous long-term and adds some UI and accessibility consistency. This leads to two overall solutions with separate problems:

  1. Introduce custom modals for alert(), prompt(), and confirm().
  • This will require central DOM management unlike toasts because there's no way to get the workspace without breaking the existing API (otherwise this is a breaking v13 change).
  • Input needs to somehow be blocked for both mouse and keyboard users while the new dialogs are open. This requires a combination of a full-screen translucent overlay that blocks mouse inputs with manually disabling key inputs.
  • There are some questions about to best style these, but this isn't particularly difficult to address.
  1. Build a mechanism that attempts to robustly ignore the focusout event that triggers when the system dialog closes.
  • A likely approach would be to introduce some sort of release latch mechanism that essentially disables interpreting focusout events until after receiving exactly the first one after a dialog closes (taking into account that explicit focus changes may also trigger a focusout).
  • One fundamental problem is it isn't guaranteed that all browsers will have the same focus issues for system dialogs.
  • AI suggested using requestAnimationFrame to try and predict a good time to release the latch, but this has a flaw in certain contexts as discovered in fix: CI tests on OS X blockly-keyboard-experimentation#770. It's not guaranteed when (or if in some cases) the callback for requestAnimationFrame will be called.
  • AI suggested using setTimeout in conjunction with requestAnimationFrame to try and guard against all scenarios. This might work, but it will be challenging to get everything properly wired.

Both approaches are non-trivial and will require a lot of multi-browser and multi-screenreader testing to feel good about them.

@BenHenning
Copy link
Collaborator Author

Actually based on the above message I am going to close this and update #9122 accordingly.

@BenHenning BenHenning closed this Dec 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: fix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Creating a variable closes the flyout 'Create variable' with keyboard navigation doesn't restore focus correctly

2 participants