Bug 1312302 - Set dummy Selection during initializing TextStore. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Tue, 25 Oct 2016 17:53:38 +0900
changeset 429570 9e4838ffc5c8d8cf0e67685c6c1da09ecba6c7a9
parent 429408 b1b18f25c0ea69d9ee57c4198d577dfcd0129ce1
child 534996 7b201313708e9712725f4eb923dc867b8d19dcba
push id33599
push userm_kato@ga2.so-net.ne.jp
push dateWed, 26 Oct 2016 03:11:14 +0000
reviewersmasayuki
bugs1312302
milestone52.0a1
Bug 1312302 - Set dummy Selection during initializing TextStore. r?masayuki When PC supports table mode, TextInputFramme.dll is loaded and it can be used for TIP. When creating new TextStore object, selection might be nothing yet on e10s. At this time, GetSelection will return E_FAIL since selection data isn't received yet. If GetSelection returns error during SetFocus, TextInputFrame.dll will crash. So we set temporary selection to avoid crash. MozReview-Commit-ID: HyVSwvhXGJh
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -4788,17 +4788,27 @@ TSFTextStore::CreateAndSetFocus(nsWindow
   if (aContext.mIMEState.mEnabled == IMEState::PASSWORD) {
     MarkContextAsKeyboardDisabled(textStore->mContext);
     RefPtr<ITfContext> topContext;
     textStore->mDocumentMgr->GetTop(getter_AddRefs(topContext));
     if (topContext && topContext != textStore->mContext) {
       MarkContextAsKeyboardDisabled(topContext);
     }
   }
-  HRESULT hr = sThreadMgr->SetFocus(textStore->mDocumentMgr);
+
+  HRESULT hr;
+  {
+    // Windows 10's softwware keyboard requires that SetSelection must be
+    // always successful into SetFocus.  If returning error, it might crash
+    // into TextInputFramework.dll.
+    AutoSetTemporarySelection setSelection(textStore->SelectionForTSFRef());
+
+    hr = sThreadMgr->SetFocus(textStore->mDocumentMgr);
+  }
+
   if (NS_WARN_IF(FAILED(hr))) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("  TSFTextStore::CreateAndSetFocus() FAILED due to "
        "ITfTheadMgr::SetFocus() failure"));
     return false;
   }
   // Use AssociateFocus() for ensuring that any native focus event
   // never steal focus from our documentMgr.
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -573,31 +573,55 @@ protected:
              aChangedSelection.mOffset == static_cast<uint32_t>(StartOffset());
     }
 
   private:
     TS_SELECTION_ACP mACP;
     WritingMode mWritingMode;
     bool mDirty;
   };
+
   // Don't access mSelection directly except at calling MarkDirty().
   // Use SelectionForTSFRef() instead.  This is modified immediately when
   // TSF requests to set selection and not updated by selection change in
   // content until mContentForTSF is cleared.
   Selection mSelectionForTSF;
 
   /**
    * Get the selection expected by TSF.  If mSelectionForTSF is already valid,
    * this just return the reference to it.  Otherwise, this initializes it
    * with eQuerySelectedText.  Please check if the result is valid before
    * actually using it.
    * Note that this is also called by ContentForTSFRef().
    */
   Selection& SelectionForTSFRef();
 
+  class MOZ_STACK_CLASS AutoSetTemporarySelection final
+  {
+  public:
+    AutoSetTemporarySelection(Selection& aSelection) : mSelection(aSelection)
+    {
+      mDirty = mSelection.IsDirty();
+      if (mDirty) {
+        mSelection.CollapseAt(0);
+      }
+    }
+
+    ~AutoSetTemporarySelection()
+    {
+      if (mDirty) {
+        mSelection.MarkDirty();
+      }
+    }
+
+ private:
+    Selection& mSelection;
+    bool mDirty;
+  };
+
   struct PendingAction final
   {
     enum ActionType : uint8_t
     {
       COMPOSITION_START,
       COMPOSITION_UPDATE,
       COMPOSITION_END,
       SET_SELECTION