Implement non-XR Gamepad discovery and input (#31200)

* Create embedder event to send to constellation

* Handle gamepad message in constellation, send to script thread

* Handle GamepadEvent in script thread and dispatch event to document

* Add missing Clones, fix event

* Add gamepad task source

* Adjust GamepadIndex type, remove unused imports

* Add internal getter for gamepads list

* Update gamepad new methods

* Handle gamepad connect and disconnect events

* Proto will be none, no need for HandleObject

* Initialize buttons and axes to standard mapping

* Adjust update type index types

* Update GamepadButton update function

* Adjust Gamepad mapping comments to match spec, add update logic

* Amend comment

* Update button and axis inputs on Updated event

* Add GilRs as gamepad backend in servoshell

* Add spec links, queue gamepad updates on task source

* ./mach fmt

* Fix comment length

* Split out button init, update spec comments

* Move gamepad event handling from document to global

* Map and normalize axes/button values

* Use std::time for gamepad timestamp

* Adjust gamepad handling in event loop

* Move button press/touch check into map+normalize function

- Small change but is more in line with spec

* ./mach fmt

* Update comment spec links and warning messages

* Doc comments -> regular comments

* Add window event handlers for gamepad connect/disconnect

* Adjust gamepad disconnect behavior

* Add missing TODO's, adjust gamepad/gamepadbutton list methods and formatting

* Update button handling from gilrs, add comments

* Enable gamepad pref during WPT tests and update expectations

* Update WPT expectations in meta-legacy-layout
This commit is contained in:
Daniel Adams 2024-02-17 08:42:31 -10:00 committed by GitHub
parent 1cc546c4fc
commit c999d4546c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 695 additions and 208 deletions

View file

@ -142,7 +142,7 @@ use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent};
use script_traits::{
webdriver_msg, AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo,
BroadcastMsg, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext,
DocumentActivity, DocumentState, HistoryEntryReplacement, IFrameLoadInfo,
DocumentActivity, DocumentState, GamepadEvent, HistoryEntryReplacement, IFrameLoadInfo,
IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LayoutControlMsg,
LayoutMsg as FromLayoutMsg, LoadData, LoadOrigin, LogEntry, MediaSessionActionType,
MessagePortMsg, MouseEventType, PortMessageTask, SWManagerMsg, SWManagerSenders,
@ -1550,6 +1550,9 @@ where
EmbedderMsg::ReadyToPresent,
));
},
FromCompositorMsg::Gamepad(gamepad_event) => {
self.handle_gamepad_msg(gamepad_event);
},
}
}
@ -5466,4 +5469,40 @@ where
error!("Got a media session action but no active media session is registered");
}
}
/// Handle GamepadEvents from the embedder and forward them to the script thread
fn handle_gamepad_msg(&mut self, event: GamepadEvent) {
// Send to the focused browsing contexts' current pipeline.
let focused_browsing_context_id = self
.webviews
.focused_webview()
.map(|(_, webview)| webview.focused_browsing_context_id);
match focused_browsing_context_id {
Some(browsing_context_id) => {
let event = CompositorEvent::GamepadEvent(event);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
Some(ctx) => ctx.pipeline_id,
None => {
return warn!(
"{}: Got gamepad event for nonexistent browsing context",
browsing_context_id,
);
},
};
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
let result = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.event_loop.send(msg),
None => {
return debug!("{}: Got gamepad event after closure", pipeline_id);
},
};
if let Err(e) = result {
self.handle_send_error(pipeline_id, e);
}
},
None => {
warn!("No focused webview to handle gamepad event");
},
}
}
}