Bug 1282043 IMContextWrapper shouldn't append 0 length clause to TextRangeArray and if IME doesn't specify clause at beginning of the composition, it should insert dummy clause r?m_kato
Here is the patched build's log:
[Main Thread]: I/nsGtkIMModuleWidgets GTKIM: 7fab5a60a2c0 CreateTextRangeArray(aContext=7fab5a7bbbf0, aCompositionString="รท" (Length()=1))
[Main Thread]: W/nsGtkIMModuleWidgets GTKIM: 7fab5a60a2c0 SetTextRange(), FAILED, due to no attr, aTextRange= { mStartOffset=0, mEndOffset=1 }
[Main Thread]: W/nsGtkIMModuleWidgets GTKIM: 7fab5a60a2c0 SetTextRange(), FAILED, due to current clause length is 0
[Main Thread]: E/nsGtkIMModuleWidgets GTKIM: 7fab5a60a2c0 SetTextRange(), FAILED, due to g_utf8_to_utf16() failure (retrieving current clause)
[Main Thread]: W/nsGtkIMModuleWidgets GTKIM: 7fab5a60a2c0 CreateTextRangeArray(), inserting a dummy clause at the beginning of the composition string mStartOffset=0, mEndOffset=1, mRangeType=TextRangeType::eRawClause
iBus Chewing IME has two clauses when user presses Shift+p, one doesn't have pango_attr, the other is empty. These clauses are not useful in Gecko. Additionally, TextRangeArray assumes that there is a clause at beginning of the composition when there is one or more clauses. Therefore, this patch tries to insert dummy clause at the beggining of composition in such case.
MozReview-Commit-ID: 3hVGVmvFrhA
--- a/widget/gtk/IMContextWrapper.cpp
+++ b/widget/gtk/IMContextWrapper.cpp
@@ -1654,24 +1654,45 @@ IMContextWrapper::CreateTextRangeArray(G
("GTKIM: %p CreateTextRangeArray(), FAILED, iterator couldn't "
"be allocated",
this));
pango_attr_list_unref(feedback_list);
g_free(preedit_string);
return textRangeArray.forget();
}
+ uint32_t minOffsetOfClauses = aCompositionString.Length();
do {
TextRange range;
if (!SetTextRange(iter, preedit_string, caretOffsetInUTF16, range)) {
continue;
}
+ MOZ_ASSERT(range.Length());
+ minOffsetOfClauses = std::min(minOffsetOfClauses, range.mStartOffset);
textRangeArray->AppendElement(range);
} while (pango_attr_iterator_next(iter));
+ // If the IME doesn't define clause from the start of the composition,
+ // we should insert dummy clause information since TextRangeArray assumes
+ // that there must be a clause whose start is 0 when there is one or
+ // more clauses.
+ if (minOffsetOfClauses) {
+ TextRange dummyClause;
+ dummyClause.mStartOffset = 0;
+ dummyClause.mEndOffset = minOffsetOfClauses;
+ dummyClause.mRangeType = TextRangeType::eRawClause;
+ textRangeArray->InsertElementAt(0, dummyClause);
+ MOZ_LOG(gGtkIMLog, LogLevel::Warning,
+ ("GTKIM: %p CreateTextRangeArray(), inserting a dummy clause "
+ "at the beginning of the composition string mStartOffset=%u, "
+ "mEndOffset=%u, mRangeType=%s",
+ this, dummyClause.mStartOffset, dummyClause.mEndOffset,
+ ToChar(dummyClause.mRangeType)));
+ }
+
TextRange range;
range.mStartOffset = range.mEndOffset = caretOffsetInUTF16;
range.mRangeType = TextRangeType::eCaret;
textRangeArray->AppendElement(range);
MOZ_LOG(gGtkIMLog, LogLevel::Debug,
("GTKIM: %p CreateTextRangeArray(), mStartOffset=%u, "
"mEndOffset=%u, mRangeType=%s",
this, range.mStartOffset, range.mEndOffset,
@@ -1740,16 +1761,27 @@ IMContextWrapper::SetTextRange(PangoAttr
if (NS_WARN_IF(!utf16CurrentClauseString)) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p SetTextRange(), FAILED, due to g_utf8_to_utf16() "
"failure (retrieving current clause)",
this));
return false;
}
+ // iBus Chewing IME tells us that there is an empty clause at the end of
+ // the composition string but we should ignore it since our code doesn't
+ // assume that there is an empty clause.
+ if (!utf16CurrentClauseLength) {
+ MOZ_LOG(gGtkIMLog, LogLevel::Warning,
+ ("GTKIM: %p SetTextRange(), FAILED, due to current clause length "
+ "is 0",
+ this));
+ return false;
+ }
+
aTextRange.mEndOffset = aTextRange.mStartOffset + utf16CurrentClauseLength;
g_free(utf16CurrentClauseString);
utf16CurrentClauseString = nullptr;
// Set styles
TextRangeStyle& style = aTextRange.mRangeStyle;
// Underline