Bug 1400189 - Give same priority to composition events and selectionset event as keyboard events at sending those events from the main process to a remote process r?stone draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 29 Sep 2017 22:03:25 +0900
changeset 673021 d9aaf081af82f462a08f8b04f9f6ebffffe8db25
parent 673020 deddfcfe71c1df7afdc644d5c0fa4abea2890a28
child 733980 d4cf0430d16c1e83b56a6f1c644764460fdcf75b
push id82438
push usermasayuki@d-toybox.com
push dateSat, 30 Sep 2017 08:50:15 +0000
reviewersstone
bugs1400189
milestone58.0a1
Bug 1400189 - Give same priority to composition events and selectionset event as keyboard events at sending those events from the main process to a remote process r?stone When sending keyboard events from TabParent to its remote process, TabParent may give higher priority to them than composition events and selectionset event. Therefore, the event order between keyboard events and composition events (and selection set event) may be broken. Keyboard events which should cause inputting some characters are ignored if keyboard events are fired before compositionend event accidentally. This patch gives same priority to composition events and selectionset event as keyboard event for avoiding breaking the event order. MozReview-Commit-ID: 53jubwuHVvw
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -724,19 +724,21 @@ child:
      * @see nsIDOMWindowUtils sendKeyEvent.
      */
     async KeyEvent(nsString aType,
                    int32_t aKeyCode,
                    int32_t aCharCode,
                    int32_t aModifiers,
                    bool aPreventDefault);
 
-    async CompositionEvent(WidgetCompositionEvent event);
+    prio(input) async CompositionEvent(WidgetCompositionEvent event);
+    async NormalPriorityCompositionEvent(WidgetCompositionEvent event);
 
-    async SelectionEvent(WidgetSelectionEvent event);
+    prio(input) async SelectionEvent(WidgetSelectionEvent event);
+    async NormalPrioritySelectionEvent(WidgetSelectionEvent event);
 
     /**
      * Call PasteTransferable via a controller on the content process
      * to handle the command content event, "pasteTransferable".
      */
     async PasteTransferable(IPCDataTransfer aDataTransfer,
                             bool aIsPrivateData,
                             Principal aRequestingPrincipal);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2110,26 +2110,39 @@ TabChild::RecvCompositionEvent(const Wid
   WidgetCompositionEvent localEvent(aEvent);
   localEvent.mWidget = mPuppetWidget;
   DispatchWidgetEventViaAPZ(localEvent);
   Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+TabChild::RecvNormalPriorityCompositionEvent(
+            const WidgetCompositionEvent& aEvent)
+{
+  return RecvCompositionEvent(aEvent);
+}
+
+mozilla::ipc::IPCResult
 TabChild::RecvSelectionEvent(const WidgetSelectionEvent& aEvent)
 {
   WidgetSelectionEvent localEvent(aEvent);
   localEvent.mWidget = mPuppetWidget;
   DispatchWidgetEventViaAPZ(localEvent);
   Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
+TabChild::RecvNormalPrioritySelectionEvent(const WidgetSelectionEvent& aEvent)
+{
+  return RecvSelectionEvent(aEvent);
+}
+
+mozilla::ipc::IPCResult
 TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
                                 const bool& aIsPrivateData,
                                 const IPC::Principal& aRequestingPrincipal)
 {
   nsresult rv;
   nsCOMPtr<nsITransferable> trans =
     do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
   NS_ENSURE_SUCCESS(rv, IPC_OK());
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -461,19 +461,27 @@ public:
                                                               const nsCString& aResponse) override;
 
   virtual mozilla::ipc::IPCResult RecvPluginEvent(const WidgetPluginEvent& aEvent) override;
 
   virtual mozilla::ipc::IPCResult
   RecvCompositionEvent(const mozilla::WidgetCompositionEvent& aEvent) override;
 
   virtual mozilla::ipc::IPCResult
+  RecvNormalPriorityCompositionEvent(
+    const mozilla::WidgetCompositionEvent& aEvent) override;
+
+  virtual mozilla::ipc::IPCResult
   RecvSelectionEvent(const mozilla::WidgetSelectionEvent& aEvent) override;
 
   virtual mozilla::ipc::IPCResult
+  RecvNormalPrioritySelectionEvent(
+    const mozilla::WidgetSelectionEvent& aEvent) override;
+
+  virtual mozilla::ipc::IPCResult
   RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
                         const bool& aIsPrivateData,
                         const IPC::Principal& aRequestingPrincipal) override;
 
   virtual mozilla::ipc::IPCResult
   RecvActivateFrameEvent(const nsString& aType, const bool& aCapture) override;
 
   virtual mozilla::ipc::IPCResult RecvLoadRemoteScript(const nsString& aURL,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2300,17 +2300,22 @@ TabParent::SendCompositionEvent(WidgetCo
 {
   if (mIsDestroyed) {
     return false;
   }
 
   if (!mContentCache.OnCompositionEvent(aEvent)) {
     return true;
   }
-  if (NS_WARN_IF(!PBrowserParent::SendCompositionEvent(aEvent))) {
+
+  bool ret =
+    Manager()->AsContentParent()->IsInputPriorityEventEnabled()
+      ? PBrowserParent::SendCompositionEvent(aEvent)
+      : PBrowserParent::SendNormalPriorityCompositionEvent(aEvent);
+  if (NS_WARN_IF(!ret)) {
     return false;
   }
   MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
   return true;
 }
 
 bool
 TabParent::SendSelectionEvent(WidgetSelectionEvent& aEvent)
@@ -2318,17 +2323,21 @@ TabParent::SendSelectionEvent(WidgetSele
   if (mIsDestroyed) {
     return false;
   }
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return true;
   }
   mContentCache.OnSelectionEvent(aEvent);
-  if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(aEvent))) {
+  bool ret =
+    Manager()->AsContentParent()->IsInputPriorityEventEnabled()
+      ? PBrowserParent::SendSelectionEvent(aEvent)
+      : PBrowserParent::SendNormalPrioritySelectionEvent(aEvent);
+  if (NS_WARN_IF(!ret)) {
     return false;
   }
   MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
   aEvent.mSucceeded = true;
   return true;
 }
 
 bool