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

@ -26,9 +26,11 @@ use num_traits::FromPrimitive;
#[cfg(feature = "gl")]
use pixels::PixelFormat;
use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent};
use script_traits::{AnimationState, AnimationTickType, ConstellationMsg, LayoutControlMsg};
use script_traits::{MouseButton, MouseEventType, ScrollState, TouchEventType, TouchId};
use script_traits::{
MouseButton, MouseEventType, ScrollState, TouchEventType, TouchId, WheelDelta,
};
use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType};
use servo_geometry::DeviceIndependentPixel;
use std::collections::HashMap;
@ -792,6 +794,22 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
}
pub fn send_wheel_event(&mut self, delta: WheelDelta, point: DevicePoint) {
let results = self.hit_test_at_point(point);
if let Some(item) = results.items.first() {
let event = WheelEvent(
delta,
item.point_in_viewport.to_untyped(),
Some(UntrustedNodeAddress(item.tag.0 as *const c_void)),
);
let pipeline_id = PipelineId::from_webrender(item.pipeline);
let msg = ConstellationMsg::ForwardEvent(pipeline_id, event);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending event to constellation failed ({:?}).", e);
}
}
}
pub fn on_touch_event(
&mut self,
event_type: TouchEventType,
@ -858,6 +876,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.dispatch_mouse_window_event_class(MouseWindowEvent::Click(button, p));
}
pub fn on_wheel_event(&mut self, delta: WheelDelta, p: DevicePoint) {
self.send_wheel_event(delta, p);
}
pub fn on_scroll_event(
&mut self,
delta: ScrollLocation,

View file

@ -10,7 +10,7 @@ use euclid::TypedScale;
use gleam::gl;
use keyboard_types::KeyboardEvent;
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId, TraversalDirection};
use script_traits::{MouseButton, TouchEventType, TouchId};
use script_traits::{MouseButton, TouchEventType, TouchId, WheelDelta};
use servo_geometry::DeviceIndependentPixel;
use servo_url::ServoUrl;
use std::fmt::{Debug, Error, Formatter};
@ -65,6 +65,8 @@ pub enum WindowEvent {
MouseWindowMoveEventClass(DevicePoint),
/// Touch event: type, identifier, point
Touch(TouchEventType, TouchId, DevicePoint),
/// Sent when user moves the mouse wheel.
Wheel(WheelDelta, DevicePoint),
/// Sent when the user scrolls. The first point is the delta and the second point is the
/// origin.
Scroll(ScrollLocation, DeviceIntPoint, TouchEventType),
@ -113,6 +115,7 @@ impl Debug for WindowEvent {
WindowEvent::MouseWindowEventClass(..) => write!(f, "Mouse"),
WindowEvent::MouseWindowMoveEventClass(..) => write!(f, "MouseMove"),
WindowEvent::Touch(..) => write!(f, "Touch"),
WindowEvent::Wheel(..) => write!(f, "Wheel"),
WindowEvent::Scroll(..) => write!(f, "Scroll"),
WindowEvent::Zoom(..) => write!(f, "Zoom"),
WindowEvent::PinchZoom(..) => write!(f, "PinchZoom"),