--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1220,40 +1220,45 @@ EventStateManager::HandleAccessKey(Widge
nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
HandleAccessKeyInRemoteChild, &accessKeyInfo);
}
}
return false;
}// end of HandleAccessKey
-bool
+void
EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent,
nsFrameLoader* aFrameLoader,
- nsEventStatus *aStatus) {
+ nsEventStatus *aStatus)
+{
TabParent* remote = TabParent::GetFrom(aFrameLoader);
if (!remote) {
- return false;
+ return;
}
switch (aEvent->mClass) {
case eMouseEventClass: {
- return remote->SendRealMouseEvent(*aEvent->AsMouseEvent());
+ remote->SendRealMouseEvent(*aEvent->AsMouseEvent());
+ return;
}
case eKeyboardEventClass: {
- return remote->SendRealKeyEvent(*aEvent->AsKeyboardEvent());
+ remote->SendRealKeyEvent(*aEvent->AsKeyboardEvent());
+ return;
}
case eWheelEventClass: {
- return remote->SendMouseWheelEvent(*aEvent->AsWheelEvent());
+ remote->SendMouseWheelEvent(*aEvent->AsWheelEvent());
+ return;
}
case eTouchEventClass: {
// Let the child process synthesize a mouse event if needed, and
// ensure we don't synthesize one in this process.
*aStatus = nsEventStatus_eConsumeNoDefault;
- return remote->SendRealTouchEvent(*aEvent->AsTouchEvent());
+ remote->SendRealTouchEvent(*aEvent->AsTouchEvent());
+ return;
}
case eDragEventClass: {
if (remote->Manager()->IsContentParent()) {
remote->Manager()->AsContentParent()->MaybeInvokeDragSession(remote);
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
uint32_t dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
@@ -1263,24 +1268,23 @@ EventStateManager::DispatchCrossProcessE
dragSession->GetDragAction(&action);
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
if (initialDataTransfer) {
initialDataTransfer->GetDropEffectInt(&dropEffect);
}
}
- bool retval = remote->SendRealDragEvent(*aEvent->AsDragEvent(),
- action, dropEffect);
-
- return retval;
+ remote->SendRealDragEvent(*aEvent->AsDragEvent(), action, dropEffect);
+ return;
}
case ePluginEventClass: {
*aStatus = nsEventStatus_eConsumeNoDefault;
- return remote->SendPluginEvent(*aEvent->AsPluginEvent());
+ remote->SendPluginEvent(*aEvent->AsPluginEvent());
+ return;
}
default: {
MOZ_CRASH("Attempt to send non-whitelisted event?");
}
}
}
bool
@@ -1292,16 +1296,19 @@ EventStateManager::IsRemoteTarget(nsICon
bool
EventStateManager::HandleCrossProcessEvent(WidgetEvent* aEvent,
nsEventStatus *aStatus) {
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
!aEvent->CanBeSentToRemoteProcess()) {
return false;
}
+ MOZ_ASSERT(!aEvent->HasBeenPostedToRemoteProcess(),
+ "Why do we need to post same event to remote processes again?");
+
// Collect the remote event targets we're going to forward this
// event to.
//
// NB: the elements of |targets| must be unique, for correctness.
AutoTArray<nsCOMPtr<nsIContent>, 1> targets;
if (aEvent->mClass != eTouchEventClass || aEvent->mMessage == eTouchStart) {
// If this event only has one target, and it's remote, add it to
// the array.
@@ -1342,17 +1349,16 @@ EventStateManager::HandleCrossProcessEve
}
if (targets.Length() == 0) {
return false;
}
// Look up the frame loader for all the remote targets we found, and
// then dispatch the event to the remote content they represent.
- bool dispatched = false;
for (uint32_t i = 0; i < targets.Length(); ++i) {
nsIContent* target = targets[i];
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(target);
if (!loaderOwner) {
continue;
}
RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
@@ -1361,19 +1367,19 @@ EventStateManager::HandleCrossProcessEve
}
uint32_t eventMode;
frameLoader->GetEventMode(&eventMode);
if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
continue;
}
- dispatched |= DispatchCrossProcessEvent(aEvent, frameLoader, aStatus);
- }
- return dispatched;
+ DispatchCrossProcessEvent(aEvent, frameLoader, aStatus);
+ }
+ return aEvent->HasBeenPostedToRemoteProcess();
}
//
// CreateClickHoldTimer
//
// Fire off a timer for determining if the user wants click-hold. This timer
// is a one-shot that will be cancelled when the user moves enough to fire
// a drag.
@@ -2818,24 +2824,23 @@ NodeAllowsClickThrough(nsINode* aNode)
aNode = nsContentUtils::GetCrossDocParentNode(aNode);
}
return true;
}
#endif
void
EventStateManager::PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent,
- nsEventStatus& aStatus,
- bool dispatchedToContentProcess)
+ nsEventStatus& aStatus)
{
if (aStatus == nsEventStatus_eConsumeNoDefault) {
return;
}
- if (!dispatchedToContentProcess) {
+ if (!aKeyboardEvent->HasBeenPostedToRemoteProcess()) {
// The widget expects a reply for every keyboard event. If the event wasn't
// dispatched to a content process (non-e10s or no content process
// running), we need to short-circuit here. Otherwise, we need to wait for
// the content process to handle the event.
aKeyboardEvent->mWidget->PostHandleKeyEvent(aKeyboardEvent);
if (aKeyboardEvent->DefaultPrevented()) {
aStatus = nsEventStatus_eConsumeNoDefault;
return;
@@ -2850,18 +2855,19 @@ EventStateManager::PostHandleKeyboardEve
// This is to prevent keyboard scrolling while alt modifier in use.
if (!aKeyboardEvent->IsAlt()) {
aStatus = nsEventStatus_eConsumeNoDefault;
// Handling the tab event after it was sent to content is bad,
// because to the FocusManager the remote-browser looks like one
// element, so we would just move the focus to the next element
// in chrome, instead of handling it in content.
- if (dispatchedToContentProcess)
+ if (aKeyboardEvent->HasBeenPostedToRemoteProcess()) {
break;
+ }
EnsureDocument(mPresContext);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm && mDocument) {
// Shift focus forward or back depending on shift key
bool isDocMove =
aKeyboardEvent->IsControl() || aKeyboardEvent->mKeyCode == NS_VK_F6;
uint32_t dir = aKeyboardEvent->IsShift() ?
@@ -2902,17 +2908,17 @@ EventStateManager::PostHandleEvent(nsPre
nsEventStatus* aStatus)
{
NS_ENSURE_ARG(aPresContext);
NS_ENSURE_ARG_POINTER(aStatus);
mCurrentTarget = aTargetFrame;
mCurrentTargetContent = nullptr;
- bool dispatchedToContentProcess = HandleCrossProcessEvent(aEvent, aStatus);
+ HandleCrossProcessEvent(aEvent, aStatus);
// NOTE: the above call may have destroyed aTargetFrame, please use
// mCurrentTarget henceforth. This is to avoid using it accidentally:
aTargetFrame = nullptr;
// Most of the events we handle below require a frame.
// Add special cases here.
if (!mCurrentTarget && aEvent->mMessage != eMouseUp &&
aEvent->mMessage != eMouseDown) {
@@ -2934,17 +2940,18 @@ EventStateManager::PostHandleEvent(nsPre
nsIPresShell::SetCapturingContent(nullptr, 0);
break;
}
// For remote content, capture the event in the parent process at the
// <xul:browser remote> element. This will ensure that subsequent mousemove/mouseup
// events will continue to be dispatched to this element and therefore forwarded
// to the child.
- if (dispatchedToContentProcess && !nsIPresShell::GetCapturingContent()) {
+ if (aEvent->HasBeenPostedToRemoteProcess() &&
+ !nsIPresShell::GetCapturingContent()) {
nsIContent* content = mCurrentTarget ? mCurrentTarget->GetContent() : nullptr;
nsIPresShell::SetCapturingContent(content, 0);
}
nsCOMPtr<nsIContent> activeContent;
// When content calls PreventDefault on pointerdown, we also call
// PreventDefault on the subsequent mouse events to suppress default
// behaviors. Normally, aStatus should be nsEventStatus_eConsumeNoDefault
@@ -3439,17 +3446,17 @@ EventStateManager::PostHandleEvent(nsPre
}
} else if (aEvent->mMessage == eDragOver && !isChromeDoc) {
// No one called preventDefault(), so handle drop only in chrome.
dragSession->SetOnlyChromeDrop(true);
}
if (ContentChild* child = ContentChild::GetSingleton()) {
child->SendUpdateDropEffect(action, dropEffect);
}
- if (dispatchedToContentProcess) {
+ if (aEvent->HasBeenPostedToRemoteProcess()) {
dragSession->SetCanDrop(true);
} else if (initialDataTransfer) {
// Now set the drop effect in the initial dataTransfer. This ensures
// that we can get the desired drop effect in the drop event. For events
// dispatched to content, the content process will take care of setting
// this.
initialDataTransfer->SetDropEffectInt(dropEffect);
}
@@ -3475,17 +3482,17 @@ EventStateManager::PostHandleEvent(nsPre
break;
case eKeyUp:
break;
case eKeyPress:
{
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
- PostHandleKeyboardEvent(keyEvent, *aStatus, dispatchedToContentProcess);
+ PostHandleKeyboardEvent(keyEvent, *aStatus);
}
break;
case eMouseEnterIntoWidget:
if (mCurrentTarget) {
nsCOMPtr<nsIContent> targetContent;
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -104,18 +104,17 @@ public:
* DOM and frame processing.
*/
nsresult PostHandleEvent(nsPresContext* aPresContext,
WidgetEvent* aEvent,
nsIFrame* aTargetFrame,
nsEventStatus* aStatus);
void PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent,
- nsEventStatus& aStatus,
- bool dispatchedToContentProcess);
+ nsEventStatus& aStatus);
/**
* DispatchLegacyMouseScrollEvents() dispatches eLegacyMouseLineOrPageScroll
* event and eLegacyMousePixelScroll event for compatibility with old Gecko.
*/
void DispatchLegacyMouseScrollEvents(nsIFrame* aTargetFrame,
WidgetWheelEvent* aEvent,
nsEventStatus* aStatus);
@@ -890,19 +889,32 @@ protected:
void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);
nsresult DoContentCommandEvent(WidgetContentCommandEvent* aEvent);
nsresult DoContentCommandScrollEvent(WidgetContentCommandEvent* aEvent);
dom::TabParent *GetCrossProcessTarget();
bool IsTargetCrossProcess(WidgetGUIEvent* aEvent);
- bool DispatchCrossProcessEvent(WidgetEvent* aEvent,
+ /**
+ * DispatchCrossProcessEvent() try to post aEvent to target remote process.
+ * If you need to check if the event is posted to a remote process, you
+ * can use aEvent->HasBeenPostedToRemoteProcess().
+ */
+ void DispatchCrossProcessEvent(WidgetEvent* aEvent,
nsFrameLoader* aRemote,
nsEventStatus *aStatus);
+ /**
+ * HandleCrossProcessEvent() may post aEvent to target remote processes.
+ * When it succeeded to post the event to at least one remote process,
+ * returns true. Otherwise, including the case not tried to dispatch to
+ * post the event, returns false.
+ * If you need to check if the event is posted to at least one remote
+ * process, you can use aEvent->HasBeenPostedToRemoteProcess().
+ */
bool HandleCrossProcessEvent(WidgetEvent* aEvent,
nsEventStatus* aStatus);
void ReleaseCurrentIMEContentObserver();
void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
private:
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1827,17 +1827,20 @@ TabChild::RequestEditCommands(nsIWidget:
case nsIWidget::NativeKeyBindingsForSingleLineEditor:
case nsIWidget::NativeKeyBindingsForMultiLineEditor:
case nsIWidget::NativeKeyBindingsForRichTextEditor:
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid native key bindings type");
}
- SendRequestNativeKeyBindings(aType, aEvent, &aCommands);
+ // Don't send aEvent to the parent process directly because it'll be marked
+ // as posted to remote process.
+ WidgetKeyboardEvent localEvent(aEvent);
+ SendRequestNativeKeyBindings(aType, localEvent, &aCommands);
}
mozilla::ipc::IPCResult
TabChild::RecvNativeSynthesisResponse(const uint64_t& aObserverId,
const nsCString& aResponse)
{
mozilla::widget::AutoObserverNotifier::NotifySavedObserver(aObserverId,
aResponse.get());
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -813,17 +813,21 @@ TabParent::ThemeChanged()
}
void
TabParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>& aCharCodes,
const int32_t& aModifierMask)
{
if (!mIsDestroyed) {
- Unused << SendHandleAccessKey(aEvent, aCharCodes, aModifierMask);
+ // Note that we don't need to mark aEvent is posted to a remote process
+ // because the event may be dispatched to it as normal keyboard event.
+ // Therefore, we should use local copy to send it.
+ WidgetKeyboardEvent localEvent(aEvent);
+ Unused << SendHandleAccessKey(localEvent, aCharCodes, aModifierMask);
}
}
void
TabParent::Activate()
{
if (!mIsDestroyed) {
Unused << Manager()->SendActivate(this);
@@ -1078,21 +1082,21 @@ TabParent::SendKeyEvent(const nsAString&
{
if (mIsDestroyed) {
return;
}
Unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
aModifiers, aPreventDefault);
}
-bool
+void
TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent)
{
if (mIsDestroyed) {
- return false;
+ return;
}
aEvent.mRefPoint += GetChildProcessOffset();
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
// When we mouseenter the tab, the tab's cursor should
// become the current cursor. When we mouseexit, we stop.
if (eMouseEnterIntoWidget == aEvent.mMessage) {
@@ -1109,66 +1113,79 @@ TabParent::SendRealMouseEvent(WidgetMous
}
ScrollableLayerGuid guid;
uint64_t blockId;
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
if (eMouseMove == aEvent.mMessage) {
if (aEvent.mReason == WidgetMouseEvent::eSynthesized) {
- return SendSynthMouseMoveEvent(aEvent, guid, blockId);
- } else {
- return SendRealMouseMoveEvent(aEvent, guid, blockId);
+ DebugOnly<bool> ret = SendSynthMouseMoveEvent(aEvent, guid, blockId);
+ NS_WARNING_ASSERTION(ret, "SendSynthMouseMoveEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
+ return;
}
+ DebugOnly<bool> ret = SendRealMouseMoveEvent(aEvent, guid, blockId);
+ NS_WARNING_ASSERTION(ret, "SendRealMouseMoveEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
+ return;
}
- return SendRealMouseButtonEvent(aEvent, guid, blockId);
+ DebugOnly<bool> ret = SendRealMouseButtonEvent(aEvent, guid, blockId);
+ NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
LayoutDeviceToCSSScale
TabParent::GetLayoutDeviceToCSSScale()
{
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
nsIDocument* doc = (content ? content->OwnerDoc() : nullptr);
nsIPresShell* shell = (doc ? doc->GetShell() : nullptr);
nsPresContext* ctx = (shell ? shell->GetPresContext() : nullptr);
return LayoutDeviceToCSSScale(ctx
? (float)ctx->AppUnitsPerDevPixel() / nsPresContext::AppUnitsPerCSSPixel()
: 0.0f);
}
-bool
+void
TabParent::SendRealDragEvent(WidgetDragEvent& aEvent, uint32_t aDragAction,
uint32_t aDropEffect)
{
if (mIsDestroyed) {
- return false;
+ return;
}
aEvent.mRefPoint += GetChildProcessOffset();
- return PBrowserParent::SendRealDragEvent(aEvent, aDragAction, aDropEffect);
+ DebugOnly<bool> ret =
+ PBrowserParent::SendRealDragEvent(aEvent, aDragAction, aDropEffect);
+ NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealDragEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
LayoutDevicePoint
TabParent::AdjustTapToChildWidget(const LayoutDevicePoint& aPoint)
{
return aPoint + LayoutDevicePoint(GetChildProcessOffset());
}
-bool
+void
TabParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent)
{
if (mIsDestroyed) {
- return false;
+ return;
}
ScrollableLayerGuid guid;
uint64_t blockId;
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
aEvent.mRefPoint += GetChildProcessOffset();
- return PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId);
+ DebugOnly<bool> ret =
+ PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId);
+ NS_WARNING_ASSERTION(ret, "PBrowserParent::SendMouseWheelEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
mozilla::ipc::IPCResult
TabParent::RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
@@ -1423,40 +1440,42 @@ TabParent::RecvClearNativeTouchSequence(
AutoSynthesizedEventResponder responder(this, aObserverId, "cleartouch");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->ClearNativeTouchSequence(responder.GetObserver());
}
return IPC_OK();
}
-bool
+void
TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent)
{
if (mIsDestroyed) {
- return false;
+ return;
}
aEvent.mRefPoint += GetChildProcessOffset();
if (aEvent.mMessage == eKeyPress) {
// XXX Should we do this only when input context indicates an editor having
// focus and the key event won't cause inputting text?
aEvent.InitAllEditCommands();
} else {
aEvent.PreventNativeKeyBindings();
}
- return PBrowserParent::SendRealKeyEvent(aEvent);
+ DebugOnly<bool> ret = PBrowserParent::SendRealKeyEvent(aEvent);
+ NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealKeyEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
-bool
+void
TabParent::SendRealTouchEvent(WidgetTouchEvent& aEvent)
{
if (mIsDestroyed) {
- return false;
+ return;
}
// PresShell::HandleEventInternal adds touches on touch end/cancel. This
// confuses remote content and the panning and zooming logic into thinking
// that the added touches are part of the touchend/cancel, when actually
// they're not.
if (aEvent.mMessage == eTouchEnd || aEvent.mMessage == eTouchCancel) {
for (int i = aEvent.mTouches.Length() - 1; i >= 0; i--) {
@@ -1467,27 +1486,46 @@ TabParent::SendRealTouchEvent(WidgetTouc
}
ScrollableLayerGuid guid;
uint64_t blockId;
nsEventStatus apzResponse;
ApzAwareEventRoutingToChild(&guid, &blockId, &apzResponse);
if (mIsDestroyed) {
- return false;
+ return;
}
LayoutDeviceIntPoint offset = GetChildProcessOffset();
for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
aEvent.mTouches[i]->mRefPoint += offset;
}
- return (aEvent.mMessage == eTouchMove) ?
- PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId, apzResponse) :
+ if (aEvent.mMessage == eTouchMove) {
+ DebugOnly<bool> ret =
+ PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId,
+ apzResponse);
+ NS_WARNING_ASSERTION(ret,
+ "PBrowserParent::SendRealTouchMoveEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
+ return;
+ }
+
+ DebugOnly<bool> ret =
PBrowserParent::SendRealTouchEvent(aEvent, guid, blockId, apzResponse);
+ NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealTouchEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
+}
+
+void
+TabParent::SendPluginEvent(WidgetPluginEvent& aEvent)
+{
+ DebugOnly<bool> ret = PBrowserParent::SendPluginEvent(aEvent);
+ NS_WARNING_ASSERTION(ret, "PBrowserParent::SendPluginEvent() failed");
+ MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
bool
TabParent::SendHandleTap(TapType aType,
const LayoutDevicePoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
@@ -2047,33 +2085,38 @@ TabParent::SendCompositionEvent(WidgetCo
{
if (mIsDestroyed) {
return false;
}
if (!mContentCache.OnCompositionEvent(aEvent)) {
return true;
}
- return PBrowserParent::SendCompositionEvent(aEvent);
+ if (NS_WARN_IF(!PBrowserParent::SendCompositionEvent(aEvent))) {
+ return false;
+ }
+ MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
+ return true;
}
bool
TabParent::SendSelectionEvent(WidgetSelectionEvent& aEvent)
{
if (mIsDestroyed) {
return false;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return true;
}
mContentCache.OnSelectionEvent(aEvent);
if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(aEvent))) {
return false;
}
+ MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
aEvent.mSucceeded = true;
return true;
}
bool
TabParent::SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
const bool& aIsPrivateData,
const IPC::Principal& aRequestingPrincipal)
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -433,27 +433,45 @@ public:
void SendMouseEvent(const nsAString& aType, float aX, float aY,
int32_t aButton, int32_t aClickCount,
int32_t aModifiers, bool aIgnoreRootScrollFrame);
void SendKeyEvent(const nsAString& aType, int32_t aKeyCode,
int32_t aCharCode, int32_t aModifiers,
bool aPreventDefault);
- bool SendRealMouseEvent(mozilla::WidgetMouseEvent& aEvent);
+ /**
+ * The following Send*Event() marks aEvent as posted to remote process if
+ * it succeeded. So, you can check the result with
+ * aEvent.HasBeenPostedToRemoteProcess().
+ */
+ void SendRealMouseEvent(WidgetMouseEvent& aEvent);
- bool SendRealDragEvent(mozilla::WidgetDragEvent& aEvent,
+ void SendRealDragEvent(WidgetDragEvent& aEvent,
uint32_t aDragAction,
uint32_t aDropEffect);
- bool SendMouseWheelEvent(mozilla::WidgetWheelEvent& aEvent);
+ void SendMouseWheelEvent(WidgetWheelEvent& aEvent);
+
+ void SendRealKeyEvent(WidgetKeyboardEvent& aEvent);
+
+ void SendRealTouchEvent(WidgetTouchEvent& aEvent);
+
+ void SendPluginEvent(WidgetPluginEvent& aEvent);
- bool SendRealKeyEvent(mozilla::WidgetKeyboardEvent& aEvent);
+ /**
+ * Different from above Send*Event(), these methods return true if the
+ * event has been posted to the remote process or failed to do that but
+ * shouldn't be handled by following event listeners.
+ * If you need to check if it's actually posted to the remote process,
+ * you can refer aEvent.HasBeenPostedToRemoteProcess().
+ */
+ bool SendCompositionEvent(mozilla::WidgetCompositionEvent& aEvent);
- bool SendRealTouchEvent(WidgetTouchEvent& aEvent);
+ bool SendSelectionEvent(mozilla::WidgetSelectionEvent& aEvent);
bool SendHandleTap(TapType aType,
const LayoutDevicePoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
virtual PDocumentRendererParent*
@@ -491,20 +509,16 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPTPROVIDER
NS_DECL_NSISECUREBROWSERUI
NS_DECL_NSIWEBBROWSERPERSISTABLE
bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent);
- bool SendCompositionEvent(mozilla::WidgetCompositionEvent& aEvent);
-
- bool SendSelectionEvent(mozilla::WidgetSelectionEvent& aEvent);
-
bool SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
const bool& aIsPrivateData,
const IPC::Principal& aRequestingPrincipal);
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
static TabParent* GetFrom(nsIFrameLoader* aFrameLoader);
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -149,16 +149,20 @@ public:
// If mNoRemoteProcessDispatch is true, the event is not allowed to be sent
// to remote process.
bool mNoRemoteProcessDispatch : 1;
// If mWantReplyFromContentProcess is true, the event will be redispatched
// in the parent process after the content process has handled it. Useful
// for when the parent process need the know first how the event was used
// by content before handling it itself.
bool mWantReplyFromContentProcess : 1;
+ // If mPostedToRemoteProcess is true, the event has been posted to the
+ // remote process (but it's not handled yet if it's not a duplicated event
+ // instance).
+ bool mPostedToRemoteProcess : 1;
// If the event is being handled in target phase, returns true.
inline bool InTargetPhase() const
{
return (mInBubblingPhase && mInCapturePhase);
}
/**
@@ -218,31 +222,33 @@ public:
// Helper methods to access flags managing state of propagation between
// processes.
/**
* Prevent to be dispatched to remote process.
*/
inline void StopCrossProcessForwarding()
{
+ MOZ_ASSERT(!mPostedToRemoteProcess);
mNoRemoteProcessDispatch = true;
mWantReplyFromContentProcess = false;
}
/**
* Return true if the event shouldn't be dispatched to remote process.
*/
inline bool IsCrossProcessForwardingStopped() const
{
return mNoRemoteProcessDispatch;
}
/**
* Mark the event as waiting reply from remote process.
*/
inline void MarkAsWaitingReplyFromRemoteProcess()
{
+ MOZ_ASSERT(!mPostedToRemoteProcess);
// When this is called, it means that event handlers in this process need
// a reply from content in a remote process. So, callers should stop
// propagation in this process first.
NS_ASSERTION(PropagationStopped(),
"Why didn't you stop propagation in this process?");
mNoRemoteProcessDispatch = false;
mWantReplyFromContentProcess = true;
}
@@ -257,16 +263,17 @@ public:
/**
* Mark the event as already handled in the remote process. This should be
* called when initializing reply events.
*/
inline void MarkAsHandledInRemoteProcess()
{
mNoRemoteProcessDispatch = true;
mWantReplyFromContentProcess = true;
+ mPostedToRemoteProcess = false;
}
/**
* Return true if the event has already been handled in the remote process.
*/
inline bool IsHandledInRemoteProcess() const
{
return mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
}
@@ -274,21 +281,51 @@ public:
* Return true if the event should be sent back to its parent process.
*/
inline bool WantReplyFromContentProcess() const
{
MOZ_ASSERT(!XRE_IsParentProcess());
return IsWaitingReplyFromRemoteProcess();
}
/**
+ * Mark the event has already posted to a remote process.
+ */
+ inline void MarkAsPostedToRemoteProcess()
+ {
+ MOZ_ASSERT(!IsCrossProcessForwardingStopped());
+ mPostedToRemoteProcess = true;
+ }
+ /**
+ * Reset the cross process dispatching state. This should be used when a
+ * process receives the event because the state is in the sender.
+ */
+ inline void ResetCrossProcessDispatchingState()
+ {
+ MOZ_ASSERT(!IsCrossProcessForwardingStopped());
+ mPostedToRemoteProcess = false;
+ }
+ /**
+ * Return true if the event has been posted to a remote process.
+ * Note that MarkAsPostedToRemoteProcess() is called by
+ * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible
+ * that posting the event failed even if this returns true. But that must
+ * really rare. If that'd be problem for you, you should unmark this in
+ * TabParent or somewhere.
+ */
+ inline bool HasBeenPostedToRemoteProcess() const
+ {
+ return mPostedToRemoteProcess;
+ }
+ /**
* Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
* content because it shouldn't be cancelable.
*/
inline void MarkAsReservedByChrome()
{
+ MOZ_ASSERT(!mPostedToRemoteProcess);
mIsReservedByChrome = true;
// For reserved commands (such as Open New Tab), we don't need to wait for
// the content to answer, neither to give a chance for content to override
// its behavior.
StopCrossProcessForwarding();
// If the event is reserved by chrome, we shouldn't expose the event to
// web contents because such events shouldn't be cancelable. So, it's not
// good behavior to fire such events but to ignore the defaultPrevented
@@ -620,16 +657,38 @@ public:
* Return true if the event should be sent back to its parent process.
* So, usual event handlers shouldn't call this.
*/
inline bool WantReplyFromContentProcess() const
{
return mFlags.WantReplyFromContentProcess();
}
/**
+ * Mark the event has already posted to a remote process.
+ */
+ inline void MarkAsPostedToRemoteProcess()
+ {
+ mFlags.MarkAsPostedToRemoteProcess();
+ }
+ /**
+ * Reset the cross process dispatching state. This should be used when a
+ * process receives the event because the state is in the sender.
+ */
+ inline void ResetCrossProcessDispatchingState()
+ {
+ mFlags.ResetCrossProcessDispatchingState();
+ }
+ /**
+ * Return true if the event has been posted to a remote process.
+ */
+ inline bool HasBeenPostedToRemoteProcess() const
+ {
+ return mFlags.HasBeenPostedToRemoteProcess();
+ }
+ /**
* Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
* content because it shouldn't be cancelable.
*/
inline void MarkAsReservedByChrome()
{
mFlags.MarkAsReservedByChrome();
}
/**
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -56,16 +56,19 @@ struct ParamTraits<mozilla::BaseEventFla
template<>
struct ParamTraits<mozilla::WidgetEvent>
{
typedef mozilla::WidgetEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
+ // Mark the event as posted to another process.
+ const_cast<mozilla::WidgetEvent&>(aParam).MarkAsPostedToRemoteProcess();
+
WriteParam(aMsg,
static_cast<mozilla::EventClassIDType>(aParam.mClass));
WriteParam(aMsg, aParam.mMessage);
WriteParam(aMsg, aParam.mRefPoint);
WriteParam(aMsg, aParam.mFocusSequenceNumber);
WriteParam(aMsg, aParam.mTime);
WriteParam(aMsg, aParam.mTimeStamp);
WriteParam(aMsg, aParam.mFlags);
@@ -77,16 +80,21 @@ struct ParamTraits<mozilla::WidgetEvent>
bool ret = ReadParam(aMsg, aIter, &eventClassID) &&
ReadParam(aMsg, aIter, &aResult->mMessage) &&
ReadParam(aMsg, aIter, &aResult->mRefPoint) &&
ReadParam(aMsg, aIter, &aResult->mFocusSequenceNumber) &&
ReadParam(aMsg, aIter, &aResult->mTime) &&
ReadParam(aMsg, aIter, &aResult->mTimeStamp) &&
ReadParam(aMsg, aIter, &aResult->mFlags);
aResult->mClass = static_cast<mozilla::EventClassID>(eventClassID);
+ if (ret) {
+ // Reset cross process dispatching state here because the event has not
+ // been dispatched to different process from current process.
+ aResult->ResetCrossProcessDispatchingState();
+ }
return ret;
}
};
template<>
struct ParamTraits<mozilla::NativeEventData>
{
typedef mozilla::NativeEventData paramType;
@@ -104,17 +112,17 @@ struct ParamTraits<mozilla::NativeEventD
template<>
struct ParamTraits<mozilla::WidgetGUIEvent>
{
typedef mozilla::WidgetGUIEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetEvent&>(aParam));
WriteParam(aMsg, aParam.mPluginEvent);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, static_cast<mozilla::WidgetEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mPluginEvent);
}
@@ -122,17 +130,17 @@ struct ParamTraits<mozilla::WidgetGUIEve
template<>
struct ParamTraits<mozilla::WidgetInputEvent>
{
typedef mozilla::WidgetInputEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
WriteParam(aMsg, aParam.mModifiers);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mModifiers);
@@ -141,17 +149,17 @@ struct ParamTraits<mozilla::WidgetInputE
template<>
struct ParamTraits<mozilla::WidgetMouseEventBase>
{
typedef mozilla::WidgetMouseEventBase paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetInputEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetInputEvent&>(aParam));
WriteParam(aMsg, aParam.button);
WriteParam(aMsg, aParam.buttons);
WriteParam(aMsg, aParam.pressure);
WriteParam(aMsg, aParam.hitCluster);
WriteParam(aMsg, aParam.inputSource);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@@ -168,17 +176,17 @@ struct ParamTraits<mozilla::WidgetMouseE
template<>
struct ParamTraits<mozilla::WidgetWheelEvent>
{
typedef mozilla::WidgetWheelEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetMouseEventBase>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetMouseEventBase&>(aParam));
WriteParam(aMsg, aParam.mDeltaX);
WriteParam(aMsg, aParam.mDeltaY);
WriteParam(aMsg, aParam.mDeltaZ);
WriteParam(aMsg, aParam.mDeltaMode);
WriteParam(aMsg, aParam.mCustomizedByUserPrefs);
WriteParam(aMsg, aParam.mMayHaveMomentum);
WriteParam(aMsg, aParam.mIsMomentum);
WriteParam(aMsg, aParam.mIsNoLineOrPageDelta);
@@ -250,17 +258,17 @@ struct ParamTraits<mozilla::WidgetPointe
template<>
struct ParamTraits<mozilla::WidgetMouseEvent>
{
typedef mozilla::WidgetMouseEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetMouseEventBase>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetMouseEventBase&>(aParam));
WriteParam(aMsg, static_cast<mozilla::WidgetPointerHelper>(aParam));
WriteParam(aMsg, aParam.mIgnoreRootScrollFrame);
WriteParam(aMsg, static_cast<paramType::ReasonType>(aParam.mReason));
WriteParam(aMsg, static_cast<paramType::ContextMenuTriggerType>(
aParam.mContextMenuTrigger));
WriteParam(aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom));
WriteParam(aMsg, aParam.mClickCount);
}
@@ -291,17 +299,17 @@ struct ParamTraits<mozilla::WidgetMouseE
template<>
struct ParamTraits<mozilla::WidgetDragEvent>
{
typedef mozilla::WidgetDragEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetMouseEvent&>(aParam));
WriteParam(aMsg, aParam.mUserCancelled);
WriteParam(aMsg, aParam.mDefaultPreventedOnContent);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
bool rv =
ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
@@ -313,17 +321,17 @@ struct ParamTraits<mozilla::WidgetDragEv
template<>
struct ParamTraits<mozilla::WidgetPointerEvent>
{
typedef mozilla::WidgetPointerEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetMouseEvent&>(aParam));
WriteParam(aMsg, aParam.mWidth);
WriteParam(aMsg, aParam.mHeight);
WriteParam(aMsg, aParam.mIsPrimary);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
bool rv =
@@ -424,17 +432,17 @@ struct ParamTraits<mozilla::ShortcutKeyC
template<>
struct ParamTraits<mozilla::WidgetKeyboardEvent>
{
typedef mozilla::WidgetKeyboardEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetInputEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetInputEvent&>(aParam));
WriteParam(aMsg,
static_cast<mozilla::KeyNameIndexType>(aParam.mKeyNameIndex));
WriteParam(aMsg,
static_cast<mozilla::CodeNameIndexType>(aParam.mCodeNameIndex));
WriteParam(aMsg, aParam.mKeyValue);
WriteParam(aMsg, aParam.mCodeValue);
WriteParam(aMsg, aParam.mKeyCode);
WriteParam(aMsg, aParam.mCharCode);
@@ -595,17 +603,17 @@ struct ParamTraits<mozilla::TextRangeArr
template<>
struct ParamTraits<mozilla::WidgetCompositionEvent>
{
typedef mozilla::WidgetCompositionEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
WriteParam(aMsg, aParam.mData);
WriteParam(aMsg, aParam.mNativeIMEContext);
bool hasRanges = !!aParam.mRanges;
WriteParam(aMsg, hasRanges);
if (hasRanges) {
WriteParam(aMsg, *aParam.mRanges.get());
}
}
@@ -679,17 +687,17 @@ struct ParamTraits<mozilla::WidgetQueryC
template<>
struct ParamTraits<mozilla::WidgetQueryContentEvent>
{
typedef mozilla::WidgetQueryContentEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
WriteParam(aMsg, aParam.mSucceeded);
WriteParam(aMsg, aParam.mUseNativeLineBreak);
WriteParam(aMsg, aParam.mWithFontRanges);
WriteParam(aMsg, aParam.mInput);
WriteParam(aMsg, aParam.mReply.mOffset);
WriteParam(aMsg, aParam.mReply.mTentativeCaretOffset);
WriteParam(aMsg, aParam.mReply.mString);
WriteParam(aMsg, aParam.mReply.mRect);
@@ -720,17 +728,17 @@ struct ParamTraits<mozilla::WidgetQueryC
template<>
struct ParamTraits<mozilla::WidgetSelectionEvent>
{
typedef mozilla::WidgetSelectionEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
WriteParam(aMsg, aParam.mOffset);
WriteParam(aMsg, aParam.mLength);
WriteParam(aMsg, aParam.mReversed);
WriteParam(aMsg, aParam.mExpandToClusterBoundary);
WriteParam(aMsg, aParam.mSucceeded);
WriteParam(aMsg, aParam.mUseNativeLineBreak);
}
@@ -953,17 +961,17 @@ struct ParamTraits<mozilla::widget::IMEN
template<>
struct ParamTraits<mozilla::WidgetPluginEvent>
{
typedef mozilla::WidgetPluginEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
WriteParam(aMsg, aParam.mRetargetToFocusedDocument);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
ReadParam(aMsg, aIter, &aResult->mRetargetToFocusedDocument);
@@ -1122,17 +1130,17 @@ struct ParamTraits<mozilla::MultiTouchIn
template<>
struct ParamTraits<mozilla::MultiTouchInput>
{
typedef mozilla::MultiTouchInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mTouches);
WriteParam(aMsg, aParam.mHandledByAPZ);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, static_cast<mozilla::InputData*>(aResult)) &&
@@ -1160,17 +1168,17 @@ struct ParamTraits<mozilla::MouseInput::
template<>
struct ParamTraits<mozilla::MouseInput>
{
typedef mozilla::MouseInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mButtonType);
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mInputSource);
WriteParam(aMsg, aParam.mButtons);
WriteParam(aMsg, aParam.mOrigin);
WriteParam(aMsg, aParam.mLocalOrigin);
WriteParam(aMsg, aParam.mHandledByAPZ);
}
@@ -1198,17 +1206,17 @@ struct ParamTraits<mozilla::PanGestureIn
template<>
struct ParamTraits<mozilla::PanGestureInput>
{
typedef mozilla::PanGestureInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mPanStartPoint);
WriteParam(aMsg, aParam.mPanDisplacement);
WriteParam(aMsg, aParam.mLocalPanStartPoint);
WriteParam(aMsg, aParam.mLocalPanDisplacement);
WriteParam(aMsg, aParam.mLineOrPageDeltaX);
WriteParam(aMsg, aParam.mLineOrPageDeltaY);
WriteParam(aMsg, aParam.mUserDeltaMultiplierX);
@@ -1246,17 +1254,17 @@ struct ParamTraits<mozilla::PinchGesture
template<>
struct ParamTraits<mozilla::PinchGestureInput>
{
typedef mozilla::PinchGestureInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mFocusPoint);
WriteParam(aMsg, aParam.mLocalFocusPoint);
WriteParam(aMsg, aParam.mCurrentSpan);
WriteParam(aMsg, aParam.mPreviousSpan);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@@ -1280,17 +1288,17 @@ struct ParamTraits<mozilla::TapGestureIn
template<>
struct ParamTraits<mozilla::TapGestureInput>
{
typedef mozilla::TapGestureInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mPoint);
WriteParam(aMsg, aParam.mLocalPoint);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, static_cast<mozilla::InputData*>(aResult)) &&
@@ -1318,17 +1326,17 @@ struct ParamTraits<mozilla::ScrollWheelI
template<>
struct ParamTraits<mozilla::ScrollWheelInput>
{
typedef mozilla::ScrollWheelInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mDeltaType);
WriteParam(aMsg, aParam.mScrollMode);
WriteParam(aMsg, aParam.mOrigin);
WriteParam(aMsg, aParam.mHandledByAPZ);
WriteParam(aMsg, aParam.mDeltaX);
WriteParam(aMsg, aParam.mDeltaY);
WriteParam(aMsg, aParam.mLocalOrigin);
WriteParam(aMsg, aParam.mLineOrPageDeltaX);
@@ -1372,17 +1380,17 @@ struct ParamTraits<mozilla::KeyboardInpu
template<>
struct ParamTraits<mozilla::KeyboardInput>
{
typedef mozilla::KeyboardInput paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, static_cast<mozilla::InputData>(aParam));
+ WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mKeyCode);
WriteParam(aMsg, aParam.mCharCode);
WriteParam(aMsg, aParam.mShortcutCandidates);
WriteParam(aMsg, aParam.mHandledByAPZ);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)