Bug 1275528 part.5 TSFTextStore should use insertion point relative query for getting character rect and caret rect only while there is a composition r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 15 Jun 2016 17:10:38 +0900
changeset 380004 c4a42d69f9092bb3b29c9bb03709b01167f80f3a
parent 380003 28e01a70279ca2619a3d04efe978733d90e8235f
child 380005 df00a3e270cffe3546b5b90c13925bc46fa72eb0
push id21107
push usermasayuki@d-toybox.com
push dateMon, 20 Jun 2016 10:09:39 +0000
reviewersm_kato
bugs1275528
milestone50.0a1
Bug 1275528 part.5 TSFTextStore should use insertion point relative query for getting character rect and caret rect only while there is a composition r?m_kato TSFTextStore should use insertion point relative query for getting character rect and caret rect while there is a composition because in such case, TSF must want to query a part of or around the composition. Therefore, it makes sense to use insertion point relative query since it adjusts the offset with the latest content information. MozReview-Commit-ID: IVjZ4zqFUkr
widget/windows/TSFTextStore.cpp
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -3579,19 +3579,31 @@ TSFTextStore::GetTextExt(TsViewCookie vc
             this, acpEnd));
     mHasReturnedNoLayoutError = true;
     return TS_E_NOLAYOUT;
   }
 
   // use eQueryTextRect to get rect in system, screen coordinates
   WidgetQueryContentEvent event(true, eQueryTextRect, mWidget);
   mWidget->InitEvent(event);
-  event.InitForQueryTextRect(acpStart, acpEnd - acpStart);
+
+  WidgetQueryContentEvent::Options options;
+  int64_t startOffset = acpStart;
+  if (mComposition.IsComposing()) {
+    // If there is a composition, TSF must want character rects related to
+    // the composition.  Therefore, we should use insertion point relative
+    // query because the composition might be at different position from
+    // the position where TSFTextStore believes it at.
+    options.mRelativeToInsertionPoint = true;
+    startOffset -= mComposition.mStart;
+  }
+  event.InitForQueryTextRect(startOffset, acpEnd - acpStart, options);
+
   DispatchEvent(event);
-  if (!event.mSucceeded) {
+  if (NS_WARN_IF(!event.mSucceeded)) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
            ("TSF: 0x%p   TSFTextStore::GetTextExt() FAILED due to "
             "eQueryTextRect failure", this));
     return TS_E_INVALIDPOS; // but unexpected failure, maybe.
   }
   // IMEs don't like empty rects, fix here
   if (event.mReply.mRect.width <= 0)
     event.mReply.mRect.width = 1;
@@ -5087,25 +5099,34 @@ TSFTextStore::CreateNativeCaret()
   Selection& currentSel = CurrentSelection();
   if (currentSel.IsDirty()) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
            ("TSF: 0x%p   TSFTextStore::CreateNativeCaret() FAILED due to "
             "CurrentSelection() failure", this));
     return;
   }
 
+  WidgetQueryContentEvent queryCaretRect(true, eQueryCaretRect, mWidget);
+  mWidget->InitEvent(queryCaretRect);
+
+  WidgetQueryContentEvent::Options options;
   // XXX If this is called without composition and the selection isn't
   //     collapsed, is it OK?
-  uint32_t caretOffset = currentSel.MaxOffset();
-
-  WidgetQueryContentEvent queryCaretRect(true, eQueryCaretRect, mWidget);
-  queryCaretRect.InitForQueryCaretRect(caretOffset);
-  mWidget->InitEvent(queryCaretRect);
+  int64_t caretOffset = currentSel.MaxOffset();
+  if (mComposition.IsComposing()) {
+    // If there is a composition, use insertion point relative query for
+    // deciding caret position because composition might be at different
+    // position where TSFTextStore believes it at.
+    options.mRelativeToInsertionPoint = true;
+    caretOffset -= mComposition.mStart;
+  }
+  queryCaretRect.InitForQueryCaretRect(caretOffset, options);
+
   DispatchEvent(queryCaretRect);
-  if (!queryCaretRect.mSucceeded) {
+  if (NS_WARN_IF(!queryCaretRect.mSucceeded)) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
            ("TSF: 0x%p   TSFTextStore::CreateNativeCaret() FAILED due to "
             "eQueryCaretRect failure (offset=%d)", this, caretOffset));
     return;
   }
 
   LayoutDeviceIntRect& caretRect = queryCaretRect.mReply.mRect;
   mNativeCaretIsCreated = ::CreateCaret(mWidget->GetWindowHandle(), nullptr,