mirror of
https://github.com/servo/servo.git
synced 2025-06-09 09:03:23 +00:00
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.
260 lines
7.5 KiB
Rust
260 lines
7.5 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use crate::dom::bindings::codegen::Bindings::MouseEventBinding;
|
|
use crate::dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
|
|
use crate::dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
|
|
use crate::dom::bindings::error::Fallible;
|
|
use crate::dom::bindings::inheritance::Castable;
|
|
use crate::dom::bindings::reflector::reflect_dom_object;
|
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
|
use crate::dom::bindings::str::DOMString;
|
|
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
|
use crate::dom::eventtarget::EventTarget;
|
|
use crate::dom::uievent::UIEvent;
|
|
use crate::dom::window::Window;
|
|
use dom_struct::dom_struct;
|
|
use euclid::Point2D;
|
|
use servo_config::pref;
|
|
use std::cell::Cell;
|
|
use std::default::Default;
|
|
|
|
#[dom_struct]
|
|
pub struct MouseEvent {
|
|
uievent: UIEvent,
|
|
screen_x: Cell<i32>,
|
|
screen_y: Cell<i32>,
|
|
client_x: Cell<i32>,
|
|
client_y: Cell<i32>,
|
|
ctrl_key: Cell<bool>,
|
|
shift_key: Cell<bool>,
|
|
alt_key: Cell<bool>,
|
|
meta_key: Cell<bool>,
|
|
button: Cell<i16>,
|
|
buttons: Cell<u16>,
|
|
related_target: MutNullableDom<EventTarget>,
|
|
point_in_target: Cell<Option<Point2D<f32>>>,
|
|
}
|
|
|
|
impl MouseEvent {
|
|
pub fn new_inherited() -> MouseEvent {
|
|
MouseEvent {
|
|
uievent: UIEvent::new_inherited(),
|
|
screen_x: Cell::new(0),
|
|
screen_y: Cell::new(0),
|
|
client_x: Cell::new(0),
|
|
client_y: Cell::new(0),
|
|
ctrl_key: Cell::new(false),
|
|
shift_key: Cell::new(false),
|
|
alt_key: Cell::new(false),
|
|
meta_key: Cell::new(false),
|
|
button: Cell::new(0),
|
|
buttons: Cell::new(0),
|
|
related_target: Default::default(),
|
|
point_in_target: Cell::new(None),
|
|
}
|
|
}
|
|
|
|
pub fn new_uninitialized(window: &Window) -> DomRoot<MouseEvent> {
|
|
reflect_dom_object(
|
|
Box::new(MouseEvent::new_inherited()),
|
|
window,
|
|
MouseEventBinding::Wrap,
|
|
)
|
|
}
|
|
|
|
pub fn new(
|
|
window: &Window,
|
|
type_: DOMString,
|
|
can_bubble: EventBubbles,
|
|
cancelable: EventCancelable,
|
|
view: Option<&Window>,
|
|
detail: i32,
|
|
screen_x: i32,
|
|
screen_y: i32,
|
|
client_x: i32,
|
|
client_y: i32,
|
|
ctrl_key: bool,
|
|
alt_key: bool,
|
|
shift_key: bool,
|
|
meta_key: bool,
|
|
button: i16,
|
|
buttons: u16,
|
|
related_target: Option<&EventTarget>,
|
|
point_in_target: Option<Point2D<f32>>,
|
|
) -> DomRoot<MouseEvent> {
|
|
let ev = MouseEvent::new_uninitialized(window);
|
|
ev.InitMouseEvent(
|
|
type_,
|
|
bool::from(can_bubble),
|
|
bool::from(cancelable),
|
|
view,
|
|
detail,
|
|
screen_x,
|
|
screen_y,
|
|
client_x,
|
|
client_y,
|
|
ctrl_key,
|
|
alt_key,
|
|
shift_key,
|
|
meta_key,
|
|
button,
|
|
related_target,
|
|
);
|
|
ev.buttons.set(buttons);
|
|
ev.point_in_target.set(point_in_target);
|
|
ev
|
|
}
|
|
|
|
pub fn Constructor(
|
|
window: &Window,
|
|
type_: DOMString,
|
|
init: &MouseEventBinding::MouseEventInit,
|
|
) -> Fallible<DomRoot<MouseEvent>> {
|
|
let bubbles = EventBubbles::from(init.parent.parent.parent.bubbles);
|
|
let cancelable = EventCancelable::from(init.parent.parent.parent.cancelable);
|
|
let event = MouseEvent::new(
|
|
window,
|
|
type_,
|
|
bubbles,
|
|
cancelable,
|
|
init.parent.parent.view.deref(),
|
|
init.parent.parent.detail,
|
|
init.screenX,
|
|
init.screenY,
|
|
init.clientX,
|
|
init.clientY,
|
|
init.parent.ctrlKey,
|
|
init.parent.altKey,
|
|
init.parent.shiftKey,
|
|
init.parent.metaKey,
|
|
init.button,
|
|
0,
|
|
init.relatedTarget.deref(),
|
|
None,
|
|
);
|
|
Ok(event)
|
|
}
|
|
|
|
pub fn point_in_target(&self) -> Option<Point2D<f32>> {
|
|
self.point_in_target.get()
|
|
}
|
|
}
|
|
|
|
impl MouseEventMethods for MouseEvent {
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-screenX
|
|
fn ScreenX(&self) -> i32 {
|
|
self.screen_x.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-screenY
|
|
fn ScreenY(&self) -> i32 {
|
|
self.screen_y.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-clientX
|
|
fn ClientX(&self) -> i32 {
|
|
self.client_x.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-clientY
|
|
fn ClientY(&self) -> i32 {
|
|
self.client_y.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-ctrlKey
|
|
fn CtrlKey(&self) -> bool {
|
|
self.ctrl_key.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-shiftKey
|
|
fn ShiftKey(&self) -> bool {
|
|
self.shift_key.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-altKey
|
|
fn AltKey(&self) -> bool {
|
|
self.alt_key.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-metaKey
|
|
fn MetaKey(&self) -> bool {
|
|
self.meta_key.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-button
|
|
fn Button(&self) -> i16 {
|
|
self.button.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#dom-mouseevent-buttons
|
|
fn Buttons(&self) -> u16 {
|
|
self.buttons.get()
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-relatedTarget
|
|
fn GetRelatedTarget(&self) -> Option<DomRoot<EventTarget>> {
|
|
self.related_target.get()
|
|
}
|
|
|
|
// See discussion at:
|
|
// - https://github.com/servo/servo/issues/6643
|
|
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1186125
|
|
// This returns the same result as current gecko.
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
|
|
fn Which(&self) -> i32 {
|
|
if pref!(dom.mouse_event.which.enabled) {
|
|
(self.button.get() + 1) as i32
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
|
|
// https://w3c.github.io/uievents/#widl-MouseEvent-initMouseEvent
|
|
fn InitMouseEvent(
|
|
&self,
|
|
type_arg: DOMString,
|
|
can_bubble_arg: bool,
|
|
cancelable_arg: bool,
|
|
view_arg: Option<&Window>,
|
|
detail_arg: i32,
|
|
screen_x_arg: i32,
|
|
screen_y_arg: i32,
|
|
client_x_arg: i32,
|
|
client_y_arg: i32,
|
|
ctrl_key_arg: bool,
|
|
alt_key_arg: bool,
|
|
shift_key_arg: bool,
|
|
meta_key_arg: bool,
|
|
button_arg: i16,
|
|
related_target_arg: Option<&EventTarget>,
|
|
) {
|
|
if self.upcast::<Event>().dispatching() {
|
|
return;
|
|
}
|
|
|
|
self.upcast::<UIEvent>().InitUIEvent(
|
|
type_arg,
|
|
can_bubble_arg,
|
|
cancelable_arg,
|
|
view_arg,
|
|
detail_arg,
|
|
);
|
|
self.screen_x.set(screen_x_arg);
|
|
self.screen_y.set(screen_y_arg);
|
|
self.client_x.set(client_x_arg);
|
|
self.client_y.set(client_y_arg);
|
|
self.ctrl_key.set(ctrl_key_arg);
|
|
self.alt_key.set(alt_key_arg);
|
|
self.shift_key.set(shift_key_arg);
|
|
self.meta_key.set(meta_key_arg);
|
|
self.button.set(button_arg);
|
|
self.related_target.set(related_target_arg);
|
|
}
|
|
|
|
// https://dom.spec.whatwg.org/#dom-event-istrusted
|
|
fn IsTrusted(&self) -> bool {
|
|
self.uievent.IsTrusted()
|
|
}
|
|
}
|