Add support for mouse wheel transactions. (bug 1013432 part 6, r=kats)

--HG--
extra : rebase_source : 7230d0bac38e3faf3c7da2ecaf406b2e02f51146
This commit is contained in:
David Anderson 2014-12-09 02:40:26 -08:00
parent f3c8767c3b
commit 9156e4bc2e
4 changed files with 110 additions and 45 deletions

View File

@ -469,7 +469,7 @@ child:
RealMouseEvent(WidgetMouseEvent event);
RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
MouseWheelEvent(WidgetWheelEvent event);
MouseWheelEvent(WidgetWheelEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);

View File

@ -2288,11 +2288,31 @@ TabChild::RecvRealMouseEvent(const WidgetMouseEvent& event)
}
bool
TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& event)
TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
WidgetWheelEvent localEvent(event);
localEvent.widget = mWidget;
DispatchWidgetEvent(localEvent);
if (IsAsyncPanZoomEnabled()) {
nsCOMPtr<nsIDocument> document(GetDocument());
if (nsIPresShell* shell = document->GetShell()) {
if (nsIFrame* rootFrame = shell->GetRootFrame()) {
nsTArray<ScrollableLayerGuid> targets;
nsIntPoint refPoint(aEvent.refPoint.x, aEvent.refPoint.y);
bool waitForRefresh =
PrepareForSetTargetAPZCNotification(aGuid, aInputBlockId, rootFrame, refPoint, &targets);
SendSetTargetAPZCNotification(shell, aInputBlockId, targets, waitForRefresh);
}
}
}
WidgetWheelEvent event(aEvent);
event.widget = mWidget;
DispatchWidgetEvent(event);
if (IsAsyncPanZoomEnabled()) {
SendContentReceivedInputBlock(aGuid, aInputBlockId, event.mFlags.mDefaultPrevented);
}
return true;
}
@ -2512,6 +2532,62 @@ private:
nsTArray<ScrollableLayerGuid> mTargets;
};
bool
TabChild::PrepareForSetTargetAPZCNotification(const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
nsIFrame* aRootFrame,
const nsIntPoint& aRefPoint,
nsTArray<ScrollableLayerGuid>* aTargets)
{
ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID);
nsPoint point =
nsLayoutUtils::GetEventCoordinatesRelativeTo(WebWidget(), aRefPoint, aRootFrame);
nsIFrame* target =
nsLayoutUtils::GetFrameForPoint(aRootFrame, point, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
nsIScrollableFrame* scrollAncestor = GetScrollableAncestorFrame(target);
nsCOMPtr<dom::Element> dpElement = GetDisplayportElementFor(scrollAncestor);
nsAutoString dpElementDesc;
if (dpElement) {
dpElement->Describe(dpElementDesc);
}
TABC_LOG("For input block %" PRIu64 " found scrollable element %p (%s)\n",
aInputBlockId, dpElement.get(),
NS_LossyConvertUTF16toASCII(dpElementDesc).get());
bool guidIsValid = APZCCallbackHelper::GetOrCreateScrollIdentifiers(
dpElement, &(guid.mPresShellId), &(guid.mScrollId));
aTargets->AppendElement(guid);
if (!guidIsValid || nsLayoutUtils::GetDisplayPort(dpElement, nullptr)) {
return false;
}
TABC_LOG("%p didn't have a displayport, so setting one...\n", dpElement.get());
return nsLayoutUtils::CalculateAndSetDisplayPortMargins(
scrollAncestor, nsLayoutUtils::RepaintMode::Repaint);
}
void
TabChild::SendSetTargetAPZCNotification(nsIPresShell* aShell,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets,
bool aWaitForRefresh)
{
bool waitForRefresh = aWaitForRefresh;
if (waitForRefresh) {
TABC_LOG("At least one target got a new displayport, need to wait for refresh\n");
waitForRefresh = aShell->AddPostRefreshObserver(
new DisplayportSetListener(this, aShell, aInputBlockId, aTargets));
}
if (!waitForRefresh) {
TABC_LOG("Sending target APZCs for input block %" PRIu64 "\n", aInputBlockId);
SendSetTargetAPZC(aInputBlockId, aTargets);
} else {
TABC_LOG("Successfully registered post-refresh observer\n");
}
}
void
TabChild::SendSetTargetAPZCNotification(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
@ -2530,43 +2606,10 @@ TabChild::SendSetTargetAPZCNotification(const WidgetTouchEvent& aEvent,
bool waitForRefresh = false;
nsTArray<ScrollableLayerGuid> targets;
for (size_t i = 0; i < aEvent.touches.Length(); i++) {
ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID);
nsPoint touchPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(
WebWidget(), aEvent.touches[i]->mRefPoint, rootFrame);
nsIFrame* target = nsLayoutUtils::GetFrameForPoint(rootFrame, touchPoint,
nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
nsIScrollableFrame* scrollAncestor = GetScrollableAncestorFrame(target);
nsCOMPtr<dom::Element> dpElement = GetDisplayportElementFor(scrollAncestor);
nsAutoString dpElementDesc;
if (dpElement) {
dpElement->Describe(dpElementDesc);
}
TABC_LOG("For input block %" PRIu64 " found scrollable element %p (%s)\n",
aInputBlockId, dpElement.get(),
NS_LossyConvertUTF16toASCII(dpElementDesc).get());
bool guidIsValid = APZCCallbackHelper::GetOrCreateScrollIdentifiers(
dpElement, &(guid.mPresShellId), &(guid.mScrollId));
targets.AppendElement(guid);
if (guidIsValid && !nsLayoutUtils::GetDisplayPort(dpElement, nullptr)) {
TABC_LOG("%p didn't have a displayport, so setting one...\n", dpElement.get());
waitForRefresh |= nsLayoutUtils::CalculateAndSetDisplayPortMargins(
scrollAncestor, nsLayoutUtils::RepaintMode::Repaint);
}
}
if (waitForRefresh) {
TABC_LOG("At least one target got a new displayport, need to wait for refresh\n");
waitForRefresh = shell->AddPostRefreshObserver(
new DisplayportSetListener(this, shell, aInputBlockId, targets));
}
if (!waitForRefresh) {
TABC_LOG("Sending target APZCs for input block %" PRIu64 "\n", aInputBlockId);
SendSetTargetAPZC(aInputBlockId, targets);
} else {
TABC_LOG("Successfully registered post-refresh observer\n");
waitForRefresh |= PrepareForSetTargetAPZCNotification(aGuid, aInputBlockId,
rootFrame, aEvent.touches[i]->mRefPoint, &targets);
}
SendSetTargetAPZCNotification(shell, aInputBlockId, targets, waitForRefresh);
}
bool

View File

@ -352,7 +352,9 @@ public:
virtual bool RecvRealMouseEvent(const mozilla::WidgetMouseEvent& event) MOZ_OVERRIDE;
virtual bool RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& event,
const MaybeNativeKeyBinding& aBindings) MOZ_OVERRIDE;
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event) MOZ_OVERRIDE;
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) MOZ_OVERRIDE;
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) MOZ_OVERRIDE;
@ -578,6 +580,22 @@ private:
void SendPendingTouchPreventedResponse(bool aPreventDefault,
const ScrollableLayerGuid& aGuid);
// Adds the scrollable layer target to the target list, and returns whether
// or not the caller should wait for a refresh to send a target
// notification.
bool PrepareForSetTargetAPZCNotification(const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
nsIFrame* aRootFrame,
const nsIntPoint& aRefPoint,
nsTArray<ScrollableLayerGuid>* aTargets);
// Sends a SetTarget notification for APZC, given one or more previous
// calls to PrepareForAPZCSetTargetNotification().
void SendSetTargetAPZCNotification(nsIPresShell* aShell,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets,
bool aWaitForRefresh);
void SendSetTargetAPZCNotification(const WidgetTouchEvent& aEvent,
const mozilla::layers::ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId);

View File

@ -987,12 +987,16 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
if (mIsDestroyed) {
return false;
}
nsEventStatus status = MaybeForwardEventToRenderFrame(event, nullptr, nullptr);
ScrollableLayerGuid guid;
uint64_t blockId;
nsEventStatus status = MaybeForwardEventToRenderFrame(event, &guid, &blockId);
if (status == nsEventStatus_eConsumeNoDefault ||
!MapEventCoordinatesForChildProcess(&event)) {
!MapEventCoordinatesForChildProcess(&event))
{
return false;
}
return PBrowserParent::SendMouseWheelEvent(event);
return PBrowserParent::SendMouseWheelEvent(event, guid, blockId);
}
static void