diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 7390a6f8e54..d18e5db925f 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -812,22 +812,26 @@ nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType, event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; - nsEventStatus status; + nsEventStatus status = nsEventStatus_eIgnore; if (aToWindow) { nsCOMPtr presShell; nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); if (!presShell || !view) { return NS_ERROR_FAILURE; } - status = nsEventStatus_eIgnore; return presShell->HandleEvent(view->GetFrame(), &event, false, &status); } - nsresult rv = widget->DispatchEvent(&event, status); + if (gfxPrefs::TestEventsAsyncEnabled()) { + status = widget->DispatchInputEvent(&event); + } else { + nsresult rv = widget->DispatchEvent(&event, status); + NS_ENSURE_SUCCESS(rv, rv); + } if (aPreventDefault) { *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); } - return rv; + return NS_OK; } NS_IMETHODIMP diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 778a8ef8857..472c68a02a4 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -492,7 +492,9 @@ parent: */ async SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCx, int32_t aCy); - prio(high) sync SynthesizedMouseWheelEvent(WidgetWheelEvent event); + prio(high) sync DispatchWheelEvent(WidgetWheelEvent event); + prio(high) sync DispatchMouseEvent(WidgetMouseEvent event); + prio(high) sync DispatchKeyboardEvent(WidgetKeyboardEvent event); child: /** diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index c240de21c78..ac66ae54223 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1219,7 +1219,7 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event) return PBrowserParent::SendMouseWheelEvent(event, guid, blockId); } -bool TabParent::RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent) +bool TabParent::RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent) { nsCOMPtr widget = GetWidget(); if (!widget) { @@ -1234,6 +1234,38 @@ bool TabParent::RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent& return true; } +bool +TabParent::RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent) +{ + nsCOMPtr widget = GetWidget(); + if (!widget) { + return true; + } + + WidgetMouseEvent localEvent(aEvent); + localEvent.widget = widget; + localEvent.refPoint -= GetChildProcessOffset(); + + widget->DispatchInputEvent(&localEvent); + return true; +} + +bool +TabParent::RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent) +{ + nsCOMPtr widget = GetWidget(); + if (!widget) { + return true; + } + + WidgetKeyboardEvent localEvent(aEvent); + localEvent.widget = widget; + localEvent.refPoint -= GetChildProcessOffset(); + + widget->DispatchInputEvent(&localEvent); + return true; +} + static void DoCommandCallback(mozilla::Command aCommand, void* aData) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index a380603f11b..75a8852728f 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -211,7 +211,9 @@ public: nsTArray&& aTargets) override; virtual bool RecvSetAllowedTouchBehavior(const uint64_t& aInputBlockId, nsTArray&& aTargets) override; - virtual bool RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override; + virtual bool RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override; + virtual bool RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent) override; + virtual bool RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent) override; virtual PColorPickerParent* AllocPColorPickerParent(const nsString& aTitle, const nsString& aInitialColor) override; diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index fce3a973220..7114a1a055b 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -339,9 +339,12 @@ private: MouseWheelHasScrollDeltaOverride, bool, false); DECL_GFX_PREF(Live, "mousewheel.transaction.ignoremovedelay",MouseWheelIgnoreMoveDelayMs, int32_t, (int32_t)100); DECL_GFX_PREF(Live, "mousewheel.transaction.timeout", MouseWheelTransactionTimeoutMs, int32_t, (int32_t)1500); - DECL_GFX_PREF(Live, "test.mousescroll", MouseScrollTestingEnabled, bool, false); DECL_GFX_PREF(Live, "nglayout.debug.widget_update_flashing", WidgetUpdateFlashing, bool, false); + + DECL_GFX_PREF(Live, "test.events.async.enabled", TestEventsAsyncEnabled, bool, false); + DECL_GFX_PREF(Live, "test.mousescroll", MouseScrollTestingEnabled, bool, false); + DECL_GFX_PREF(Live, "ui.click_hold_context_menus.delay", UiClickHoldContextMenusDelay, int32_t, 500); DECL_GFX_PREF(Once, "webgl.angle.force-d3d11", WebGLANGLEForceD3D11, bool, false); DECL_GFX_PREF(Once, "webgl.angle.try-d3d11", WebGLANGLETryD3D11, bool, false); diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 26f5bc5cea8..fba166a2733 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -17,6 +17,7 @@ #include "mozilla/Preferences.h" #include "mozilla/TextComposition.h" #include "mozilla/TextEvents.h" +#include "mozilla/unused.h" #include "PuppetWidget.h" #include "nsIWidgetListener.h" @@ -327,6 +328,28 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus) return NS_OK; } +nsEventStatus +PuppetWidget::DispatchInputEvent(WidgetInputEvent* aEvent) +{ + if (!mTabChild) { + return nsEventStatus_eIgnore; + } + + switch (aEvent->mClass) { + case eMouseEventClass: + unused << + mTabChild->SendDispatchMouseEvent(*aEvent->AsMouseEvent()); + break; + case eKeyboardEventClass: + unused << + mTabChild->SendDispatchKeyboardEvent(*aEvent->AsKeyboardEvent()); + break; + default: + MOZ_ASSERT_UNREACHABLE("unsupported event type"); + } + + return nsEventStatus_eIgnore; +} nsEventStatus PuppetWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent) @@ -343,7 +366,8 @@ PuppetWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent) switch (aEvent->mClass) { case eWheelEventClass: - mTabChild->SendSynthesizedMouseWheelEvent(*aEvent->AsWheelEvent()); + unused << + mTabChild->SendDispatchWheelEvent(*aEvent->AsWheelEvent()); break; default: MOZ_ASSERT_UNREACHABLE("unsupported event type"); diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 864e6d81d75..c31860f3900 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -129,6 +129,7 @@ public: NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus) override; nsEventStatus DispatchAPZAwareEvent(WidgetInputEvent* aEvent) override; + nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override; NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener, bool aDoCapture) override diff --git a/widget/TextEventDispatcher.cpp b/widget/TextEventDispatcher.cpp index f217d501666..459b40632ec 100644 --- a/widget/TextEventDispatcher.cpp +++ b/widget/TextEventDispatcher.cpp @@ -124,7 +124,16 @@ TextEventDispatcher::DispatchEvent(nsIWidget* aWidget, nsRefPtr kungFuDeathGrip(this); nsCOMPtr widget(aWidget); mDispatchingEvent++; - nsresult rv = widget->DispatchEvent(&aEvent, aStatus); + + nsresult rv = NS_OK; + if (aEvent.AsInputEvent() && + (!aEvent.mFlags.mIsSynthesizedForTests || gfxPrefs::TestEventsAsyncEnabled())) + { + aStatus = widget->DispatchInputEvent(aEvent.AsInputEvent()); + } else { + rv = widget->DispatchEvent(&aEvent, aStatus); + } + mDispatchingEvent--; return rv; } diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index a859ac5259f..a2b23264716 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -233,7 +233,7 @@ public: // Helper function for dispatching events which are not processed by APZ, // but need to be transformed by APZ. - nsEventStatus DispatchInputEvent(mozilla::WidgetInputEvent* aEvent); + nsEventStatus DispatchInputEvent(mozilla::WidgetInputEvent* aEvent) override; // Dispatch an event that must be first be routed through APZ. nsEventStatus DispatchAPZAwareEvent(mozilla::WidgetInputEvent* aEvent) override; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 6e64c8c6b2c..62ec47a2897 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1704,6 +1704,13 @@ class nsIWidget : public nsISupports { */ virtual nsEventStatus DispatchAPZAwareEvent(mozilla::WidgetInputEvent* aEvent) = 0; + /** + * Dispatches an event that must be transformed by APZ first, but is not + * actually handled by APZ. If invoked in the child process, it is + * forwarded to the parent process synchronously. + */ + virtual nsEventStatus DispatchInputEvent(mozilla::WidgetInputEvent* aEvent) = 0; + /** * Enables the dropping of files to a widget (XXX this is temporary) *