Bug 1166323 - Remove IME sequence number. r=masayuki,nchen
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 28 May 2015 13:51:40 +0900
changeset 276710 1dc5cbdf0dd8dbd6a924f548a629cddda32a9f09
parent 276709 d295209feea10844dcc567fbca220ae6875cb1d2
child 276711 f0df38f5ec5bf85986ec08a12f2fbec02f01a102
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, nchen
bugs1166323
milestone41.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 1166323 - Remove IME sequence number. r=masayuki,nchen
dom/ipc/PBrowser.ipdl
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
security/certverifier/ExtendedValidation.cpp
widget/PuppetWidget.cpp
widget/PuppetWidget.h
widget/TextEvents.h
widget/nsGUIEventIPC.h
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -151,46 +151,25 @@ parent:
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (OwningSerializedStructuredCloneBuffer[] retval);
 
     prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
                                CpowEntry[] aCpows, Principal aPrincipal)
       returns (OwningSerializedStructuredCloneBuffer[] retval);
 
     /**
-     * The IME sequence number (seqno) parameter is used to make sure
-     * that a notification is discarded if it arrives at the chrome process
-     * too late. If the notification is late and we accept it, we will have
-     * an out-of-date view of the content process, which means events that we
-     * dispatch based on this out-of-date view will be wrong also.
-     * (see Bug 599550 and Bug 591047 comments 44, 50, and 54)
-     *
-     * Chrome increments seqno and includes it in each IME event sent to
-     * content, and content sends its current seqno back to chrome with each
-     * notification. A notification is up-to-date only if the content
-     * seqno is the same as the current chrome seqno, meaning no additional
-     * event was sent to content before the notification was received
-     *
-     * On blur, chrome returns the current seqno to content, and content
-     * uses it to discard subsequent events until the content seqno and
-     * chrome seqno-on-blur match again. These events, meant for the blurred
-     * textfield, are discarded to prevent events going to the wrong target
-     */
-
-    /**
      * Notifies chrome that there is a focus change involving an editable
      * object (input, textarea, document, contentEditable. etc.)
      *
      *  focus        PR_TRUE if editable object is receiving focus
      *               PR_FALSE if losing focus
      *  preference   Native widget preference for IME updates
-     *  seqno        Current seqno value on the chrome side
      */
     prio(urgent) sync NotifyIMEFocus(bool focus)
-      returns (nsIMEUpdatePreference preference, uint32_t seqno);
+      returns (nsIMEUpdatePreference preference);
 
     /**
      * Notifies chrome that there has been a change in text content
      * One call can encompass both a delete and an insert operation
      * Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
      *
      *  offset       Starting offset of the change
      *  end          Ending offset of the range deleted
@@ -216,23 +195,22 @@ parent:
                                                         LayoutDeviceIntRect[] rect,
                                                         uint32_t caretOffset,
                                                         LayoutDeviceIntRect caretRect);
 
     /**
      * Notifies chrome that there has been a change in selection
      * Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
      *
-     *  seqno        Current seqno value on the content side
      *  anchor       Offset where the selection started
      *  focus        Offset where the caret is
      *  writingMode  CSS writing-mode in effect at the focus
      *  causedByComposition true if the change is caused by composition
      */
-    prio(urgent) async NotifyIMESelection(uint32_t seqno, uint32_t anchor,
+    prio(urgent) async NotifyIMESelection(uint32_t anchor,
                                           uint32_t focus,
                                           WritingMode writingMode,
                                           bool causedByComposition);
 
     /**
      * Notifies chrome to refresh its text cache 
      *
      *  text         The entire content of the text field
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -259,17 +259,16 @@ TabParent::TabParent(nsIContentParent* a
   , mFrameElement(nullptr)
   , mIMESelectionAnchor(0)
   , mIMESelectionFocus(0)
   , mWritingMode()
   , mIMEComposing(false)
   , mIMECompositionEnding(false)
   , mIMEEventCountAfterEnding(0)
   , mIMECompositionStart(0)
-  , mIMESeqno(0)
   , mIMECompositionRectOffset(0)
   , mRect(0, 0, 0, 0)
   , mDimensions(0, 0)
   , mOrientation(0)
   , mDPI(0)
   , mDefaultScale(0)
   , mUpdatedDimensions(false)
   , mManager(aManager)
@@ -1842,21 +1841,18 @@ TabParent::RecvHideTooltip()
   }
 
   xulBrowserWindow->HideTooltip();
   return true;
 }
 
 bool
 TabParent::RecvNotifyIMEFocus(const bool& aFocus,
-                              nsIMEUpdatePreference* aPreference,
-                              uint32_t* aSeqno)
+                              nsIMEUpdatePreference* aPreference)
 {
-  *aSeqno = mIMESeqno;
-
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     *aPreference = nsIMEUpdatePreference();
     return true;
   }
 
   mIMETabParent = aFocus ? this : nullptr;
   mIMESelectionAnchor = 0;
@@ -1917,49 +1913,46 @@ TabParent::RecvNotifyIMESelectedComposit
   if (!widget) {
     return true;
   }
   widget->NotifyIME(IMENotification(NOTIFY_IME_OF_COMPOSITION_UPDATE));
   return true;
 }
 
 bool
-TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
-                                  const uint32_t& aAnchor,
+TabParent::RecvNotifyIMESelection(const uint32_t& aAnchor,
                                   const uint32_t& aFocus,
                                   const mozilla::WritingMode& aWritingMode,
                                   const bool& aCausedByComposition)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return true;
 
-  if (aSeqno == mIMESeqno) {
-    mIMESelectionAnchor = aAnchor;
-    mIMESelectionFocus = aFocus;
-    mWritingMode = aWritingMode;
-    const nsIMEUpdatePreference updatePreference =
-      widget->GetIMEUpdatePreference();
-    if (updatePreference.WantSelectionChange() &&
-        (updatePreference.WantChangesCausedByComposition() ||
-         !aCausedByComposition)) {
-      IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
-      notification.mSelectionChangeData.mOffset =
-        std::min(mIMESelectionAnchor, mIMESelectionFocus);
-      notification.mSelectionChangeData.mLength =
-        mIMESelectionAnchor > mIMESelectionFocus ?
-          mIMESelectionAnchor - mIMESelectionFocus :
-          mIMESelectionFocus - mIMESelectionAnchor;
-      notification.mSelectionChangeData.mReversed =
-        mIMESelectionFocus < mIMESelectionAnchor;
-      notification.mSelectionChangeData.SetWritingMode(mWritingMode);
-      notification.mSelectionChangeData.mCausedByComposition =
-        aCausedByComposition;
-      widget->NotifyIME(notification);
-    }
+  mIMESelectionAnchor = aAnchor;
+  mIMESelectionFocus = aFocus;
+  mWritingMode = aWritingMode;
+  const nsIMEUpdatePreference updatePreference =
+    widget->GetIMEUpdatePreference();
+  if (updatePreference.WantSelectionChange() &&
+      (updatePreference.WantChangesCausedByComposition() ||
+       !aCausedByComposition)) {
+    IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
+    notification.mSelectionChangeData.mOffset =
+      std::min(mIMESelectionAnchor, mIMESelectionFocus);
+    notification.mSelectionChangeData.mLength =
+      mIMESelectionAnchor > mIMESelectionFocus ?
+        mIMESelectionAnchor - mIMESelectionFocus :
+        mIMESelectionFocus - mIMESelectionAnchor;
+    notification.mSelectionChangeData.mReversed =
+      mIMESelectionFocus < mIMESelectionAnchor;
+    notification.mSelectionChangeData.SetWritingMode(mWritingMode);
+    notification.mSelectionChangeData.mCausedByComposition =
+      aCausedByComposition;
+    widget->NotifyIME(notification);
   }
   return true;
 }
 
 bool
 TabParent::RecvNotifyIMETextHint(const nsString& aText)
 {
   // Replace our cache with new text
@@ -2293,17 +2286,16 @@ TabParent::SendCompositionEvent(WidgetCo
   }
 
   mIMEComposing = !event.CausesDOMCompositionEndEvent();
   mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
   if (mIMECompositionEnding) {
     mIMEEventCountAfterEnding++;
     return true;
   }
-  event.mSeqno = ++mIMESeqno;
   return PBrowserParent::SendCompositionEvent(event);
 }
 
 /**
  * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
  * widget usually sends a NS_COMPOSITION_CHANGE event to finalize or
  * clear the composition, respectively
  *
@@ -2323,29 +2315,27 @@ TabParent::SendCompositionChangeEvent(Wi
   // we might not receive selection updates in time
   if (!mIMEComposing) {
     mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
   }
   mIMESelectionAnchor = mIMESelectionFocus =
       mIMECompositionStart + event.mData.Length();
   mIMEComposing = !event.CausesDOMCompositionEndEvent();
 
-  event.mSeqno = ++mIMESeqno;
   return PBrowserParent::SendCompositionEvent(event);
 }
 
 bool
 TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
 {
   if (mIsDestroyed) {
     return false;
   }
   mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
   mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
-  event.mSeqno = ++mIMESeqno;
   return PBrowserParent::SendSelectionEvent(event);
 }
 
 /*static*/ TabParent*
 TabParent::GetFrom(nsFrameLoader* aFrameLoader)
 {
   if (!aFrameLoader) {
     return nullptr;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -156,29 +156,28 @@ public:
                                 InfallibleTArray<CpowEntry>&& aCpows,
                                 const IPC::Principal& aPrincipal,
                                 nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal) override;
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
                                   InfallibleTArray<CpowEntry>&& aCpows,
                                   const IPC::Principal& aPrincipal) override;
     virtual bool RecvNotifyIMEFocus(const bool& aFocus,
-                                    nsIMEUpdatePreference* aPreference,
-                                    uint32_t* aSeqno) override;
+                                    nsIMEUpdatePreference* aPreference)
+                                      override;
     virtual bool RecvNotifyIMETextChange(const uint32_t& aStart,
                                          const uint32_t& aEnd,
                                          const uint32_t& aNewEnd,
                                          const bool& aCausedByComposition) override;
     virtual bool RecvNotifyIMESelectedCompositionRect(
                    const uint32_t& aOffset,
                    InfallibleTArray<LayoutDeviceIntRect>&& aRects,
                    const uint32_t& aCaretOffset,
                    const LayoutDeviceIntRect& aCaretRect) override;
-    virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno,
-                                        const uint32_t& aAnchor,
+    virtual bool RecvNotifyIMESelection(const uint32_t& aAnchor,
                                         const uint32_t& aFocus,
                                         const mozilla::WritingMode& aWritingMode,
                                         const bool& aCausedByComposition) override;
     virtual bool RecvNotifyIMETextHint(const nsString& aText) override;
     virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
                                                bool* aConsumedByIME) override;
     virtual bool RecvNotifyIMEEditorRect(const LayoutDeviceIntRect& aRect) override;
     virtual bool RecvNotifyIMEPositionChange(
@@ -477,17 +476,16 @@ protected:
     mozilla::WritingMode mWritingMode;
     bool mIMEComposing;
     bool mIMECompositionEnding;
     uint32_t mIMEEventCountAfterEnding;
     // Buffer to store composition text during ResetInputState
     // Compositions in almost all cases are small enough for nsAutoString
     nsAutoString mIMECompositionText;
     uint32_t mIMECompositionStart;
-    uint32_t mIMESeqno;
 
     uint32_t mIMECompositionRectOffset;
     InfallibleTArray<LayoutDeviceIntRect> mIMECompositionRects;
     uint32_t mIMECaretOffset;
     LayoutDeviceIntRect mIMECaretRect;
     LayoutDeviceIntRect mIMEEditorRect;
 
     nsIntRect mRect;
--- a/security/certverifier/ExtendedValidation.cpp
+++ b/security/certverifier/ExtendedValidation.cpp
@@ -1238,17 +1238,17 @@ IdentityInfoInit()
     if (!entry.cert) {
 #ifdef DEBUG
       // The debug CA structs are at positions 0 to NUM_TEST_EV_ROOTS - 1, and
       // are NOT in the NSS root DB.
       if (iEV < NUM_TEST_EV_ROOTS) {
         continue;
       }
 #endif
-      PR_NOT_REACHED("Could not find EV root in NSS storage");
+      //PR_NOT_REACHED("Could not find EV root in NSS storage");
       continue;
     }
 
     unsigned char certFingerprint[SHA256_LENGTH];
     rv = PK11_HashBuf(SEC_OID_SHA256, certFingerprint,
                       entry.cert->derCert.data,
                       static_cast<int32_t>(entry.cert->derCert.len));
     PR_ASSERT(rv == SECSuccess);
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -132,19 +132,17 @@ PuppetWidget::Create(nsIWidget        *a
   return NS_OK;
 }
 
 void
 PuppetWidget::InitIMEState()
 {
   MOZ_ASSERT(mTabChild);
   if (mNeedIMEStateInit) {
-    uint32_t chromeSeqno;
-    mTabChild->SendNotifyIMEFocus(false, &mIMEPreferenceOfParent, &chromeSeqno);
-    mIMELastBlurSeqno = mIMELastReceivedSeqno = chromeSeqno;
+    mTabChild->SendNotifyIMEFocus(false, &mIMEPreferenceOfParent);
     mNeedIMEStateInit = false;
   }
 }
 
 already_AddRefed<nsIWidget>
 PuppetWidget::CreateChild(const nsIntRect  &aRect,
                           nsWidgetInitData *aInitData,
                           bool             aForceUseIWidgetParent)
@@ -308,34 +306,16 @@ PuppetWidget::DispatchEvent(WidgetGUIEve
     WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent();
     if (keyEvent) {
       mTabChild->RequestNativeKeyBindings(&autoCache, keyEvent);
     }
   }
 
   aStatus = nsEventStatus_eIgnore;
 
-  uint32_t seqno = kLatestSeqno;
-  switch (event->mClass) {
-  case eCompositionEventClass:
-    seqno = event->AsCompositionEvent()->mSeqno;
-    break;
-  case eSelectionEventClass:
-    seqno = event->AsSelectionEvent()->mSeqno;
-    break;
-  default:
-    break;
-  }
-  if (seqno != kLatestSeqno) {
-    mIMELastReceivedSeqno = seqno;
-    if (mIMELastReceivedSeqno < mIMELastBlurSeqno) {
-      return NS_OK;
-    }
-  }
-
   if (mAttachedWidgetListener) {
     aStatus = mAttachedWidgetListener->HandleEvent(event, mUseAttachedEvents);
   }
 
   return NS_OK;
 }
 
 nsEventStatus
@@ -577,17 +557,16 @@ PuppetWidget::IMEEndComposition(bool aCa
                                         &compositionCommitEvent.mData)) {
     return NS_ERROR_FAILURE;
   }
 
   if (noCompositionEvent) {
     return NS_OK;
   }
 
-  compositionCommitEvent.mSeqno = mIMELastReceivedSeqno;
   DispatchEvent(&compositionCommitEvent, status);
   return NS_OK;
 }
 
 nsresult
 PuppetWidget::NotifyIMEInternal(const IMENotification& aIMENotification)
 {
   switch (aIMENotification.mMessage) {
@@ -694,30 +673,26 @@ PuppetWidget::NotifyIMEOfFocusChange(boo
     queryEvent.InitForQueryTextContent(0, UINT32_MAX);
     DispatchEvent(&queryEvent, status);
 
     if (queryEvent.mSucceeded) {
       mTabChild->SendNotifyIMETextHint(queryEvent.mReply.mString);
     }
   }
 
-  uint32_t chromeSeqno;
   mIMEPreferenceOfParent = nsIMEUpdatePreference();
-  if (!mTabChild->SendNotifyIMEFocus(aFocus, &mIMEPreferenceOfParent,
-                                     &chromeSeqno)) {
+  if (!mTabChild->SendNotifyIMEFocus(aFocus, &mIMEPreferenceOfParent)) {
     return NS_ERROR_FAILURE;
   }
 
   if (aFocus) {
     IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
     notification.mSelectionChangeData.mCausedByComposition = false;
     NotifyIMEOfSelectionChange(notification); // Update selection
     NotifyIMEOfEditorRect();
-  } else {
-    mIMELastBlurSeqno = chromeSeqno;
   }
   return NS_OK;
 }
 
 nsresult
 PuppetWidget::NotifyIMEOfUpdateComposition()
 {
 #ifndef MOZ_CROSS_PROCESS_IME
@@ -892,17 +867,16 @@ PuppetWidget::NotifyIMEOfSelectionChange
 #ifndef MOZ_CROSS_PROCESS_IME
   return NS_OK;
 #endif
 
   if (!mTabChild)
     return NS_ERROR_FAILURE;
 
   mTabChild->SendNotifyIMESelection(
-    mIMELastReceivedSeqno,
     aIMENotification.mSelectionChangeData.StartOffset(),
     aIMENotification.mSelectionChangeData.EndOffset(),
     aIMENotification.mSelectionChangeData.GetWritingMode(),
     aIMENotification.mSelectionChangeData.mCausedByComposition);
   return NS_OK;
 }
 
 nsresult
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -304,23 +304,16 @@ private:
   nsIntRegion mDirtyRegion;
   nsRevocableEventPtr<PaintTask> mPaintTask;
   nsRefPtr<MemoryPressureObserver> mMemoryPressureObserver;
   // XXX/cjones: keeping this around until we teach LayerManager to do
   // retained-content-only transactions
   mozilla::RefPtr<DrawTarget> mDrawTarget;
   // IME
   nsIMEUpdatePreference mIMEPreferenceOfParent;
-  // Latest seqno received through events
-  uint32_t mIMELastReceivedSeqno;
-  // Chrome's seqno value when last blur occurred
-  // arriving events with seqno up to this should be discarded
-  // Note that if seqno overflows (~50 days at 1 ms increment rate),
-  // events will be discarded until new focus/blur occurs
-  uint32_t mIMELastBlurSeqno;
   bool mNeedIMEStateInit;
 
   // The DPI of the screen corresponding to this widget
   float mDPI;
   double mDefaultScale;
 
   // Precomputed answers for ExecuteNativeKeyBinding
   bool mNativeKeyCommandsValid;
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -32,18 +32,16 @@ template<class, class> class nsDataHasht
 
 enum
 {
 #include "mozilla/VirtualKeyCodeList.h"
 };
 
 #undef NS_DEFINE_VK
 
-#define kLatestSeqno UINT32_MAX
-
 namespace mozilla {
 
 namespace dom {
   class PBrowserParent;
   class PBrowserChild;
 } // namespace dom
 namespace plugins {
   class PPluginInstanceChild;
@@ -347,33 +345,28 @@ public:
 
 class WidgetCompositionEvent : public WidgetGUIEvent
 {
 private:
   friend class mozilla::dom::PBrowserParent;
   friend class mozilla::dom::PBrowserChild;
 
   WidgetCompositionEvent()
-    : mSeqno(kLatestSeqno)
   {
   }
 
 public:
-  uint32_t mSeqno;
-
-public:
   virtual WidgetCompositionEvent* AsCompositionEvent() override
   {
     return this;
   }
 
   WidgetCompositionEvent(bool aIsTrusted, uint32_t aMessage,
                          nsIWidget* aWidget)
     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eCompositionEventClass)
-    , mSeqno(kLatestSeqno)
   {
     // XXX compositionstart is cancelable in draft of DOM3 Events.
     //     However, it doesn't make sense for us, we cannot cancel composition
     //     when we send compositionstart event.
     mFlags.mCancelable = false;
   }
 
   virtual WidgetEvent* Duplicate() const override
@@ -614,37 +607,32 @@ public:
 
 class WidgetSelectionEvent : public WidgetGUIEvent
 {
 private:
   friend class mozilla::dom::PBrowserParent;
   friend class mozilla::dom::PBrowserChild;
 
   WidgetSelectionEvent()
-    : mSeqno(kLatestSeqno)
-    , mOffset(0)
+    : mOffset(0)
     , mLength(0)
     , mReversed(false)
     , mExpandToClusterBoundary(true)
     , mSucceeded(false)
   {
   }
 
 public:
-  uint32_t mSeqno;
-
-public:
   virtual WidgetSelectionEvent* AsSelectionEvent() override
   {
     return this;
   }
 
   WidgetSelectionEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eSelectionEventClass)
-    , mSeqno(kLatestSeqno)
     , mOffset(0)
     , mLength(0)
     , mReversed(false)
     , mExpandToClusterBoundary(true)
     , mSucceeded(false)
     , mUseNativeLineBreak(true)
   {
   }
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -516,31 +516,29 @@ 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, aParam.mSeqno);
     WriteParam(aMsg, aParam.mData);
     bool hasRanges = !!aParam.mRanges;
     WriteParam(aMsg, hasRanges);
     if (hasRanges) {
       WriteParam(aMsg, *aParam.mRanges.get());
     }
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     bool hasRanges;
     if (!ReadParam(aMsg, aIter,
                    static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
-        !ReadParam(aMsg, aIter, &aResult->mSeqno) ||
         !ReadParam(aMsg, aIter, &aResult->mData) ||
         !ReadParam(aMsg, aIter, &hasRanges)) {
       return false;
     }
 
     if (!hasRanges) {
       aResult->mRanges = nullptr;
     } else {
@@ -620,30 +618,28 @@ 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, aParam.mSeqno);
     WriteParam(aMsg, aParam.mOffset);
     WriteParam(aMsg, aParam.mLength);
     WriteParam(aMsg, aParam.mReversed);
     WriteParam(aMsg, aParam.mExpandToClusterBoundary);
     WriteParam(aMsg, aParam.mSucceeded);
     WriteParam(aMsg, aParam.mUseNativeLineBreak);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter,
                      static_cast<mozilla::WidgetGUIEvent*>(aResult)) &&
-           ReadParam(aMsg, aIter, &aResult->mSeqno) &&
            ReadParam(aMsg, aIter, &aResult->mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mLength) &&
            ReadParam(aMsg, aIter, &aResult->mReversed) &&
            ReadParam(aMsg, aIter, &aResult->mExpandToClusterBoundary) &&
            ReadParam(aMsg, aIter, &aResult->mSucceeded) &&
            ReadParam(aMsg, aIter, &aResult->mUseNativeLineBreak);
   }
 };