Bug 1409113 - Add nsIPresShell::HasHandledUserInput() r=masayuki
MozReview-Commit-ID: 3Yr5UmFJx5h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -798,16 +798,17 @@ PresShell::PresShell()
, mAsyncResizeTimerIsActive(false)
, mInResize(false)
, mApproximateFrameVisibilityVisited(false)
, mNextPaintCompressed(false)
, mHasCSSBackgroundColor(false)
, mScaleToResolution(false)
, mIsLastChromeOnlyEscapeKeyConsumed(false)
, mHasReceivedPaintMessage(false)
+ , mHasHandledUserInput(false)
{
MOZ_LOG(gLog, LogLevel::Debug, ("PresShell::PresShell this=%p", this));
#ifdef MOZ_REFLOW_PERF
mReflowCountMgr = new ReflowCountMgr();
mReflowCountMgr->SetPresContext(mPresContext);
mReflowCountMgr->SetPresShell(this);
#endif
@@ -7648,16 +7649,20 @@ PresShell::HandleEventInternal(WidgetEve
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
fm->FlushBeforeEventHandlingIfNeeded(mCurrentEventContent);
}
}
// XXX How about IME events and input events for plugins?
if (aEvent->IsTrusted()) {
+ if (aEvent->IsUserAction()) {
+ mHasHandledUserInput = true;
+ }
+
switch (aEvent->mMessage) {
case eKeyPress:
case eKeyDown:
case eKeyUp: {
nsIDocument* doc = GetCurrentEventContent() ?
mCurrentEventContent->OwnerDoc() : nullptr;
auto keyCode = aEvent->AsKeyboardEvent()->mKeyCode;
if (keyCode == NS_VK_ESCAPE) {
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -404,16 +404,20 @@ public:
void SetNextPaintCompressed() { mNextPaintCompressed = true; }
void NotifyStyleSheetServiceSheetAdded(mozilla::StyleSheet* aSheet,
uint32_t aSheetType) override;
void NotifyStyleSheetServiceSheetRemoved(mozilla::StyleSheet* aSheet,
uint32_t aSheetType) override;
+ virtual bool HasHandledUserInput() const override {
+ return mHasHandledUserInput;
+ }
+
protected:
virtual ~PresShell();
void HandlePostedReflowCallbacks(bool aInterruptible);
void CancelPostedReflowCallbacks();
void ScheduleBeforeFirstPaint();
void UnsuppressAndInvalidate();
@@ -888,16 +892,19 @@ protected:
// Whether the last chrome-only escape key event is consumed.
bool mIsLastChromeOnlyEscapeKeyConsumed : 1;
// Whether the widget has received a paint message yet.
bool mHasReceivedPaintMessage : 1;
bool mIsLastKeyDownCanceled : 1;
+ // Whether we have ever handled a user input event
+ bool mHasHandledUserInput : 1;
+
static bool sDisableNonTestMouseEvents;
mozilla::TimeStamp mLastOSWake;
static mozilla::TimeStamp sLastInputCreated;
static mozilla::TimeStamp sLastInputProcessed;
static bool sProcessInteractable;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1567,16 +1567,21 @@ public:
* specified level of the cascade is shared by multiple style sets.
*
* @param aSheetType One of the nsIStyleSheetService.*_SHEET constants.
*/
nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
bool* aRetVal);
/**
+ * Returns whether or not the document has ever handled user input
+ */
+ virtual bool HasHandledUserInput() const = 0;
+
+ /**
* Refresh observer management.
*/
protected:
void DoObserveStyleFlushes();
void DoObserveLayoutFlushes();
/**
* Does the actual work of figuring out the current state of font size
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -995,16 +995,18 @@ public:
// nsVideoFrame may create anonymous image element which fires eLoad,
// eLoadStart, eLoadEnd, eLoadError. We don't want these events cross
// the boundary of NAC
mFlags.mComposedInNativeAnonymousContent = mMessage != eLoad &&
mMessage != eLoadStart &&
mMessage != eLoadEnd &&
mMessage != eLoadError;
}
+
+ bool IsUserAction() const;
};
/******************************************************************************
* mozilla::NativeEventData
*
* WidgetGUIEvent's mPluginEvent member used to be a void* pointer,
* used to reference external, OS-specific data structures.
*
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -536,16 +536,45 @@ WidgetEvent::PreventDefault(bool aCalled
// Ignore the case that it's called by a web extension.
return;
}
}
}
mFlags.PreventDefault(aCalledByDefaultHandler);
}
+bool
+WidgetEvent::IsUserAction() const
+{
+ if (!IsTrusted()) {
+ return false;
+ }
+ // FYI: eMouseScrollEventClass and ePointerEventClass represent
+ // user action but they are synthesized events.
+ switch (mClass) {
+ case eKeyboardEventClass:
+ case eCompositionEventClass:
+ case eMouseScrollEventClass:
+ case eWheelEventClass:
+ case eGestureNotifyEventClass:
+ case eSimpleGestureEventClass:
+ case eTouchEventClass:
+ case eCommandEventClass:
+ case eContentCommandEventClass:
+ case ePluginEventClass:
+ return true;
+ case eMouseEventClass:
+ case eDragEventClass:
+ case ePointerEventClass:
+ return AsMouseEvent()->IsReal();
+ default:
+ return false;
+ }
+}
+
/******************************************************************************
* mozilla::WidgetInputEvent
******************************************************************************/
/* static */
Modifier
WidgetInputEvent::GetModifier(const nsAString& aDOMKeyName)
{