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
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 09 Oct 2018 01:29:42 +0000
changeset 440043 80f3e8b1d66fb5a9dbaba457ae2535a679ec49c5
parent 440042 2cdf1848b6a7f7e006233a95ed78085d19d6ab6f
child 440138 ac590db9a29403e4d42559f394f7ffab7d2c2eb5
push id70563
push usermasayuki@d-toybox.com
push dateTue, 09 Oct 2018 01:52:01 +0000
treeherderautoland@80f3e8b1d66f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1495978
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
widget/PuppetWidget.cpp
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -713,25 +713,45 @@ PuppetWidget::RequestIMEToCommitComposit
   Unused <<
     mTabChild->SendOnEventNeedingAckHandled(eCompositionCommitRequestHandled);
 
   // NOTE: PuppetWidget might be destroyed already.
   return NS_OK;
 }
 
 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;
 }
 
 void
 PuppetWidget::SetPluginFocused(bool& aFocused)
 {
   if (mTabChild) {
     mTabChild->SendSetPluginFocused(aFocused);