From bcfd6cd96195f2d0c7c28435c56ca613d7a6e3eb Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Fri, 29 Mar 2019 09:47:35 +0000 Subject: [PATCH] Bug 1409085 - Tell RDM when picking to stop simulating touch; r=mtigley,gl Differential Revision: https://phabricator.services.mozilla.com/D25231 --HG-- extra : moz-landing-system : lando --- devtools/client/framework/toolbox.js | 23 ++++++++++++++++++ devtools/server/actors/emulation.js | 24 +++++++++++++++++++ .../actors/emulation/touch-simulator.js | 16 +++++++++++++ devtools/shared/specs/emulation.js | 7 ++++++ 4 files changed, 70 insertions(+) diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 3a46f2497c99..3426c0b4454c 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -64,6 +64,8 @@ loader.lazyRequireGetter(this, "createEditContextMenu", "devtools/client/framework/toolbox-context-menu", true); loader.lazyRequireGetter(this, "remoteClientManager", "devtools/client/shared/remote-debugging/remote-client-manager.js", true); +loader.lazyRequireGetter(this, "ResponsiveUIManager", + "devtools/client/responsive.html/manager", true); loader.lazyGetter(this, "domNodeConstants", () => { return require("devtools/shared/dom-node-constants"); @@ -1343,6 +1345,7 @@ Toolbox.prototype = { }, _onPickerStarting: async function() { + this.tellRDMAboutPickerState(true); this.pickerButton.isChecked = true; await this.selectTool("inspector", "inspect_dom"); this.on("select", this.inspector.nodePicker.stop); @@ -1354,11 +1357,31 @@ Toolbox.prototype = { }, _onPickerStopped: function() { + this.tellRDMAboutPickerState(false); this.off("select", this.inspector.nodePicker.stop); this.doc.removeEventListener("keypress", this._onPickerKeypress, true); this.pickerButton.isChecked = false; }, + /** + * RDM sometimes simulates touch events. For this to work correctly at all times, it + * needs to know when the picker is active or not. + * This method communicates with the RDM Manager if it exists. + * + * @param {Boolean} state + */ + tellRDMAboutPickerState: async function(state) { + const { tab } = this.target; + + if (!ResponsiveUIManager.isActiveForTab(tab) || + await !this.target.actorHasMethod("emulation", "setElementPickerState")) { + return; + } + + const ui = ResponsiveUIManager.getResponsiveUIForTab(tab); + await ui.emulationFront.setElementPickerState(state); + }, + /** * When the picker is canceled, make sure the toolbox * gets the focus. diff --git a/devtools/server/actors/emulation.js b/devtools/server/actors/emulation.js index ab00b246ebbf..c3c6f4585d71 100644 --- a/devtools/server/actors/emulation.js +++ b/devtools/server/actors/emulation.js @@ -177,6 +177,30 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, { _previousTouchEventsOverride: undefined, + /** + * Set the current element picker state. + * + * True means the element picker is currently active and we should not be emulating + * touch events. + * False means the element picker is not active and it is ok to emulate touch events. + * + * This actor method is meant to be called by the DevTools front-end. The reason for + * this is the following: + * RDM is the only current consumer of the touch simulator. RDM instantiates this actor + * on its own, whether or not the Toolbox is opened. That means it does so in its own + * Debugger Server instance. + * When the Toolbox is running, it uses a different DebuggerServer. Therefore, it is not + * possible for the touch simulator to know whether the picker is active or not. This + * state has to be sent by the client code of the Toolbox to this actor. + * If a future use case arises where we want to use the touch simulator from the Toolbox + * too, then we could add code in here to detect the picker mode as described in + * https://bugzilla.mozilla.org/show_bug.cgi?id=1409085#c3 + * @param {Boolean} state + */ + setElementPickerState(state) { + this.touchSimulator.setElementPickerState(state); + }, + setTouchEventsOverride(flag) { if (this.getTouchEventsOverride() == flag) { return false; diff --git a/devtools/server/actors/emulation/touch-simulator.js b/devtools/server/actors/emulation/touch-simulator.js index cccecbf0a243..88834ff63ddf 100644 --- a/devtools/server/actors/emulation/touch-simulator.js +++ b/devtools/server/actors/emulation/touch-simulator.js @@ -73,7 +73,23 @@ TouchSimulator.prototype = { this.enabled = false; }, + /** + * Set the current element picker state value. + * True means the element picker is currently active and we should not be emulating + * touch events. + * False means the element picker is not active and it is ok to emulate touch events. + * @param {Boolean} state + */ + setElementPickerState(state) { + this._isPicking = state; + }, + handleEvent(evt) { + // Bail out if devtools is in pick mode in the same tab. + if (this._isPicking) { + return; + } + // The gaia system window use an hybrid system even on the device which is // a mix of mouse/touch events. So let's not cancel *all* mouse events // if it is the current target. diff --git a/devtools/shared/specs/emulation.js b/devtools/shared/specs/emulation.js index bf716d5d5d15..f0448d2ea191 100644 --- a/devtools/shared/specs/emulation.js +++ b/devtools/shared/specs/emulation.js @@ -123,6 +123,13 @@ const emulationSpec = generateActorSpec({ valueChanged: RetVal("boolean"), }, }, + + setElementPickerState: { + request: { + state: Arg(0, "boolean"), + }, + response: {}, + }, }, });