Implement WheelEvent Interface

Note: The WheelEvent interface supports rotation in all 3 spatial
dimensions. This implementation only supports two due to limitations
in the Glutin compositor.

The wheelevent interface is a dom interface that triggers for any
attached device that can rotate in one or more spatial dimensions.
Traditionally this is the mouse wheel though other devices could be
used as well. E.g. the trackball on a trackball mouse.
This commit is contained in:
Robert Snakard 2019-02-24 21:24:36 +00:00 committed by Josh Matthews
parent 8f11b52d9a
commit 35bca991ad
16 changed files with 347 additions and 146 deletions

View file

@ -97,6 +97,7 @@ use crate::dom::treewalker::TreeWalker;
use crate::dom::uievent::UIEvent;
use crate::dom::virtualmethods::vtable_for;
use crate::dom::webglcontextevent::WebGLContextEvent;
use crate::dom::wheelevent::WheelEvent;
use crate::dom::window::{ReflowReason, Window};
use crate::dom::windowproxy::WindowProxy;
use crate::fetch::FetchCanceller;
@ -135,7 +136,9 @@ use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataR
use ref_slice::ref_slice;
use script_layout_interface::message::{Msg, ReflowGoal};
use script_traits::{AnimationState, DocumentActivity, MouseButton, MouseEventType};
use script_traits::{MsDuration, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress};
use script_traits::{
MsDuration, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta,
};
use servo_arc::Arc;
use servo_atoms::Atom;
use servo_config::pref;
@ -1218,6 +1221,53 @@ impl Document {
.reflow(ReflowGoal::Full, ReflowReason::MouseEvent);
}
#[allow(unsafe_code)]
pub fn handle_wheel_event(
&self,
js_runtime: *mut JSRuntime,
delta: WheelDelta,
client_point: Point2D<f32>,
node_address: Option<UntrustedNodeAddress>,
) {
let wheel_event_type_string = "wheel".to_owned();
debug!("{}: at {:?}", wheel_event_type_string, client_point);
let el = node_address.and_then(|address| {
let node = unsafe { node::from_untrusted_node_address(js_runtime, address) };
node.inclusive_ancestors(ShadowIncluding::No)
.filter_map(DomRoot::downcast::<Element>)
.next()
});
let el = match el {
Some(el) => el,
None => return,
};
let node = el.upcast::<Node>();
debug!("{}: on {:?}", wheel_event_type_string, node.debug_str());
// https://w3c.github.io/uievents/#event-wheelevents
let event = WheelEvent::new(
&self.window,
DOMString::from(wheel_event_type_string),
EventBubbles::Bubbles,
EventCancelable::Cancelable,
Some(&self.window),
0i32,
Finite::wrap(delta.x),
Finite::wrap(delta.y),
Finite::wrap(delta.z),
delta.mode as u32,
);
let event = event.upcast::<Event>();
event.set_trusted(true);
let target = node.upcast();
event.fire(target);
}
#[allow(unsafe_code)]
pub fn handle_touch_event(
&self,