Bug 1242690 - Make sure that synthetic mouse events have a reasonable guid so that the callback transform can get unapplied properly. r= draft
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 27 Jan 2016 10:08:44 -0500
changeset 326163 2c536c68dd558c4ff2b97e68268fec7fbb23db5f
parent 326162 45f6023648fd50ab52a5cb52ede28c9e18a57240
child 513563 adcd6952b34c1e3fface0838502f9ffa0350dff4
push id10106
push userkgupta@mozilla.com
push dateWed, 27 Jan 2016 15:11:06 +0000
Bug 1242690 - Make sure that synthetic mouse events have a reasonable guid so that the callback transform can get unapplied properly. r=
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -178,16 +178,17 @@
 #include "RestyleManager.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDragSession.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/gfx/2D.h"
 #include "nsSubDocumentFrame.h"
 #include "nsQueryObject.h"
 #include "nsLayoutStylesheetCache.h"
+#include "mozilla/layers/InputAPZContext.h"
 #ifdef ANDROID
 #include "nsIDocShellTreeOwner.h"
 #include "GeckoTaskTracer.h"
 using namespace mozilla::tasktracer;
@@ -5450,16 +5451,23 @@ PresShell::ProcessSynthMouseMoveEvent(bo
   event.refPoint = LayoutDeviceIntPoint::FromAppUnitsToNearest(refpoint, viewAPD);
   event.time = PR_IntervalNow();
   // XXX set event.modifiers ?
   // XXX mnakano I think that we should get the latest information from widget.
   nsCOMPtr<nsIPresShell> shell = pointVM->GetPresShell();
   if (shell) {
+    // Since this gets run in a refresh tick there isn't an InputAPZContext on
+    // the stack from the nsBaseWidget. We need to simulate one with at least
+    // the correct target guid, so that the correct callback transform gets
+    // applied if this event goes to a child process. The input block id is set
+    // to 0 because this is a synthetic event which doesn't really belong to any
+    // input block. Same for the APZ response field.
+    InputAPZContext apzContext(mMouseEventTargetGuid, 0, nsEventStatus_eIgnore);
     shell->DispatchSynthMouseMove(&event, !aFromScroll);
   if (!aFromScroll) {
@@ -6418,19 +6426,21 @@ PresShell::RecordMouseLocation(WidgetGUI
       aEvent->mMessage == eMouseEnterIntoWidget ||
       aEvent->mMessage == eMouseDown ||
       aEvent->mMessage == eMouseUp) {
     nsIFrame* rootFrame = GetRootFrame();
     if (!rootFrame) {
       nsView* rootView = mViewManager->GetRootView();
       mMouseLocation = nsLayoutUtils::TranslateWidgetToView(mPresContext,
         aEvent->widget, aEvent->refPoint, rootView);
+      mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
     } else {
       mMouseLocation =
         nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
+      mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
     if (aEvent->mMessage == eMouseEnterIntoWidget) {
       printf("[ps=%p]got mouse enter for %p\n",
              this, aEvent->widget);
     printf("[ps=%p]setting mouse location to (%d,%d)\n",
            this, mMouseLocation.x, mMouseLocation.y);
@@ -6440,16 +6450,17 @@ PresShell::RecordMouseLocation(WidgetGUI
   } else if (aEvent->mMessage == eMouseExitFromWidget) {
     // Although we only care about the mouse moving into an area for which this
     // pres shell doesn't receive mouse move events, we don't check which widget
     // the mouse exit was for since this seems to vary by platform.  Hopefully
     // this won't matter at all since we'll get the mouse move or enter after
     // the mouse exit when the mouse moves from one of our widgets into another.
+    mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
     printf("[ps=%p]got mouse exit for %p\n",
            this, aEvent->widget);
     printf("[ps=%p]clearing mouse location\n",
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -774,16 +774,19 @@ protected:
   // the mouse pointer may have changed without the mouse moving (eg scrolling,
   // change to the document contents).
   // It is set only on a presshell for a root document, this value represents
   // the last observed location of the mouse relative to that root document. It
   // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
   // over our window or there is no last observed mouse location for some
   // reason.
   nsPoint                   mMouseLocation;
+  // This is an APZ state variable that goes with mMouseLocation and is needed
+  // for the synthetic mouse events.
+  mozilla::layers::ScrollableLayerGuid mMouseEventTargetGuid;
   // mStyleSet owns it but we maintain a ref, may be null
   RefPtr<mozilla::CSSStyleSheet> mPrefStyleSheet;
   // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
   // we finish reflowing mCurrentReflowRoot.
   nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;