mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
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:
@@ -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) &&
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user