Bug 1273137 - Add the missing main-thread target confirmation for drag blocks. r?rbarker
This patch also cleans up some inconsistencies in the conditions under which the
main thread would respond to wheel and mouse events. With this patch applied, the
main-thread notifications are only sent if the input block id is nonzero, which
indicates the APZ actually processed the input event and added it to an input
block.
MozReview-Commit-ID: GBlgj6whi5T
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1904,53 +1904,63 @@ TabChild::RecvSynthMouseMoveEvent(const
return RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
}
bool
TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
+ if (aInputBlockId) {
+ MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
+ nsCOMPtr<nsIDocument> document(GetDocument());
+ APZCCallbackHelper::SendSetTargetAPZCNotification(
+ mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
+ }
+
nsEventStatus unused;
InputAPZContext context(aGuid, aInputBlockId, unused);
WidgetMouseEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (aEvent.mFlags.mHandledByAPZ) {
+ if (aInputBlockId) {
+ MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
mAPZEventState->ProcessMouseEvent(aEvent, aGuid, aInputBlockId);
}
return true;
}
bool
TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
- if (aEvent.mFlags.mHandledByAPZ) {
+ if (aInputBlockId) {
+ MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
nsCOMPtr<nsIDocument> document(GetDocument());
APZCCallbackHelper::SendSetTargetAPZCNotification(
mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
}
WidgetWheelEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (localEvent.mCanTriggerSwipe) {
SendRespondStartSwipeEvent(aInputBlockId, localEvent.TriggersSwipe());
}
- if (aEvent.mFlags.mHandledByAPZ) {
+ if (aInputBlockId) {
+ MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
mAPZEventState->ProcessWheelEvent(localEvent, aGuid, aInputBlockId);
}
return true;
}
bool
TabChild::RecvMouseScrollTestEvent(const uint64_t& aLayersId,
const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -757,16 +757,19 @@ APZCCallbackHelper::SendSetTargetAPZCNot
if (const WidgetTouchEvent* touchEvent = aEvent.AsTouchEvent()) {
for (size_t i = 0; i < touchEvent->mTouches.Length(); i++) {
waitForRefresh |= PrepareForSetTargetAPZCNotification(aWidget, aGuid,
rootFrame, touchEvent->mTouches[i]->mRefPoint, &targets);
}
} else if (const WidgetWheelEvent* wheelEvent = aEvent.AsWheelEvent()) {
waitForRefresh = PrepareForSetTargetAPZCNotification(aWidget, aGuid,
rootFrame, wheelEvent->mRefPoint, &targets);
+ } else if (const WidgetMouseEvent* mouseEvent = aEvent.AsMouseEvent()) {
+ waitForRefresh = PrepareForSetTargetAPZCNotification(aWidget, aGuid,
+ rootFrame, mouseEvent->mRefPoint, &targets);
}
// TODO: Do other types of events need to be handled?
if (!targets.IsEmpty()) {
SendSetTargetAPZCNotificationHelper(
aWidget,
shell,
aInputBlockId,
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -354,18 +354,21 @@ APZEventState::ProcessWheelEvent(const W
mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented);
}
void
APZEventState::ProcessMouseEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
{
- // If we get here and the input block has not been confirmed then
- // no scrollbar reacted to the event thus APZC should ignore this block.
+ // If we get here and the drag block has not been confirmed by the code in
+ // nsSliderFrame, then no scrollbar reacted to the event thus APZC will
+ // ignore this drag block. We can send defaultPrevented as either true or
+ // false, it doesn't matter, because APZ won't have the scrollbar metrics
+ // anyway, and will know to drop the block.
bool defaultPrevented = false;
mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented);
}
void
APZEventState::ProcessAPZStateChange(const nsCOMPtr<nsIDocument>& aDocument,
ViewID aViewId,
APZStateChange aChange,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1097,25 +1097,27 @@ nsBaseWidget::ProcessUntransformedAPZEve
mSetAllowedTouchBehaviorCallback);
}
APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
*(original->AsTouchEvent()), aGuid, aInputBlockId);
}
mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId,
aApzResponse, status);
} else if (WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent()) {
- if (wheelEvent->mFlags.mHandledByAPZ) {
- APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
- *(original->AsWheelEvent()), aGuid, aInputBlockId);
- if (wheelEvent->mCanTriggerSwipe) {
- ReportSwipeStarted(aInputBlockId, wheelEvent->TriggersSwipe());
- }
- mAPZEventState->ProcessWheelEvent(*wheelEvent, aGuid, aInputBlockId);
+ MOZ_ASSERT(wheelEvent->mFlags.mHandledByAPZ);
+ APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
+ *(original->AsWheelEvent()), aGuid, aInputBlockId);
+ if (wheelEvent->mCanTriggerSwipe) {
+ ReportSwipeStarted(aInputBlockId, wheelEvent->TriggersSwipe());
}
+ mAPZEventState->ProcessWheelEvent(*wheelEvent, aGuid, aInputBlockId);
} else if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
+ MOZ_ASSERT(mouseEvent->mFlags.mHandledByAPZ);
+ APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
+ *(original->AsMouseEvent()), aGuid, aInputBlockId);
mAPZEventState->ProcessMouseEvent(*mouseEvent, aGuid, aInputBlockId);
}
}
return status;
}
class DispatchWheelEventOnMainThread : public Runnable