Skip to content

Add keyboard locking option#232

Merged
foolip merged 21 commits intowhatwg:mainfrom
marcoscaceres:keyboard_lock
May 8, 2026
Merged

Add keyboard locking option#232
foolip merged 21 commits intowhatwg:mainfrom
marcoscaceres:keyboard_lock

Conversation

@marcoscaceres
Copy link
Copy Markdown
Member

@marcoscaceres marcoscaceres commented Dec 6, 2023

Introduce a dictionary member keyboardLock to requestFullscreen(options) to request keyboard lock together with fullscreen.

Fixes #231

(See WHATWG Working Mode: Changes for more details.)


💥 Error: 422 Unprocessable Entity 💥

PR Preview failed to build. (Last tried on May 8, 2026, 9:36 AM UTC).

More

PR Preview relies on a number of web services to run. There seems to be an issue with the following one:

🚨 Spec Generator - Spec Generator is the web service used to build bikeshed/ReSpec specs

🔗 Related URL

Error output:

[
    {
        "lineNum": "114:35",
        "messageType": "link",
        "text": "Multiple possible 'removing steps' dfn refs.\nArbitrarily chose https://dom.spec.whatwg.org/#concept-node-remove-ext\nTo auto-select one of the following refs, insert one of these lines into a <pre class=link-defaults> block:\nspec:dom; type:dfn; text:removing steps\nspec:geolocation-element; type:dfn; for:ActivationBlockersMixin; text:removing steps\nspec:geolocation-element; type:dfn; for:HTMLGeolocationElement; text:removing steps\nspec:geolocation-element; type:dfn; for:PowerfulFeatureObserver; text:removing steps\n<a bs-line-number=\"114:35\" data-link-type=\"dfn\" data-lt=\"removing steps\">removing steps</a>"
    },
    {
        "lineNum": null,
        "messageType": "failure",
        "text": "Did not generate, due to errors exceeding the allowed error level."
    }
]

This seems to be an issue with the Spec Generator service. PR Preview doesn't manage this service and so has no control over it. If you've identified an issue with it, you can report the issue to the maintainers of Spec Generator directly. Please be courteous. Thank you!

If you don't have enough information above to solve the error by yourself or if the issue doesn't seem related to Spec Generator, you can file an issue with PR Preview.

@marcoscaceres marcoscaceres mentioned this pull request Dec 6, 2023
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Copy link
Copy Markdown

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty good. Some suggestions.

Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs
<p>Users should be clearly notified when [=keyboard locking=] is active, possibly through browser
UI indicators.

<p>There should be a simple and intuitive method for users to override keyboard locking, reverting
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be really nice if we could standardize this. That way, the experience is consistent across browsers.

I don't regard this as essential, but it would be nice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree... though this might need to happen after browsers ship something and if we all align. I guess it would be a SHOULD (or even MAY) level thing. History suggests that we will naturally converge on a UI/UX convention for this.

@mdevaev
Copy link
Copy Markdown

mdevaev commented Nov 27, 2025

Hello. Please forgive me for impudently and unceremoniously barging in :)

WebKit has recently received an implementation of Mozilla's proposal, and apparently at some point it will reach Safari and other browsers: https://bugs.webkit.org/show_bug.cgi?id=264843

As a developer of a web-based for remote access device, I'm super-interested in this feature because it's the only blocker that prevents me from recommending Firefox instead of Chrome to my clients.

I hope that if this specification is adopted, then eventually things will get off the ground, and it will be done in Firefox too. Considering that we already have an actual implementation, and if there are no problems here, is it worth merging this PR? It looks great.

@lukewarlow
Copy link
Copy Markdown
Member

Per https://webkit.org/blog/17674/release-notes-for-safari-technology-preview-234/ I believe this has shipped in Safari TP. It would be good to check how accurate the spec PR is compared to the implementation and try to get it across the line now there's some implementation interest.

@marcoscaceres marcoscaceres marked this pull request as ready for review January 19, 2026 05:41
@marcoscaceres
Copy link
Copy Markdown
Member Author

marcoscaceres commented Jan 19, 2026

Ok, had a look. the WebKit PR does follow the spec. The only thing is that the tests that were added use WebKit infrastructure, but I think they could be migrated to be fullscreen tests... assuming we can lock and we all generally agree that hitting "ESC" once shouldn't cause fullscreen to cancel if the lock if applied (this might be hard to test across UAs... but we can try).

In the meantime we need interest from a second implementer.

@mdevaev
Copy link
Copy Markdown

mdevaev commented Jan 19, 2026

As a developer, I would like to note that there is exactly one problem with the current draft/implementation: it is impossible to check the presence or absence of keyboardLock support on the target browser without having to call requestFullscreen(). There is no any flag or property that we could use for this. And even after the call, the code does not know whether it intercepts all key events.

If this is not supported, it would be great to be able to distinguish between these states to alert the user who expects all his keys to be intercepted.

It might not be too late to add something for that.

Comment thread fullscreen.bs
Comment thread fullscreen.bs Outdated
Copy link
Copy Markdown
Member

@saschanaz saschanaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on above.

@saschanaz
Copy link
Copy Markdown
Member

I'm concerned that Safari would ship with something nobody agreed on, without an updated PR. If @marcoscaceres is busy I can take this and update it. (In that case I'll exclude system lock mode.)

Comment thread fullscreen.bs
@saschanaz
Copy link
Copy Markdown
Member

saschanaz commented Feb 23, 2026

I'm starting to think that all we need for keyboardLock: "browser" is to make the escape key not immediately escape fullscreen. Do we even need to call it "keyboard lock" in that case?

(Because browser shortcuts are already preventDefault-able.)

@martinthomson
Copy link
Copy Markdown

Are you suggesting that sites looking to avoid things like tab switching have some enumeration of all browser shortcuts and just .preventDefault() on all of them? Isn't there at least some value in having that done for them?

@saschanaz
Copy link
Copy Markdown
Member

Are you suggesting that sites looking to avoid things like tab switching have some enumeration of all browser shortcuts and just .preventDefault() on all of them? Isn't there at least some value in having that done for them?

(TIL Firefox and Chrome even allow that...)

But anyway that's what Safari is going to ship now - there's no "bypass" as this PR says, all it does is to prevent the escape key to not immediately escape the fullscreen mode. There's no even extra capture for shortcuts, it turns out that both Safari and Chrome already allow the page to capture extra browser shortcuts on fullscreen mode that Firefox currently does not.

And I do think it may indeed be easier to just prevent-default those shortcuts in keyboard lock mode, but I'm not sure preventing all shortcuts is a great idea. Is Control+C a browser shortcut to prevent, for example? What is the definition of "browser shortcuts that we want to prevent" here?

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented Apr 15, 2026

Since Safari has shipped, the cost of tweaking the API is higher now. I think we should keep the "none" and "browser" enums, but drop "system".

It should be up to the UA to decide which keys are reserved with keyboard lock active (and when not active).

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented Apr 15, 2026

Adding Gecko as interested implementer (see https://bugzilla.mozilla.org/show_bug.cgi?id=700123).

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented Apr 15, 2026

As a developer, I would like to note that there is exactly one problem with the current draft/implementation: it is impossible to check the presence or absence of keyboardLock support on the target browser without having to call requestFullscreen(). There is no any flag or property that we could use for this. And even after the call, the code does not know whether it intercepts all key events.

If this is not supported, it would be great to be able to distinguish between these states to alert the user who expects all his keys to be intercepted.

It might not be too late to add something for that.

It's possible to feature-check that the keyboardLock dictionary member is supported without going fullscreen like this: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/14660

This doesn't tell you whether a particular value is supported until actually going fullscreen, though. This step:

If FullscreenOptions 's keyboardLock 's value is not supported, reject promise with a NotSupportedError exception and terminate these steps.

Runs after rejecting when |error| is true, so you can only tell that the value is supported by going fullscreen with requesting keyboardLock (and checking that the dictionary member is supported first, since unknown dictionary members are silently ignored).

While this method of checking dictionary members has been deemed sufficient for feature-checking in some cases, I could be convinced that it's not ideal DX and there should be a property similar to document.fullscreenEnabled (e.g. document.keyboardLockEnabled) to allow easy feature-checking and easy checking if keyboard lock is currently active. (If we drop system then this becomes a boolean.)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Comment thread fullscreen.bs Outdated
Comment thread fullscreen.bs Outdated
Copy link
Copy Markdown
Member

@foolip foolip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed a problem and am wondering about the more general idea with nested fullscreen scenarios. In both "requestFullscreen(options) method steps" and the "exit fullscreen" algorithm, the flag is only set/unset on a single element. But in nested scenarios, there's no guarantee that those elements are the same. Consider this simple case:

elm1.onclick = () => { elm1.requestFullscreen({ keyboardLock: "browser" }); }
elm2.onclick = () => { elm2.requestFullscreen(); }

If the elements are clicked in order and later something triggers "fully exit fullscreen", the keyboard lock flag will remain set on elm1.

Comment thread fullscreen.bs Outdated
@foolip
Copy link
Copy Markdown
Member

foolip commented May 5, 2026

How should this interact with the navigator.keyboard.lock() API?

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented May 5, 2026

I noticed a problem and am wondering about the more general idea with nested fullscreen scenarios. In both "requestFullscreen(options) method steps" and the "exit fullscreen" algorithm, the flag is only set/unset on a single element. But in nested scenarios, there's no guarantee that those elements are the same. Consider this simple case:

elm1.onclick = () => { elm1.requestFullscreen({ keyboardLock: "browser" }); }
elm2.onclick = () => { elm2.requestFullscreen(); }

If the elements are clicked in order and later something triggers "fully exit fullscreen", the keyboard lock flag will remain set on elm1.

No it won't, because fully exit fullscreen calls #unfullscreen-an-element on all fullscreened elements which unsets the keyboard lock flag.

It's true that "exit fullscreen" for elm2 in your example will change the fullscreen element to elm1 and then keyboard lock is active again; this is intentional.

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented May 5, 2026

How should this interact with the navigator.keyboard.lock() API?

For Gecko, the plan is to not support that API.

@foolip
Copy link
Copy Markdown
Member

foolip commented May 6, 2026

Can someone prepare the WPT PR so we can merge spec and tests together?

@foolip
Copy link
Copy Markdown
Member

foolip commented May 6, 2026

@marcoscaceres WDYT about interaction with the keyboard lock API for browsers that support both?

@saschanaz
Copy link
Copy Markdown
Member

Can someone prepare the WPT PR so we can merge spec and tests together?

As listed in the OP, it already exists.

@saschanaz
Copy link
Copy Markdown
Member

saschanaz commented May 6, 2026

@foolip does Google have thoughts about usefulness of this API? One of my concerns is that, given browser shortcuts are already locked on fullscreen without keyboard lock on Safari and Chrome, people will not care about this API unless they care about Escape key behavior.

Edit: And the same question also applies to Blink's navigator.keyboard.lock, to me the API looks much less useful now compared to when it was introduced, because of the same reasons above.

@foolip
Copy link
Copy Markdown
Member

foolip commented May 6, 2026

Can someone prepare the WPT PR so we can merge spec and tests together?

As listed in the OP, it already exists.

Yes, but "PR for to move to non-tentative TODO"

Comment thread fullscreen.bs
Comment thread fullscreen.bs

<p>User agents should reserve an additional input for the purposes of exiting fullscreen. There are
also some system-level key sequences or combinations that cannot be intercepted for security
reasons, such as Ctrl+Alt+Del on Windows.
Copy link
Copy Markdown
Member

@saschanaz saschanaz May 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add implementation note somewhere around here? Something like:

For example, browsers that use Esc key for exiting fullscreen use keyboard lock to prevent immediate exit on key press, and instead require longer press to exit fullscreen. Some of such implementations also implicitly grant partial keyboard lock to fullscreen session, in that case Esc key may be the only key that is affected with explicit keyboard lock. See also #260.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added that with some light edits like browser → user agent.

@marcoscaceres are you happy with this addition?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcoscaceres I'll go ahead and merge this, but if you want changes later just file a new issue or PR.

@foolip
Copy link
Copy Markdown
Member

foolip commented May 7, 2026

@foolip does Google have thoughts about usefulness of this API? One of my concerns is that, given browser shortcuts are already locked on fullscreen without keyboard lock on Safari and Chrome, people will not care about this API unless they care about Escape key behavior.

Edit: And the same question also applies to Blink's navigator.keyboard.lock, to me the API looks much less useful now compared to when it was introduced, because of the same reasons above.

I'm reviewing this as spec editor and am not planning to implement anything myself, so no implementer interest from Google. But that isn't needed process wise since Apple and Mozilla do want this change.

That being said, given how "declarative" this API is I think it should be possible to define it in terms of the keyboard lock API later if we want to do that, or at the very least define how they interact. But to figure that out really requires an attempt to implement this, I think.

@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented May 7, 2026

Can someone prepare the WPT PR so we can merge spec and tests together?

Done.

lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request May 8, 2026
…en exiting one level of fullscreen, a=testonly

Automatic update from web-platform-tests
Fullscreen: keyboard lock is restored when exiting one level of fullscreen

See whatwg/fullscreen#232

--

wpt-commits: 298f30b75db03f20ab25a74b945efb43ad6db2ee
wpt-pr: 59451
@zcorpan zcorpan closed this May 8, 2026
@zcorpan zcorpan reopened this May 8, 2026
@zcorpan
Copy link
Copy Markdown
Member

zcorpan commented May 8, 2026

I think this is ready to land. CI checks are green now also.

@foolip foolip merged commit 6b688fb into whatwg:main May 8, 2026
2 of 4 checks passed
foolip pushed a commit to web-platform-tests/wpt that referenced this pull request May 8, 2026
fmasalha pushed a commit to fmasalha/firefox that referenced this pull request May 8, 2026
…en exiting one level of fullscreen, a=testonly

Automatic update from web-platform-tests
Fullscreen: keyboard lock is restored when exiting one level of fullscreen

See whatwg/fullscreen#232

--

wpt-commits: 298f30b75db03f20ab25a74b945efb43ad6db2ee
wpt-pr: 59451
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Keyboard lock

9 participants