From b6719b756ffecfb3da75145423bb3d2370ac4a59 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Thu, 2 May 2019 17:51:30 +0000 Subject: [PATCH] Bug 1545296 - Suppress mouse button events firing in content when clicking on the Picture-in-Picture toggle. r=jaws Differential Revision: https://phabricator.services.mozilla.com/D29422 --HG-- extra : moz-landing-system : lando --- toolkit/actors/PictureInPictureChild.jsm | 121 +++++++++++++++++++---- toolkit/modules/ActorManagerParent.jsm | 1 + 2 files changed, 105 insertions(+), 17 deletions(-) diff --git a/toolkit/actors/PictureInPictureChild.jsm b/toolkit/actors/PictureInPictureChild.jsm index c8710584f524..c16520c86b37 100644 --- a/toolkit/actors/PictureInPictureChild.jsm +++ b/toolkit/actors/PictureInPictureChild.jsm @@ -74,6 +74,13 @@ class PictureInPictureToggleChild extends ActorChild { mousemoveDeferredTask: null, // A weak reference to the last video we displayed the toggle over. weakOverVideo: null, + // True if the user is in the midst of clicking the toggle. + isClickingToggle: false, + // Set to the original target element on pointerdown if the user is clicking + // the toggle - this way, we can determine if a "click" event will need to be + // suppressed ("click" events don't fire if a "mouseup" occurs on a different + // element from the "pointerdown" / "mousedown" event). + clickedElement: null, }; this.weakDocStates.set(this.content.document, state); } @@ -98,14 +105,27 @@ class PictureInPictureToggleChild extends ActorChild { } break; } - case "mousedown": { - this.onMouseDown(event); + case "mousedown": + case "pointerup": + case "mouseup": + case "click": { + this.onMouseButtonEvent(event); + break; + } + case "pointerdown": { + this.onPointerDown(event); break; } case "mousemove": { this.onMouseMove(event); break; } + case "pagehide": { + if (event.target.top == event.target) { + this.removeMouseButtonListeners(); + } + break; + } } } @@ -200,6 +220,40 @@ class PictureInPictureToggleChild extends ActorChild { } } + addMouseButtonListeners() { + // We want to try to cancel the mouse events from continuing + // on into content if the user has clicked on the toggle, so + // we don't use the mozSystemGroup here, and add the listener + // to the parent target of the window, which in this case, + // is the windowRoot. Since this event listener is attached to + // part of the outer window, we need to also remove it in a + // pagehide event listener in the event that the page unloads + // before stopTrackingMouseOverVideos fires. + this.content.windowRoot.addEventListener("pointerdown", this, + { capture: true }); + this.content.windowRoot.addEventListener("mousedown", this, + { capture: true }); + this.content.windowRoot.addEventListener("mouseup", this, + { capture: true }); + this.content.windowRoot.addEventListener("pointerup", this, + { capture: true }); + this.content.windowRoot.addEventListener("click", this, + { capture: true }); + } + + removeMouseButtonListeners() { + this.content.windowRoot.removeEventListener("pointerdown", this, + { capture: true }); + this.content.windowRoot.removeEventListener("mousedown", this, + { capture: true }); + this.content.windowRoot.removeEventListener("mouseup", this, + { capture: true }); + this.content.windowRoot.removeEventListener("pointerup", this, + { capture: true }); + this.content.windowRoot.removeEventListener("click", this, + { capture: true }); + } + /** * One of the challenges of displaying this toggle is that many sites put * things over top of