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"
#endif
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracer.h"
using namespace mozilla::tasktracer;
@@ -5450,16 +5451,23 @@ PresShell::ProcessSynthMouseMoveEvent(bo
WidgetMouseEvent::eSynthesized);
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) {
mSynthMouseMoveEvent.Forget();
}
}
@@ -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();
}
#ifdef DEBUG_MOUSE_LOCATION
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.
mMouseLocation = nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ mMouseEventTargetGuid = InputAPZContext::GetTargetLayerGuid();
#ifdef DEBUG_MOUSE_LOCATION
printf("[ps=%p]got mouse exit for %p\n",
this, aEvent->widget);
printf("[ps=%p]clearing mouse location\n",
this);
#endif
}
}
--- 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;