Allow synthetic input events to be dispatched asynchronously. (bug 1146243, r=kats)

This commit is contained in:
David Anderson 2015-03-24 15:00:52 -07:00
parent 37a72c0133
commit 7bc98f302c
10 changed files with 95 additions and 11 deletions

View File

@ -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<nsIPresShell> 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

View File

@ -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:
/**

View File

@ -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<nsIWidget> widget = GetWidget();
if (!widget) {
@ -1234,6 +1234,38 @@ bool TabParent::RecvSynthesizedMouseWheelEvent(const mozilla::WidgetWheelEvent&
return true;
}
bool
TabParent::RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent)
{
nsCOMPtr<nsIWidget> 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<nsIWidget> 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)
{

View File

@ -211,7 +211,9 @@ public:
nsTArray<ScrollableLayerGuid>&& aTargets) override;
virtual bool RecvSetAllowedTouchBehavior(const uint64_t& aInputBlockId,
nsTArray<TouchBehaviorFlags>&& 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;

View File

@ -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);

View File

@ -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");

View File

@ -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

View File

@ -124,7 +124,16 @@ TextEventDispatcher::DispatchEvent(nsIWidget* aWidget,
nsRefPtr<TextEventDispatcher> kungFuDeathGrip(this);
nsCOMPtr<nsIWidget> 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;
}

View File

@ -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;

View File

@ -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)
*