Bug 1495978 - Make PuppetWidget::StartPluginIME() restore cross process dispatching state of given keyboard event instance after sending it to the main process synchronously r=m_kato

PuppetWidget::StartPluginIME() calls TabChild::SendStartPluginIME()
with given WidgetKeyboardEvent instance.  Then, the keyboard event
will be marked as "posted to remote process" by
ParamTraits<mozilla::WidgetEvent>::Write().  However, the method
sends back the keyboard event to the main process synchronously.
So, we don't want the event is treated as "posted" since the
flag is used to check whether current process handles posted event
*before* the remote process or not.

So, PuppetWidget::StartPluginIME() should restore the cross process
dispatching state with calling
WidgetEvent::ResetCrossProcessDispatchingState().  Unfortunately,
this also clears propagation state of the event too if the event
has already been posted to a remote process and is waiting reply
from the remote process.  This shouldn't occur in content
process, however, we should check it with MOZ_ASSERT() for
detecting regressions.

Differential Revision: https://phabricator.services.mozilla.com/D7579
This commit is contained in:
Masayuki Nakano
2018-10-09 01:29:42 +00:00
parent 7266f6f4bb
commit a9b7564a2f

View File

@@ -718,15 +718,35 @@ PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
}
nsresult
PuppetWidget::StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
PuppetWidget::StartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
int32_t aPanelX, int32_t aPanelY,
nsString& aCommitted)
{
DebugOnly<bool> propagationAlreadyStopped =
aKeyboardEvent.mFlags.mPropagationStopped;
DebugOnly<bool> immediatePropagationAlreadyStopped =
aKeyboardEvent.mFlags.mImmediatePropagationStopped;
if (!mTabChild ||
!mTabChild->SendStartPluginIME(aKeyboardEvent, aPanelX,
aPanelY, &aCommitted)) {
return NS_ERROR_FAILURE;
}
// TabChild::SendStartPluginIME() sends back the keyboard event to the main
// process synchronously. At this time, ParamTraits<WidgetEvent>::Write()
// marks the event as "posted to remote process". However, this is not
// correct here since the event has been handled synchronously in the main
// process. So, we adjust the cross process dispatching state here.
const_cast<WidgetKeyboardEvent&>(aKeyboardEvent).
ResetCrossProcessDispatchingState();
// Although it shouldn't occur in content process,
// ResetCrossProcessDispatchingState() may reset propagation state too
// if the event was posted to a remote process and we're waiting its
// result. So, if you saw hitting the following assertions, you'd
// need to restore the propagation state too.
MOZ_ASSERT(propagationAlreadyStopped ==
aKeyboardEvent.mFlags.mPropagationStopped);
MOZ_ASSERT(immediatePropagationAlreadyStopped ==
aKeyboardEvent.mFlags.mImmediatePropagationStopped);
return NS_OK;
}