Bug 1189396 part.3 Make IMENotification::SelectionChangeData useful even outside of IMENotification r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 22 Aug 2015 01:43:41 +0900
changeset 291465 c5f78184538a0ce83186948a8983344318755556
parent 291464 f99e7dec5a4f5ca54d0562431bc67bdbff8a7695
child 291466 f124971f48a6d519bf79a0f360e6b5acdff673fb
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1189396
milestone43.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 1189396 part.3 Make IMENotification::SelectionChangeData useful even outside of IMENotification r=smaug
widget/IMEData.h
widget/gtk/IMContextWrapper.cpp
widget/nsBaseWidget.cpp
widget/nsGUIEventIPC.h
widget/windows/TSFTextStore.cpp
--- a/widget/IMEData.h
+++ b/widget/IMEData.h
@@ -534,17 +534,17 @@ struct IMENotification final
     }
     nsIntRect AsIntRect() const
     {
       return nsIntRect(mX, mY, mWidth, mHeight);
     }
   };
 
   // NOTIFY_IME_OF_SELECTION_CHANGE specific data
-  struct SelectionChangeData
+  struct SelectionChangeDataBase
   {
     // Selection range.
     uint32_t mOffset;
 
     // Selected string
     nsString* mString;
 
     // Writing mode at the selection.
@@ -585,27 +585,67 @@ struct IMENotification final
       mReversed = false;
       mCausedByComposition = false;
       mCausedBySelectionEvent = false;
     }
     bool IsValid() const
     {
       return mOffset != UINT32_MAX;
     }
-    void Assign(const SelectionChangeData& aOther)
+    void Assign(const SelectionChangeDataBase& aOther)
     {
       mOffset = aOther.mOffset;
       *mString = aOther.String();
       mWritingMode = aOther.mWritingMode;
       mReversed = aOther.mReversed;
       mCausedByComposition = aOther.mCausedByComposition;
       mCausedBySelectionEvent = aOther.mCausedBySelectionEvent;
     }
   };
 
+  // SelectionChangeDataBase cannot have constructors because it's used in
+  // the union.  Therefore, SelectionChangeData should only implement
+  // constructors.  In other words, add other members to
+  // SelectionChangeDataBase.
+  struct SelectionChangeData final : public SelectionChangeDataBase
+  {
+    SelectionChangeData()
+    {
+      mString = &mStringInstance;
+      Clear();
+    }
+    explicit SelectionChangeData(const SelectionChangeDataBase& aOther)
+    {
+      mString = &mStringInstance;
+      Assign(aOther);
+    }
+    SelectionChangeData(const SelectionChangeData& aOther)
+    {
+      mString = &mStringInstance;
+      Assign(aOther);
+    }
+    SelectionChangeData& operator=(const SelectionChangeDataBase& aOther)
+    {
+      mString = &mStringInstance;
+      Assign(aOther);
+      return *this;
+    }
+    SelectionChangeData& operator=(const SelectionChangeData& aOther)
+    {
+      mString = &mStringInstance;
+      Assign(aOther);
+      return *this;
+    }
+
+  private:
+    // When SelectionChangeData is used outside of union, it shouldn't create
+    // nsString instance in the heap as far as possible.
+    nsString mStringInstance;
+  };
+
   struct TextChangeDataBase
   {
     // mStartOffset is the start offset of modified or removed text in
     // original content and inserted text in new content.
     uint32_t mStartOffset;
     // mRemovalEndOffset is the end offset of modified or removed text in
     // original content.  If the value is same as mStartOffset, no text hasn't
     // been removed yet.
@@ -703,17 +743,17 @@ struct IMENotification final
     int16_t mButtons;
     // The value of WidgetInputEvent::modifiers
     Modifiers mModifiers;
   };
 
   union
   {
     // NOTIFY_IME_OF_SELECTION_CHANGE specific data
-    SelectionChangeData mSelectionChangeData;
+    SelectionChangeDataBase mSelectionChangeData;
 
     // NOTIFY_IME_OF_TEXT_CHANGE specific data
     TextChangeDataBase mTextChangeData;
 
     // NOTIFY_IME_OF_MOUSE_BUTTON_EVENT specific data
     MouseButtonEventData mMouseButtonEventData;
   };
 
--- a/widget/gtk/IMContextWrapper.cpp
+++ b/widget/gtk/IMContextWrapper.cpp
@@ -878,17 +878,17 @@ IMContextWrapper::OnSelectionChange(nsWi
                                     const IMENotification& aIMENotification)
 {
     mSelection.Assign(aIMENotification);
 
     if (MOZ_UNLIKELY(IsDestroyed())) {
         return;
     }
 
-    const IMENotification::SelectionChangeData& selectionChangeData =
+    const IMENotification::SelectionChangeDataBase& selectionChangeData =
         aIMENotification.mSelectionChangeData;
 
     MOZ_LOG(gGtkIMLog, LogLevel::Info,
         ("GTKIM: %p OnSelectionChange(aCaller=0x%p, aIMENotification={ "
          "mSelectionChangeData={ mOffset=%u, Length()=%u, mReversed=%s, "
          "mWritingMode=%s, mCausedByComposition=%s, mCausedBySelectionEvent=%s "
          "} }), mCompositionState=%s, mIsDeletingSurrounding=%s",
          this, aCaller, selectionChangeData.mOffset,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -101,24 +101,24 @@ int32_t nsIWidget::sPointerIdCounter = 0
 // Some statics from nsIWidget.h
 /*static*/ uint64_t AutoObserverNotifier::sObserverId = 0;
 /*static*/ nsDataHashtable<nsUint64HashKey, nsCOMPtr<nsIObserver>> AutoObserverNotifier::sSavedObservers;
 
 namespace mozilla {
 namespace widget {
 
 void
-IMENotification::SelectionChangeData::SetWritingMode(
+IMENotification::SelectionChangeDataBase::SetWritingMode(
                                         const WritingMode& aWritingMode)
 {
   mWritingMode = aWritingMode.mWritingMode;
 }
 
 WritingMode
-IMENotification::SelectionChangeData::GetWritingMode() const
+IMENotification::SelectionChangeDataBase::GetWritingMode() const
 {
   return WritingMode(mWritingMode);
 }
 
 } // namespace widget
 } // namespace mozilla
 
 nsAutoRollup::nsAutoRollup()
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -696,19 +696,19 @@ struct ParamTraits<mozilla::widget::IMEN
     return ReadParam(aMsg, aIter, &aResult->mX) &&
            ReadParam(aMsg, aIter, &aResult->mY) &&
            ReadParam(aMsg, aIter, &aResult->mWidth) &&
            ReadParam(aMsg, aIter, &aResult->mHeight);
   }
 };
 
 template<>
-struct ParamTraits<mozilla::widget::IMENotification::SelectionChangeData>
+struct ParamTraits<mozilla::widget::IMENotification::SelectionChangeDataBase>
 {
-  typedef mozilla::widget::IMENotification::SelectionChangeData paramType;
+  typedef mozilla::widget::IMENotification::SelectionChangeDataBase paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     MOZ_RELEASE_ASSERT(aParam.mString);
     WriteParam(aMsg, aParam.mOffset);
     WriteParam(aMsg, *aParam.mString);
     WriteParam(aMsg, aParam.mWritingMode);
     WriteParam(aMsg, aParam.mReversed);
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -4503,17 +4503,17 @@ TSFTextStore::NotifyTSFOfTextChange(cons
           "acpNewEnd=%ld })...", this, aTextChange.acpStart,
           aTextChange.acpOldEnd, aTextChange.acpNewEnd));
   mSink->OnTextChange(0, &aTextChange);
 }
 
 nsresult
 TSFTextStore::OnSelectionChangeInternal(const IMENotification& aIMENotification)
 {
-  const IMENotification::SelectionChangeData& selectionChangeData =
+  const IMENotification::SelectionChangeDataBase& selectionChangeData =
     aIMENotification.mSelectionChangeData;
   MOZ_LOG(sTextStoreLog, LogLevel::Debug,
          ("TSF: 0x%p   TSFTextStore::OnSelectionChangeInternal("
           "aIMENotification={ mSelectionChangeData={ mOffset=%lu, "
           "Length()=%lu, mReversed=%s, mWritingMode=%s, "
           "mCausedByComposition=%s, mCausedBySelectionEvent=%s } }), "
           "mSink=0x%p, mSinkMask=%s, mIsRecordingActionsWithoutLock=%s, "
           "mComposition.IsComposing()=%s",