Bug 1296578 IMEInputHandler should use insertion point relative query content events during composition r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 19 Aug 2016 21:51:54 +0900
changeset 403600 b6a4d3aad56562b873b1d7bd217028cc8d2b5bc3
parent 403257 b4a5ab92903593cb47d8f8d2155f724b4527d16d
child 528954 bb058011609db0d947cbb0e816531d46e56fc1e2
push id26962
push usermasayuki@d-toybox.com
push dateSat, 20 Aug 2016 13:57:43 +0000
reviewersm_kato
bugs1296578
milestone51.0a1
Bug 1296578 IMEInputHandler should use insertion point relative query content events during composition r?m_kato Start offset of composition string is fixed when composition string becomes non-empty in focused editor. In other words, until composition string is fixed, composition start offset may be changed from selection start offset at dispatching compositionstart event. Especially, in e10s mode, pending keyboard events usually change composition start offset. So, while there is composition, IMEHandler should use query events querying text rect or text content relative to actual start offset of composition string because native IME believes composition string at selection selection start when starting composition in the main process. MozReview-Commit-ID: 3hinwozl9Ow
widget/cocoa/TextInputHandler.mm
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -3262,17 +3262,28 @@ IMEInputHandler::GetAttributedSubstringF
          "computed with mIMECompositionString (result string=\"%s\")",
          this, NS_ConvertUTF16toUTF8(str).get()));
     }
     return result;
   }
 
   nsAutoString str;
   WidgetQueryContentEvent textContent(true, eQueryTextContent, mWidget);
-  textContent.InitForQueryTextContent(aRange.location, aRange.length);
+  WidgetQueryContentEvent::Options options;
+  int64_t startOffset = aRange.location;
+  if (IsIMEComposing()) {
+    // The composition may be at different offset from the selection start
+    // offset at dispatching compositionstart because start of composition
+    // is fixed when composition string becomes non-empty in the editor.
+    // Therefore, we need to use query event which is relative to insertion
+    // point.
+    options.mRelativeToInsertionPoint = true;
+    startOffset -= mIMECompositionStart;
+  }
+  textContent.InitForQueryTextContent(startOffset, aRange.length, options);
   textContent.RequestFontRanges();
   DispatchEvent(textContent);
 
   MOZ_LOG(gLog, LogLevel::Info,
     ("%p IMEInputHandler::GetAttributedSubstringFromRange, "
      "textContent={ mSucceeded=%s, mReply={ mString=\"%s\", mOffset=%llu } }",
      this, TrueOrFalse(textContent.mSucceeded),
      NS_ConvertUTF16toUTF8(textContent.mReply.mString).get(),
@@ -3430,32 +3441,54 @@ IMEInputHandler::FirstRectForCharacterRa
   }
 
   RefPtr<IMEInputHandler> kungFuDeathGrip(this);
 
   LayoutDeviceIntRect r;
   bool useCaretRect = (aRange.length == 0);
   if (!useCaretRect) {
     WidgetQueryContentEvent charRect(true, eQueryTextRect, mWidget);
-    charRect.InitForQueryTextRect(aRange.location, 1);
+    WidgetQueryContentEvent::Options options;
+    int64_t startOffset = aRange.location;
+    if (IsIMEComposing()) {
+      // The composition may be at different offset from the selection start
+      // offset at dispatching compositionstart because start of composition
+      // is fixed when composition string becomes non-empty in the editor.
+      // Therefore, we need to use query event which is relative to insertion
+      // point.
+      options.mRelativeToInsertionPoint = true;
+      startOffset -= mIMECompositionStart;
+    }
+    charRect.InitForQueryTextRect(startOffset, 1, options);
     DispatchEvent(charRect);
     if (charRect.mSucceeded) {
       r = charRect.mReply.mRect;
       actualRange.location = charRect.mReply.mOffset;
       actualRange.length = charRect.mReply.mString.Length();
       mWritingMode = charRect.GetWritingMode();
       mRangeForWritingMode = actualRange;
     } else {
       useCaretRect = true;
     }
   }
 
   if (useCaretRect) {
     WidgetQueryContentEvent caretRect(true, eQueryCaretRect, mWidget);
-    caretRect.InitForQueryCaretRect(aRange.location);
+    WidgetQueryContentEvent::Options options;
+    int64_t startOffset = aRange.location;
+    if (IsIMEComposing()) {
+      // The composition may be at different offset from the selection start
+      // offset at dispatching compositionstart because start of composition
+      // is fixed when composition string becomes non-empty in the editor.
+      // Therefore, we need to use query event which is relative to insertion
+      // point.
+      options.mRelativeToInsertionPoint = true;
+      startOffset -= mIMECompositionStart;
+    }
+    caretRect.InitForQueryCaretRect(startOffset, options);
     DispatchEvent(caretRect);
     if (!caretRect.mSucceeded) {
       return rect;
     }
     r = caretRect.mReply.mRect;
     r.width = 0;
     actualRange.location = caretRect.mReply.mOffset;
     actualRange.length = 0;