Bug 1233272 - Suppress event retargeting for mouse events generated via longpress. r=snorp

Instead of just special-casing the eContextMenu and eMouseLongTap events in
PositionedEventTargeting, this adds a mechanism to suppress retargeting for
any events dispatched from a particular code block. This allows us to also
suppress retargeting the mousemove that precedes the eContextMenu, while still
retargeting any other mousemove events (e.g. the one that precedes a click).
Doing this is important because if the mousemove is retargeted, it can trigger
the hover pseudoclass CSS on an element when that element is not actually
going to be activated at all, and can be confusing to the user.

Depends on D65211

Differential Revision: https://phabricator.services.mozilla.com/D65212

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kartikaya Gupta 2020-03-04 20:24:55 +00:00
Родитель 2112e26256
Коммит 3fe82f3ca4
4 изменённых файлов: 24 добавлений и 1 удалений

Просмотреть файл

@ -14,6 +14,7 @@
#include "TouchManager.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/PositionedEventTargeting.h"
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_dom.h"
@ -206,6 +207,9 @@ bool APZEventState::FireContextmenuEvents(PresShell* aPresShell,
const CSSToLayoutDeviceScale& aScale,
Modifiers aModifiers,
const nsCOMPtr<nsIWidget>& aWidget) {
// Suppress retargeting for mouse events generated by a long-press
EventRetargetSuppression suppression;
// Synthesize mousemove event for allowing users to emulate to move mouse
// cursor over the element. As a result, users can open submenu UI which
// is opened when mouse cursor is moved over a link (i.e., it's a case that

Просмотреть файл

@ -415,7 +415,7 @@ nsIFrame* FindFrameTargetedByInputEvent(
aRootFrame);
const EventRadiusPrefs* prefs = GetPrefsFor(aEvent->mClass);
if (!prefs || !prefs->mEnabled) {
if (!prefs || !prefs->mEnabled || EventRetargetSuppression::IsActive()) {
PET_LOG("Retargeting disabled\n");
return target;
}
@ -509,4 +509,12 @@ nsIFrame* FindFrameTargetedByInputEvent(
return target;
}
uint32_t EventRetargetSuppression::sSuppressionCount = 0;
EventRetargetSuppression::EventRetargetSuppression() { sSuppressionCount++; }
EventRetargetSuppression::~EventRetargetSuppression() { sSuppressionCount--; }
bool EventRetargetSuppression::IsActive() { return sSuppressionCount > 0; }
} // namespace mozilla

Просмотреть файл

@ -25,6 +25,16 @@ nsIFrame* FindFrameTargetedByInputEvent(
WidgetGUIEvent* aEvent, nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame, uint32_t aFlags = 0);
class MOZ_RAII EventRetargetSuppression {
public:
EventRetargetSuppression();
~EventRetargetSuppression();
static bool IsActive();
private:
static uint32_t sSuppressionCount;
};
} // namespace mozilla
#endif /* mozilla_PositionedEventTargeting_h */

Просмотреть файл

@ -78,6 +78,7 @@ EXPORTS.mozilla += [
'MotionPathUtils.h',
'MVMContext.h',
'OverflowChangedTracker.h',
'PositionedEventTargeting.h',
'PresShell.h',
'PresShellForwards.h',
'PresShellInlines.h',