diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/compositing/compositor.rs | 7 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 35 | ||||
-rw-r--r-- | components/script/dom/activation.rs | 2 | ||||
-rw-r--r-- | components/script/dom/document.rs | 36 | ||||
-rw-r--r-- | components/script/dom/mouseevent.rs | 10 | ||||
-rw-r--r-- | components/script/dom/webidls/MouseEvent.webidl | 4 | ||||
-rw-r--r-- | components/script/script_thread.rs | 15 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 17 |
8 files changed, 111 insertions, 15 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 2b1322bfc63..5f5e32bbd75 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -662,6 +662,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { result.point_in_viewport.to_untyped(), Some(UntrustedNodeAddress(result.tag.0 as *const c_void)), Some(result.point_relative_to_item.to_untyped()), + MouseButton::Left as u16, ); let pipeline_id = PipelineId::from_webrender(result.pipeline); @@ -705,7 +706,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { let results = self.hit_test_at_point(cursor); if let Some(item) = results.items.first() { let node_address = Some(UntrustedNodeAddress(item.tag.0 as *const c_void)); - let event = MouseMoveEvent(Some(item.point_in_viewport.to_untyped()), node_address); + let event = MouseMoveEvent( + Some(item.point_in_viewport.to_untyped()), + node_address, + MouseButton::Left as u16, + ); let pipeline_id = PipelineId::from_webrender(item.pipeline); let msg = ConstellationMsg::ForwardEvent(pipeline_id, event); if let Err(e) = self.constellation_chan.send(msg) { diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 713afb633e9..11967e10038 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -135,6 +135,8 @@ use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use net_traits::{self, FetchResponseMsg, IpcSend, ResourceThreads}; use profile_traits::mem; use profile_traits::time; +use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent}; +use script_traits::MouseEventType; use script_traits::{webdriver_msg, LogEntry, ScriptToConstellationChan, ServiceWorkerMsg}; use script_traits::{ AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo, CompositorEvent, @@ -373,6 +375,10 @@ pub struct Constellation<Message, LTF, STF> { /// Navigation requests from script awaiting approval from the embedder. pending_approval_navigations: PendingApprovalNavigations, + + /// Bitmask which indicates which combination of mouse buttons are + /// currently being pressed. + pressed_mouse_buttons: u16, } /// State needed to construct a constellation. @@ -715,6 +721,7 @@ where webvr_chan: state.webvr_chan, canvas_chan: CanvasPaintThread::start(), pending_approval_navigations: HashMap::new(), + pressed_mouse_buttons: 0, }; constellation.run(); @@ -1798,6 +1805,34 @@ where } fn forward_event(&mut self, destination_pipeline_id: PipelineId, event: CompositorEvent) { + if let MouseButtonEvent(event_type, button, ..) = &event { + match event_type { + MouseEventType::MouseDown | MouseEventType::Click => { + self.pressed_mouse_buttons |= *button as u16; + }, + MouseEventType::MouseUp => { + self.pressed_mouse_buttons &= !(*button as u16); + }, + } + } + + let event = match event { + MouseButtonEvent(event_type, button, point, node_address, point_in_node, _) => { + MouseButtonEvent( + event_type, + button, + point, + node_address, + point_in_node, + self.pressed_mouse_buttons, + ) + }, + MouseMoveEvent(point, node_address, _) => { + MouseMoveEvent(point, node_address, self.pressed_mouse_buttons) + }, + _ => event, + }; + let msg = ConstellationControlMsg::SendEvent(destination_pipeline_id, event); let result = match self.pipelines.get(&destination_pipeline_id) { None => { diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs index b838ac4156a..e4658de2e9f 100644 --- a/components/script/dom/activation.rs +++ b/components/script/dom/activation.rs @@ -12,6 +12,7 @@ use crate::dom::mouseevent::MouseEvent; use crate::dom::node::window_from_node; use crate::dom::window::ReflowReason; use script_layout_interface::message::ReflowGoal; +use script_traits::MouseButton; /// Trait for elements with defined activation behavior pub trait Activatable { @@ -96,6 +97,7 @@ pub fn synthetic_click_activation( alt_key, meta_key, 0, + MouseButton::Left as u16, None, None, ); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index eeec8060fff..7eb43c81b79 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -926,6 +926,7 @@ impl Document { mouse_event_type: MouseEventType, node_address: Option<UntrustedNodeAddress>, point_in_node: Option<Point2D<f32>>, + pressed_mouse_buttons: u16, ) { let mouse_event_type_string = match mouse_event_type { MouseEventType::Click => "click".to_owned(), @@ -976,6 +977,7 @@ impl Document { false, false, 0i16, + pressed_mouse_buttons, None, point_in_node, ); @@ -1007,14 +1009,19 @@ impl Document { if let MouseEventType::Click = mouse_event_type { self.commit_focus_transaction(FocusType::Element); - self.maybe_fire_dblclick(client_point, node); + self.maybe_fire_dblclick(client_point, node, pressed_mouse_buttons); } self.window .reflow(ReflowGoal::Full, ReflowReason::MouseEvent); } - fn maybe_fire_dblclick(&self, click_pos: Point2D<f32>, target: &Node) { + fn maybe_fire_dblclick( + &self, + click_pos: Point2D<f32>, + target: &Node, + pressed_mouse_buttons: u16, + ) { // https://w3c.github.io/uievents/#event-type-dblclick let now = Instant::now(); @@ -1053,6 +1060,7 @@ impl Document { false, false, 0i16, + pressed_mouse_buttons, None, None, ); @@ -1073,6 +1081,7 @@ impl Document { client_point: Point2D<f32>, target: &EventTarget, event_name: FireMouseEventType, + pressed_mouse_buttons: u16, ) { let client_x = client_point.x.to_i32().unwrap_or(0); let client_y = client_point.y.to_i32().unwrap_or(0); @@ -1093,6 +1102,7 @@ impl Document { false, false, 0i16, + pressed_mouse_buttons, None, None, ); @@ -1107,6 +1117,7 @@ impl Document { client_point: Option<Point2D<f32>>, prev_mouse_over_target: &MutNullableDom<Element>, node_address: Option<UntrustedNodeAddress>, + pressed_mouse_buttons: u16, ) { let client_point = match client_point { None => { @@ -1132,7 +1143,12 @@ impl Document { None => return, }; - self.fire_mouse_event(client_point, new_target.upcast(), FireMouseEventType::Move); + self.fire_mouse_event( + client_point, + new_target.upcast(), + FireMouseEventType::Move, + pressed_mouse_buttons, + ); // Nothing more to do here, mousemove is sent, // and the element under the mouse hasn't changed. @@ -1165,7 +1181,12 @@ impl Document { } // Remove hover state to old target and its parents - self.fire_mouse_event(client_point, old_target.upcast(), FireMouseEventType::Out); + self.fire_mouse_event( + client_point, + old_target.upcast(), + FireMouseEventType::Out, + pressed_mouse_buttons, + ); // TODO: Fire mouseleave here only if the old target is // not an ancestor of the new target. @@ -1184,7 +1205,12 @@ impl Document { element.set_hover_state(true); } - self.fire_mouse_event(client_point, &new_target.upcast(), FireMouseEventType::Over); + self.fire_mouse_event( + client_point, + &new_target.upcast(), + FireMouseEventType::Over, + pressed_mouse_buttons, + ); // TODO: Fire mouseenter here. } diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 6ae1c2efab9..6fcadbbeaf8 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -32,6 +32,7 @@ pub struct MouseEvent { 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>>>, } @@ -49,6 +50,7 @@ impl MouseEvent { 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), } @@ -78,6 +80,7 @@ impl MouseEvent { shift_key: bool, meta_key: bool, button: i16, + buttons: u16, related_target: Option<&EventTarget>, point_in_target: Option<Point2D<f32>>, ) -> DomRoot<MouseEvent> { @@ -99,6 +102,7 @@ impl MouseEvent { button, related_target, ); + ev.buttons.set(buttons); ev.point_in_target.set(point_in_target); ev } @@ -126,6 +130,7 @@ impl MouseEvent { init.parent.shiftKey, init.parent.metaKey, init.button, + 0, init.relatedTarget.deref(), None, ); @@ -183,6 +188,11 @@ impl MouseEventMethods for MouseEvent { 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() diff --git a/components/script/dom/webidls/MouseEvent.webidl b/components/script/dom/webidls/MouseEvent.webidl index 5e5a03790fa..29d5872f65e 100644 --- a/components/script/dom/webidls/MouseEvent.webidl +++ b/components/script/dom/webidls/MouseEvent.webidl @@ -17,7 +17,7 @@ interface MouseEvent : UIEvent { readonly attribute short button; readonly attribute EventTarget? relatedTarget; // Introduced in DOM Level 3 - //readonly attribute unsigned short buttons; + readonly attribute unsigned short buttons; //boolean getModifierState (DOMString keyArg); [Pref="dom.mouseevent.which.enabled"] @@ -31,7 +31,7 @@ dictionary MouseEventInit : EventModifierInit { long clientX = 0; long clientY = 0; short button = 0; - //unsigned short buttons = 0; + unsigned short buttons = 0; EventTarget? relatedTarget = null; }; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index cc0500805aa..f45a4349a55 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -3060,7 +3060,14 @@ impl ScriptThread { self.handle_resize_event(pipeline_id, new_size, size_type); }, - MouseButtonEvent(event_type, button, point, node_address, point_in_node) => { + MouseButtonEvent( + event_type, + button, + point, + node_address, + point_in_node, + pressed_mouse_buttons, + ) => { self.handle_mouse_event( pipeline_id, event_type, @@ -3068,10 +3075,11 @@ impl ScriptThread { point, node_address, point_in_node, + pressed_mouse_buttons, ); }, - MouseMoveEvent(point, node_address) => { + MouseMoveEvent(point, node_address, pressed_mouse_buttons) => { let document = match { self.documents.borrow().find_document(pipeline_id) } { Some(document) => document, None => return warn!("Message sent to closed pipeline {}.", pipeline_id), @@ -3086,6 +3094,7 @@ impl ScriptThread { point, &self.topmost_mouse_over_target, node_address, + pressed_mouse_buttons, ); // Short-circuit if nothing changed @@ -3185,6 +3194,7 @@ impl ScriptThread { point: Point2D<f32>, node_address: Option<UntrustedNodeAddress>, point_in_node: Option<Point2D<f32>>, + pressed_mouse_buttons: u16, ) { let document = match { self.documents.borrow().find_document(pipeline_id) } { Some(document) => document, @@ -3197,6 +3207,7 @@ impl ScriptThread { mouse_event_type, node_address, point_in_node, + pressed_mouse_buttons, ); } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 0e5fc316037..d5a030323f6 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -444,11 +444,11 @@ pub struct TouchId(pub i32); #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub enum MouseButton { /// The left mouse button. - Left, - /// The middle mouse button. - Middle, + Left = 1, /// The right mouse button. - Right, + Right = 2, + /// The middle mouse button. + Middle = 4, } /// The types of mouse events @@ -474,9 +474,16 @@ pub enum CompositorEvent { Point2D<f32>, Option<UntrustedNodeAddress>, Option<Point2D<f32>>, + // Bitmask of MouseButton values representing the currently pressed buttons + u16, ), /// The mouse was moved over a point (or was moved out of the recognizable region). - MouseMoveEvent(Option<Point2D<f32>>, Option<UntrustedNodeAddress>), + MouseMoveEvent( + Option<Point2D<f32>>, + Option<UntrustedNodeAddress>, + // Bitmask of MouseButton values representing the currently pressed buttons + u16, + ), /// A touch event was generated with a touch ID and location. TouchEvent( TouchEventType, |