toji / chrome-webvr-issues

Stub repository for tracking bugs related to Chrome's experimental WebVR support
53 stars 12 forks source link

requestPresent is rejected when call in a promise trigered by a user gesture #129

Closed ortollag closed 6 years ago

ortollag commented 7 years ago

If I trigger the followoling fonction by a user gesture, requestPresent is rejected.

function() { navigator.getVRDisplays().then((displays)=>{ var hmd = displays[0]; hmd.requestPresent([{source:canvas}]); return hmd; }); } //there may be errors in the previous code, I wrote just to summarize the pb.

It should be possible to retrieve a VRDisplay (by calling navigator.getVRDisplays) only at the time we need it (and not exclusively when page loads). And generally we need it when we begin presenting.

cvan commented 7 years ago

Can you show the rest of your code? Would help to see where your listener/handler is getting attached.

matthias-w commented 7 years ago

I agree to @ortollag. This is really an issue, but it seems to be not Chrome specific. It could be a more fundamental problem. As far as I understand, the problem is that VRDisplay.requestPresent has to be called synchronously. Otherwise the following error appears in Chrome (FF Nightly just says uncaught exception: undefined)

API can only be initiated by a user gesture

This also happens when the call is a direct result of a user gesture, such as a click on a button, i.e. my_button.onclick = () => setTimeout(VRDisplay.requestPresent)

Though the WebVR specification says

> (requestPresent) Must be called in response to a user gesture

my expectation would be that also an asynchrounous call triggered by a user gesture is valid.

What do you think?

capnmidnight commented 7 years ago

Well, I think part of the problem here is that a user gesture is specifically defined as only synchronous calls from an event handler for touchend, mousedown, mouseup, keydown, and keyup. There is also a VRDisplay::onactivate event defined in the spec that would also serve as a user gesture, but it's not widely available yet.

This also happens when the call is a direct result of a user gesture, such as a click on a button, i.e. my_button.onclick = () => setTimeout(VRDisplay.requestPresent)

Yes, the expected behavior here is for requestPresent--or any other user-gesture-requiring API call such as requestFullScreen or getUserMedia--to fail.

matthias-w commented 7 years ago

Hello @capnmidnight, thanks for the clarification. I guessed that this is a more fundamental issue. Could you provide a link to the mentioned definition of a user gesture? That would be great.

capnmidnight commented 7 years ago

It took me a while to find, I've actually been searching for it since last night. The key factor is that the HTML spec calls it "User Activation", whereas all the browsers call it "User Gesture" >:(

https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-activation

matthias-w commented 7 years ago

Thank you @capnmidnight. That was fast ;) Anyway, considering that modern web APIs are increasingly async-only (e.g. IndexedDB), to me this appears too restrictive. But I guess this is not the right place to complain about ;)

Greetings and thanks again

capnmidnight commented 7 years ago

Tell me about it. With my WebVR apps, I'd like to let users set fullScreen on their main monitor and presentation mode on their HMD at the same time, because there is significant use of the mouse and keyboard with my work and the mouse really needs to be Pointer Locked (another User-Activation-only API) to the canvas to make sure the user can mouse around without needing to see the main monitor. This used to work. Now both Firefox and Chrome either refuse to do one of them if I chain the promises together, or hard-crash out to the desktop if I run them sequentially.

toji commented 6 years ago

Closing all bugs in this issue tracker.

This repo was created to track issues in the experimental builds WebVR Chromium builds, which are now deprecated. Chrome Canary for Windows now has much more secure (and hopefully more performant) support for WebVR behind a flag, and Android has had WebVR support as an Origin Trial and behind a flag for a while now.

If this is a performance or correctness bug and you suspect it's still happening, please test against the latest Canary build of Chrome to verify and then file a bug at https://crbug.com. If this is an issue with the API, please review the latest WebXR explainer to see if it's been resolved and file a bug there if not.

Thanks for your interest in VR on the web! We've got an exciting year ahead of us! --Brandon