RESOLVED FIXED 269292
Gamepad API does not work in WKWebView
https://bugs.webkit.org/show_bug.cgi?id=269292
Summary Gamepad API does not work in WKWebView
Ashley Gullen
Reported 2024-02-13 06:57:10 PST
It appears that the Gamepad API does not work in WKWebView. Tested on an iPhone 12 Pro Max with iOS 17.2.1 and a PlayStation 4 wireless controller. Steps to reproduce: 1. Connect a gamepad to an iOS device (in my case I used bluetooth to pair the controller to the device) 2. In the Safari browser, visit https://hardwaretester.com/gamepad. Press some buttons on the gamepad. 3. In WKWebView, visit https://hardwaretester.com/gamepad and also press some buttons on the gamepad. This can be done with a test app like ExpoFP WKWebViewer, a framework like Cordova, or a browser like Chrome for iOS which is implemented using WKWebView, all of which reproduce the issue. Observed result: In the Safari browser, it successfully detects the gamepad and its input. In WKWebView no gamepad input is ever detected. Expected result: WKWebView to be able to detect gamepad input as the Safari browser does. Note that this prevents any iOS apps made in Construct (www.construct.net) from being able to use gamepad input. Also note that as it is a bug that only affects non-Safari browsers on iOS, it may have regulatory significance.
Attachments
Broken gamepad API sample Xcode project (77.21 KB, application/zip)
2024-02-22 10:52 PST, michaeldo
no flags
Ashley Gullen
Comment 1 2024-02-13 07:09:17 PST
Note also that adding the "Game controllers" capability in Xcode, and checking "Extended gamepad", makes no difference - WKWebView still never detects any gamepads or gamepad input.
Brady Eidson
Comment 2 2024-02-14 16:45:58 PST
To expose Gamepad support, your WKWebView needs to be the firstResponder. Safari - correctly for Apple platforms - keeps focused WKWebViews as the firstResponder. Many apps neglect to do this, and once we let a developer know and they make the change gamepads start working. Do you have an example app where the WKWebView is definitely the firstResponder but they don't work?
Ashley Gullen
Comment 3 2024-02-15 03:46:58 PST
Would the same issue affect keyboard input with an attached physical keyboard device, as in issue 206887?
Brady Eidson
Comment 4 2024-02-15 11:59:16 PST
(In reply to Ashley Gullen from comment #3) > Would the same issue affect keyboard input with an attached physical > keyboard device, as in issue 206887? The responder chain (and therefore "firstResponder") was originally about mouse and keyboard input, so yes that is likely the case.
Ashley Gullen
Comment 5 2024-02-20 05:35:33 PST
I've filed follow-up issues with both Chrome for iOS (https://issues.chromium.org/issues/325307469) and Cordova (https://github.com/apache/cordova-ios/issues/1397) to check if they need to do something about the firstResponder.
Radar WebKit Bug Importer
Comment 6 2024-02-20 06:58:32 PST
michaeldo
Comment 7 2024-02-22 10:52:26 PST
Created attachment 470016 [details] Broken gamepad API sample Xcode project
michaeldo
Comment 8 2024-02-22 10:53:01 PST
The gamepad API doesn't work if the WKWebView is not first responder at "the correct" point during a page load. I didn't dig into WebKit to see exactly where this is happening, but you can test with this attached sample app.
Ashley Gullen
Comment 9 2024-02-23 02:16:39 PST
michaeldo@ - could you explain a bit more about the workaround for the benefit of Cordova on iOS, which had the same issue? (https://github.com/apache/cordova-ios/issues/1397)
michaeldo
Comment 10 2024-02-23 08:20:25 PST
I added a comment on the Cordova GitHub issue. However, I still think this bug is worth exploring further in WebKit. I would expect the gamepad API to work even if the first responder is set after the page load, similar to the routing of hardware keyboard commands.
Darryl Pogue
Comment 11 2024-02-23 09:23:04 PST
This is the code that checks for the firstResponder on WKWebView on iOS: https://github.com/WebKit/WebKit/blob/3fbaadfcd9305751f242411149c68dfd2f4c1ed9/Source/WebKit/UIProcess/Gamepad/ios/UIGamepadProviderIOS.mm#L37-L52 That gets called when the process pool first loads (via https://github.com/WebKit/WebKit/blob/3fbaadfcd9305751f242411149c68dfd2f4c1ed9/Source/WebKit/UIProcess/Gamepad/UIGamepadProvider.cpp#L132-L139) and also when the view becomes active (via https://github.com/WebKit/WebKit/blob/3fbaadfcd9305751f242411149c68dfd2f4c1ed9/Source/WebKit/UIProcess/Gamepad/UIGamepadProvider.cpp#L150-L160) However, `viewBecameActive` is only triggered on macOS based on NSWindow events (here: https://github.com/WebKit/WebKit/blob/3fbaadfcd9305751f242411149c68dfd2f4c1ed9/Source/WebKit/UIProcess/mac/WebViewImpl.mm#L1999-L2008) and there doesn't seem to be an equivalent thing happening on iOS. That probably explains why gamepad support is only detected at page load on iOS. Maybe iOS should re-evaluate this when the WKWebView becomes the firstResponder?
Darryl Pogue
Comment 12 2024-02-23 12:41:12 PST
(In reply to Darryl Pogue from comment #11) > Maybe iOS should re-evaluate this when the WKWebView becomes the > firstResponder? My totally naïve thought without understanding all the nuances involved is that UIGamepadProvider::singleton().viewBecameActive() should be called from somewhere in WKContentView becomeFirstResponderForWebView. Around https://github.com/WebKit/WebKit/blob/3832d8ef60666b50d8e827bdc044290ec5f989af/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm#L1890-L1905 maybe?
Darryl Pogue
Comment 13 2024-03-25 18:00:00 PDT
EWS
Comment 14 2024-05-22 07:49:13 PDT
Committed 279124@main (24bc94ef702d): <https://commits.webkit.org/279124@main> Reviewed commits have been landed. Closing PR #26444 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.