mirror of
https://github.com/servo/servo.git
synced 2025-09-30 08:39:16 +01:00
script: Move the majority of the input event handling code to DocumentEventHandler
(#38584)
This moves the majority of the input event handler code to the `DocumentEventHandler` helper structure. It better encapsulates event handling, hiding most of the details from both `ScriptThread` and `Document`. The benefit here is that the majority of the functions can become private and `Document` is over 1000 lines shorter. Testing: This should not change any behavior so is covered by existing WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
bd9bb77295
commit
069ad40872
8 changed files with 1519 additions and 1484 deletions
|
@ -33,9 +33,9 @@ use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarker
|
|||
use dom_struct::dom_struct;
|
||||
use embedder_traits::user_content_manager::{UserContentManager, UserScript};
|
||||
use embedder_traits::{
|
||||
AlertResponse, ConfirmResponse, EmbedderMsg, GamepadEvent, GamepadSupportedHapticEffects,
|
||||
GamepadUpdateType, PromptResponse, SimpleDialog, Theme, UntrustedNodeAddress, ViewportDetails,
|
||||
WebDriverJSError, WebDriverJSResult, WebDriverLoadStatus,
|
||||
AlertResponse, ConfirmResponse, EmbedderMsg, PromptResponse, SimpleDialog, Theme,
|
||||
UntrustedNodeAddress, ViewportDetails, WebDriverJSError, WebDriverJSResult,
|
||||
WebDriverLoadStatus,
|
||||
};
|
||||
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D};
|
||||
use euclid::{Point2D, Scale, Size2D, Vector2D};
|
||||
|
@ -69,8 +69,6 @@ use num_traits::ToPrimitive;
|
|||
use profile_traits::ipc as ProfiledIpc;
|
||||
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
||||
use profile_traits::time::ProfilerChan as TimeProfilerChan;
|
||||
use script_bindings::codegen::GenericBindings::NavigatorBinding::NavigatorMethods;
|
||||
use script_bindings::codegen::GenericBindings::PerformanceBinding::PerformanceMethods;
|
||||
use script_bindings::conversions::SafeToJSValConvertible;
|
||||
use script_bindings::interfaces::WindowHelpers;
|
||||
use script_bindings::root::Root;
|
||||
|
@ -133,8 +131,6 @@ use crate::dom::document::{AnimationFrameCallback, Document};
|
|||
use crate::dom::element::Element;
|
||||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::gamepad::{Gamepad, contains_user_gesture};
|
||||
use crate::dom::gamepadevent::GamepadEventType;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::hashchangeevent::HashChangeEvent;
|
||||
use crate::dom::history::History;
|
||||
|
@ -713,126 +709,6 @@ impl Window {
|
|||
pub(crate) fn font_context(&self) -> &Arc<FontContext> {
|
||||
&self.font_context
|
||||
}
|
||||
|
||||
pub(crate) fn handle_gamepad_event(&self, gamepad_event: GamepadEvent) {
|
||||
match gamepad_event {
|
||||
GamepadEvent::Connected(index, name, bounds, supported_haptic_effects) => {
|
||||
self.handle_gamepad_connect(
|
||||
index.0,
|
||||
name,
|
||||
bounds.axis_bounds,
|
||||
bounds.button_bounds,
|
||||
supported_haptic_effects,
|
||||
);
|
||||
},
|
||||
GamepadEvent::Disconnected(index) => {
|
||||
self.handle_gamepad_disconnect(index.0);
|
||||
},
|
||||
GamepadEvent::Updated(index, update_type) => {
|
||||
self.receive_new_gamepad_button_or_axis(index.0, update_type);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/gamepad/#dfn-gamepadconnected>
|
||||
fn handle_gamepad_connect(
|
||||
&self,
|
||||
// As the spec actually defines how to set the gamepad index, the GilRs index
|
||||
// is currently unused, though in practice it will almost always be the same.
|
||||
// More infra is currently needed to track gamepads across windows.
|
||||
_index: usize,
|
||||
name: String,
|
||||
axis_bounds: (f64, f64),
|
||||
button_bounds: (f64, f64),
|
||||
supported_haptic_effects: GamepadSupportedHapticEffects,
|
||||
) {
|
||||
// TODO: 2. If document is not null and is not allowed to use the "gamepad" permission,
|
||||
// then abort these steps.
|
||||
let this = Trusted::new(self);
|
||||
self.upcast::<GlobalScope>()
|
||||
.task_manager()
|
||||
.gamepad_task_source()
|
||||
.queue(task!(gamepad_connected: move || {
|
||||
let window = this.root();
|
||||
|
||||
let navigator = window.Navigator();
|
||||
let selected_index = navigator.select_gamepad_index();
|
||||
let gamepad = Gamepad::new(
|
||||
&window,
|
||||
selected_index,
|
||||
name,
|
||||
"standard".into(),
|
||||
axis_bounds,
|
||||
button_bounds,
|
||||
supported_haptic_effects,
|
||||
false,
|
||||
CanGc::note(),
|
||||
);
|
||||
navigator.set_gamepad(selected_index as usize, &gamepad, CanGc::note());
|
||||
}));
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/gamepad/#dfn-gamepaddisconnected>
|
||||
fn handle_gamepad_disconnect(&self, index: usize) {
|
||||
let this = Trusted::new(self);
|
||||
self.upcast::<GlobalScope>()
|
||||
.task_manager()
|
||||
.gamepad_task_source()
|
||||
.queue(task!(gamepad_disconnected: move || {
|
||||
let window = this.root();
|
||||
let navigator = window.Navigator();
|
||||
if let Some(gamepad) = navigator.get_gamepad(index) {
|
||||
if window.Document().is_fully_active() {
|
||||
gamepad.update_connected(false, gamepad.exposed(), CanGc::note());
|
||||
navigator.remove_gamepad(index);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/gamepad/#receiving-inputs>
|
||||
fn receive_new_gamepad_button_or_axis(&self, index: usize, update_type: GamepadUpdateType) {
|
||||
let this = Trusted::new(self);
|
||||
|
||||
// <https://w3c.github.io/gamepad/#dfn-update-gamepad-state>
|
||||
self.upcast::<GlobalScope>().task_manager().gamepad_task_source().queue(
|
||||
task!(update_gamepad_state: move || {
|
||||
let window = this.root();
|
||||
let navigator = window.Navigator();
|
||||
if let Some(gamepad) = navigator.get_gamepad(index) {
|
||||
let current_time = window.Performance().Now();
|
||||
gamepad.update_timestamp(*current_time);
|
||||
match update_type {
|
||||
GamepadUpdateType::Axis(index, value) => {
|
||||
gamepad.map_and_normalize_axes(index, value);
|
||||
},
|
||||
GamepadUpdateType::Button(index, value) => {
|
||||
gamepad.map_and_normalize_buttons(index, value);
|
||||
}
|
||||
};
|
||||
if !navigator.has_gamepad_gesture() && contains_user_gesture(update_type) {
|
||||
navigator.set_has_gamepad_gesture(true);
|
||||
navigator.GetGamepads()
|
||||
.iter()
|
||||
.filter_map(|g| g.as_ref())
|
||||
.for_each(|gamepad| {
|
||||
gamepad.set_exposed(true);
|
||||
gamepad.update_timestamp(*current_time);
|
||||
let new_gamepad = Trusted::new(&**gamepad);
|
||||
if window.Document().is_fully_active() {
|
||||
window.upcast::<GlobalScope>().task_manager().gamepad_task_source().queue(
|
||||
task!(update_gamepad_connect: move || {
|
||||
let gamepad = new_gamepad.root();
|
||||
gamepad.notify_event(GamepadEventType::Connected, CanGc::note());
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#atob
|
||||
|
@ -3128,7 +3004,9 @@ impl Window {
|
|||
return;
|
||||
};
|
||||
|
||||
self.Document().set_cursor(hit_test_result.cursor);
|
||||
self.Document()
|
||||
.event_handler()
|
||||
.set_cursor(hit_test_result.cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue