import change from rmottola/Arctic-Fox:

- revert PaleMoon HSCROLL (077a87aed)
- If APZ is enabled, do not handle wheel-event scrolling in layout. (bug 1126090 part 1) (8c0ba79d6)
- Factor out how APZ-aware events are dispatched from widgets. (bug 1126090 part 2) (fb6b7e57b)
- Events synthesized in the child process must be propagated back to the parent. (bug 1126090 part 3) (5a4c9439e)
- Translate coordinates in events synthesized from the child process. (bug 1126090 part 4) (5148f7fc2)
- Wait for all paints to flush before synthesizing scroll events. (bug 1126090 part 5) (b99a19995)
- Don't try to async scroll frames that have less than one pixel of scrollability. (bug 1126090 part 7) (475ffa090)
This commit is contained in:
2019-05-31 07:25:07 +08:00
parent 365b9b17b6
commit 30bc5e7c6d
20 changed files with 131 additions and 58 deletions
+1 -3
View File
@@ -1030,9 +1030,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
nsEventStatus status;
nsresult rv = widget->DispatchEvent(&wheelEvent, status);
NS_ENSURE_SUCCESS(rv, rv);
widget->DispatchAPZAwareEvent(&wheelEvent);
bool failedX = false;
if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
+13 -7
View File
@@ -87,6 +87,7 @@
#include "mozilla/LookAndFeel.h"
#include "GoannaProfiler.h"
#include "Units.h"
#include "mozilla/layers/APZCTreeManager.h"
#ifdef XP_MACOSX
#import <ApplicationServices/ApplicationServices.h>
@@ -3046,13 +3047,18 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
switch (WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent)) {
case WheelPrefs::ACTION_HSCROLL: {
// Swap axes and fall through
double deltaX = wheelEvent->deltaX;
wheelEvent->deltaX = wheelEvent->deltaY;
wheelEvent->deltaY = deltaX;
}
// When APZ is enabled, the actual scroll animation might be handled by
// the compositor.
WheelPrefs::Action action;
if (gfxPrefs::AsyncPanZoomEnabled() &&
layers::APZCTreeManager::WillHandleWheelEvent(wheelEvent))
{
action = WheelPrefs::ACTION_NONE;
} else {
action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
}
switch (action) {
case WheelPrefs::ACTION_SCROLL: {
// For scrolling of default action, we should honor the mouse wheel
// transaction.
+1 -2
View File
@@ -447,8 +447,7 @@ protected:
ACTION_SCROLL,
ACTION_HISTORY,
ACTION_ZOOM,
ACTION_HSCROLL,
ACTION_LAST = ACTION_HSCROLL
ACTION_LAST = ACTION_ZOOM
};
Action ComputeActionFor(WidgetWheelEvent* aEvent);
+2 -1
View File
@@ -131,6 +131,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' # b2g(failing when the test g
[test_bug944011.html]
[test_bug944847.html]
[test_bug946632.html]
skip-if = buildapp == 'b2g'
[test_bug967796.html]
skip-if = toolkit == "gonk" || e10s
[test_bug985988.html]
@@ -165,7 +166,7 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
skip-if = buildapp == 'mulet'
[test_messageEvent.html]
[test_moz_mouse_pixel_scroll_event.html]
skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet' || buildapp == 'b2g' # bug 1126090, no wheel events on b2g
[test_onerror_handler_args.html]
[test_wheel_default_action.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
+5 -1
View File
@@ -7,6 +7,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=946632
<title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
.scrollable {
@@ -125,7 +126,10 @@ function nextTest()
var test = tests[i];
++i;
prepare(test.check);
test.test();
window.waitForAllPaintsFlushed(function() {
test.test();
});
}
function runTests()
+2
View File
@@ -484,6 +484,8 @@ parent:
*/
async SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCx, int32_t aCy);
prio(high) sync SynthesizedMouseWheelEvent(WidgetWheelEvent event);
child:
/**
* Notify the remote browser that it has been Show()n on this
+15
View File
@@ -1235,6 +1235,21 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
return PBrowserParent::SendMouseWheelEvent(event, guid, blockId);
}
bool TabParent::RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return true;
}
WidgetWheelEvent localEvent(aEvent);
localEvent.widget = widget;
localEvent.refPoint -= GetChildProcessOffset();
widget->DispatchAPZAwareEvent(&localEvent);
return true;
}
static void
DoCommandCallback(mozilla::Command aCommand, void* aData)
{
+1
View File
@@ -233,6 +233,7 @@ public:
const bool& aPreventDefault) override;
virtual bool RecvSetTargetAPZC(const uint64_t& aInputBlockId,
nsTArray<ScrollableLayerGuid>&& aTargets) override;
virtual bool RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override;
virtual PColorPickerParent*
AllocPColorPickerParent(const nsString& aTitle, const nsString& aInitialColor) override;
+8 -3
View File
@@ -854,6 +854,13 @@ APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
return status;
}
bool
APZCTreeManager::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
{
return EventStateManager::WheelEventIsScrollAction(aEvent) &&
aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE;
}
nsEventStatus
APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
@@ -891,9 +898,7 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
}
case eWheelEventClass: {
WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent();
if (wheelEvent.deltaMode != nsIDOMWheelEvent::DOM_DELTA_LINE ||
!EventStateManager::WheelEventIsScrollAction(&wheelEvent))
{
if (!WillHandleWheelEvent(&wheelEvent)) {
// Don't send through APZ if we're not scrolling or if the delta mode
// is not line-based.
return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId);
+9
View File
@@ -382,6 +382,15 @@ public:
*/
nsRefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain(const nsRefPtr<AsyncPanZoomController>& aInitialTarget);
public:
// Returns whether or not a wheel event action will be (or was) performed by
// APZ. If this returns true, the event must not perform a synchronous
// scroll.
//
// Even if this returns false, all wheel events in APZ-aware widgets must
// be sent through APZ so they are transformed correctly for TabParent.
static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~APZCTreeManager();
+5 -6
View File
@@ -1089,13 +1089,12 @@ static bool IsFocused(nsIContent* aContent)
bool
ScrollFrameHelper::WantAsyncScroll() const
{
nsRect scrollRange = GetScrollRange();
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
bool isVScrollable = (scrollRange.height > 0)
&& (styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN);
bool isHScrollable = (scrollRange.width > 0)
&& (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN);
uint32_t directions = mOuter->GetScrollTargetFrame()->GetPerceivedScrollingDirections();
bool isVScrollable = !!(directions & nsIScrollableFrame::VERTICAL) &&
(styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN);
bool isHScrollable = !!(directions & nsIScrollableFrame::HORIZONTAL) &&
(styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN);
#if defined(MOZ_B2G) || defined(MOZ_WIDGET_ANDROID)
// Mobile platforms need focus to scroll.
+1 -1
View File
@@ -83,7 +83,7 @@ support-files = bug633762_iframe.html
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug748961.html]
[test_bug784410.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
skip-if = buildapp == 'b2g' #Bug 931116, 1129060 no wheel events on b2g
[test_bug785324.html]
[test_bug791616.html]
skip-if = buildapp == 'b2g' # b2g(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438) b2g-debug(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438) b2g-desktop(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438)
+24
View File
@@ -328,6 +328,30 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
}
nsEventStatus
PuppetWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent)
{
if (!gfxPrefs::AsyncPanZoomEnabled()) {
nsEventStatus status = nsEventStatus_eIgnore;
DispatchEvent(aEvent, status);
return status;
}
if (!mTabChild) {
return nsEventStatus_eIgnore;
}
switch (aEvent->mClass) {
case eWheelEventClass:
mTabChild->SendSynthesizedMouseWheelEvent(*aEvent->AsWheelEvent());
break;
default:
MOZ_ASSERT_UNREACHABLE("unsupported event type");
}
return nsEventStatus_eIgnore;
}
NS_IMETHODIMP_(bool)
PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
const mozilla::WidgetKeyboardEvent& aEvent,
+1
View File
@@ -128,6 +128,7 @@ public:
void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr);
NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus) override;
nsEventStatus DispatchAPZAwareEvent(WidgetInputEvent* aEvent) override;
NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener,
bool aDoCapture) override
+1 -1
View File
@@ -326,7 +326,7 @@ nsWindow::DispatchTouchEventForAPZ(const MultiTouchInput& aInput,
// for "normal" flow. The event might get sent to the child process still,
// but if it doesn't we need to notify the APZ of various things. All of
// that happens in DispatchEventForAPZ
DispatchEventForAPZ(&event, aGuid, aInputBlockId);
ProcessUntransformedAPZEvent(&event, aGuid, aInputBlockId);
}
class DispatchTouchInputOnControllerThread : public Task
+1 -13
View File
@@ -3249,19 +3249,7 @@ nsWindow::OnScrollEvent(GdkEventScroll *aEvent)
wheelEvent.time = aEvent->time;
if (mAPZC) {
uint64_t inputBlockId = 0;
ScrollableLayerGuid guid;
nsEventStatus result = mAPZC->ReceiveInputEvent(*wheelEvent.AsWheelEvent(), &guid, &inputBlockId);
if (result == nsEventStatus_eConsumeNoDefault) {
return;
}
DispatchEventForAPZ(&wheelEvent, guid, inputBlockId);
} else {
nsEventStatus status;
DispatchEvent(&wheelEvent, status);
}
DispatchAPZAwareEvent(&wheelEvent);
}
void
+22 -3
View File
@@ -973,9 +973,9 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
}
nsEventStatus
nsBaseWidget::DispatchEventForAPZ(WidgetGUIEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
{
MOZ_ASSERT(NS_IsMainThread());
InputAPZContext context(aGuid, aInputBlockId);
@@ -1015,6 +1015,25 @@ nsBaseWidget::DispatchEventForAPZ(WidgetGUIEvent* aEvent,
return status;
}
nsEventStatus
nsBaseWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent)
{
if (mAPZC) {
uint64_t inputBlockId = 0;
ScrollableLayerGuid guid;
nsEventStatus result = mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
if (result == nsEventStatus_eConsumeNoDefault) {
return result;
}
return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId);
}
nsEventStatus status;
DispatchEvent(aEvent, status);
return status;
}
void
nsBaseWidget::GetPreferredCompositorBackends(nsTArray<LayersBackend>& aHints)
{
+7 -5
View File
@@ -231,6 +231,9 @@ public:
NS_IMETHOD UnregisterTouchWindow() override;
NS_IMETHOD_(TextEventDispatcher*) GetTextEventDispatcher() override final;
// Dispatch an event that must be first be routed through APZ.
nsEventStatus DispatchAPZAwareEvent(mozilla::WidgetInputEvent* aEvent) MOZ_OVERRIDE;
void NotifyWindowDestroyed();
void NotifySizeMoveDone();
void NotifyWindowMoved(int32_t aX, int32_t aY);
@@ -326,11 +329,10 @@ protected:
virtual void ConfigureAPZCTreeManager();
virtual already_AddRefed<GoannaContentController> CreateRootContentController();
// Dispatch an event that has been routed through APZ directly from the
// widget.
nsEventStatus DispatchEventForAPZ(mozilla::WidgetGUIEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
// Dispatch an event that has already been routed through APZ.
nsEventStatus ProcessUntransformedAPZEvent(mozilla::WidgetInputEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
const nsIntRegion RegionFromArray(const nsTArray<nsIntRect>& aRects);
void ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects);
+7
View File
@@ -1687,6 +1687,13 @@ class nsIWidget : public nsISupports {
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* event,
nsEventStatus & aStatus) = 0;
/**
* Dispatches an event that must be handled by APZ first, when APZ is
* enabled. If invoked in the child process, it is forwarded to the
* parent process synchronously.
*/
virtual nsEventStatus DispatchAPZAwareEvent(mozilla::WidgetInputEvent* aEvent) = 0;
/**
* Enables the dropping of files to a widget (XXX this is temporary)
*
+5 -12
View File
@@ -3697,20 +3697,13 @@ bool nsWindow::DispatchKeyboardEvent(WidgetGUIEvent* event)
bool nsWindow::DispatchScrollEvent(WidgetGUIEvent* aEvent)
{
nsEventStatus status;
if (mAPZC && aEvent->mClass == eWheelEventClass) {
uint64_t inputBlockId = 0;
ScrollableLayerGuid guid;
nsEventStatus result = mAPZC->ReceiveInputEvent(*aEvent->AsWheelEvent(), &guid, &inputBlockId);
if (result == nsEventStatus_eConsumeNoDefault) {
return true;
}
status = DispatchEventForAPZ(aEvent, guid, inputBlockId);
} else {
if (aEvent->mClass != eWheelEventClass) {
nsEventStatus status;
DispatchEvent(aEvent, status);
return ConvertStatus(status);
}
nsEventStatus status = DispatchAPZAwareEvent(aEvent->AsInputEvent());
return ConvertStatus(status);
}