Re: [gamepad] The API is not thread-safe and can not be fixed. (#18)

(Forgive me if I retread a bit of ground here, I'm still organizing my thoughts on the matter.)

This issue has come up in various forms a few times, with @pyalot specifically bringing up the issue with gamepads as the primary navigation method on consoles. (And I apologize for not having the time to adequately respond to those concerns.) The extension issue is certainly an interesting wrinkle, but I feel like it's still fundamentally the same problem: The gamepad needs the ability to work both as a navigation device AND a traditional gamepad, but not at the same time.

Browser history has shown us that ~0 developers will revisit previously published sites to update their code. Give that, a solution to this issue that allows existing pages to work on devices with this conflict would be ideal, and we should examine any possible options in that direction first. If it turns out to be infeasible, however, then a breaking change is preferable to never working at all.

The first thing that comes to mind is that gamepad-navigated devices (hereafter referred to as "consoles" for convenience) could reserve a button (Like the XBox button) that acts as the "escape hatch", like `Esc` for pointer lock. The button isn't accessible to the gamepad API directly, and any time the user presses it the gamepad API stops receiving values and control reverts back to the page. To the page this could appear to be gamepad connected and disconnected events. Seems like an interesting compromise, and has the benefit of allowing the UA to do what's most natural for the platform without page intervention. But there's problems too: Most gamepad-enabled pages will start polling for gamepad events right away and continue polling throughout the lifetime of the page. That makes the poll a bad proxy for a gamepad "lock" request, and means that once the gamepad focus has been taken back by the page there's no natural way for the page to indicate it wants to re-acquire the input. 
 The dedicated button mentioned before could act as a toggle, but that would actually indicate it should be something other than the Xbox/PS button because you expect that pushing that when the controller is being used to navigate should return "up" a level to OS navigation and not "down" to deeper page control. Plus placing the mode switch entirely in the users hand's is undiscoverable and awkward: You'd end up tapping the "gamepad lock" button on every page just to see if it works. So that idea seems dead in the water.

So what we really want is a way for the page to explicitly say "I want to take control now" and make sure the UA can always logically escape that, notifying the page of when the input becomes locked and unlocked. We already have this for mouse events: [PointerLock](http://www.w3.org/TR/pointerlock/). So it feels natural to simply duplicate the API for gamepads, right? Actually, it seems to me like pointer lock could function as a gamepad lock as-is on consoles. After all, when using the gamepad to navigate it is literally functioning as your pointer, regardless of whether or not it displays a mouse-like cursor. So what if on consoles the gamepad API simply doesn't return anything unless you lock the pointer. This feels like an awkward conflation of APIs, but it has some advantages: There's at least some subset of existing pages with gamepad support that _also_ use pointerlock for keyboard/mouse input, and those pages don't generally stop polling for gamepad events just because the po
 inter is locked. (See http://phoboslab.org/xibalba/ for an example of the type of content I'm talking about.) So while we don't get every existing page working on consoles we pick up some percentage of them by happy accident, plus we've provided a clear route forward for pages that want to work on consoles. Device that don't use gamepads as a navigation device (desktop, mobile) continue to work as-is. That seems like a reasonable compromise to me, though it's actually on the console makers to implement it. At least we could spec the behavior out.

_But_ it seems like that doesn't address the extension case, and frankly I'm not sure how we can reasonably address it. I suppose the canonical example here would be a desktop extension that allows  you to navigate the browser with the gamepad as @carlsmith alluded to. Shoulder buttons to switch tabs, back button to refresh, "A" to click links. That sort of thing. It feels nonsensical to have such an API use pointerlock, especially because it would have the side effect on desktops of hiding the mouse cursor. However, we also have the benefit of allowing different API surface in extensions than pages due to the different permissions model. So it feels like extensions could gain their own "gamepad lock", accompanied by an explicit "gamepad unlock" call. While an extension has the gamepad locked no other page or extension can receive gamepad events (Multiple competing extensions would probably just follow a first-to-lock rule, but could be notified if the reason their lock failed was an
 other extension holding the lock to communicate issues to the user.) The extension can then implement it's own version of the "escape hatch" method described above, designating whatever method they see fit for allowing the page to start/stop seeing gamepad inputs. This doesn't effect the existing gamepad API at all, since it's extension-only.

So that's all a little cobbled together, but it strikes me as a better path than declaring API bankruptcy and focusing on a 2.0 API instead. Thoughts?

---
Reply to this email directly or view it on GitHub:
https://github.com/w3c/gamepad/issues/18#issuecomment-157145377

Received on Monday, 16 November 2015 19:34:51 UTC