Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions shell/platform/common/text_input_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,22 @@ void TextInputModel::BeginComposing() {
composing_range_ = TextRange(selection_.start());
}

void TextInputModel::UpdateComposingText(const std::u16string& text) {
void TextInputModel::UpdateComposingText(const std::u16string& text,
const TextRange& selection) {
// Preserve selection if we get a no-op update to the composing region.
if (text.length() == 0 && composing_range_.collapsed()) {
return;
}
DeleteSelected();
text_.replace(composing_range_.start(), composing_range_.length(), text);
const TextRange& rangeToDelete =
composing_range_.collapsed() ? selection_ : composing_range_;
text_.replace(rangeToDelete.start(), rangeToDelete.length(), text);
composing_range_.set_end(composing_range_.start() + text.length());
selection_ = TextRange(composing_range_.end());
selection_ = TextRange(selection.start() + composing_range_.start(),
selection.extent() + composing_range_.start());
}

void TextInputModel::UpdateComposingText(const std::u16string& text) {
UpdateComposingText(text, TextRange(text.length()));
}

void TextInputModel::UpdateComposingText(const std::string& text) {
Expand Down
15 changes: 10 additions & 5 deletions shell/platform/common/text_input_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,17 @@ class TextInputModel {
// are restricted to the composing range.
void BeginComposing();

// Replaces the composing range with new UTF-16 text.
// Replaces the composing range with new UTF-16 text, and sets the selection.
//
// If a selection of non-zero length exists, it is deleted if the composing
// text is non-empty. The composing range is adjusted to the length of
// |text| and the selection base and offset are set to the end of the
// composing range.
// The given |text| replaces text within the current composing range, or the
// current selection if the text wasn't composing. The composing range is
// adjusted to the length of |text|, and the |selection| describes the new
// selection range, relative to the start of the new composing range.
void UpdateComposingText(const std::u16string& text,
const TextRange& selection);

// Replaces the composing range with new UTF-16 text and sets the selection to
// the end of the composing text.
void UpdateComposingText(const std::u16string& text);

// Replaces the composing range with new UTF-8 text.
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/common/text_input_model_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,17 @@ TEST(TextInputModel, UpdateComposingRemovesLastComposingCharacter) {
model->SetText("ACDE");
}

TEST(TextInputModel, UpdateSelectionWhileComposing) {
auto model = std::make_unique<TextInputModel>();
model->SetText("ABCDE");
model->BeginComposing();
model->SetComposingRange(TextRange(4, 5), 1);
model->UpdateComposingText(u"ぴょんぴょん", TextRange(3, 6));
EXPECT_STREQ(model->GetText().c_str(), "ABCDぴょんぴょん");
EXPECT_EQ(model->selection(), TextRange(7, 10));
EXPECT_EQ(model->composing_range(), TextRange(4, 10));
}

TEST(TextInputModel, AddCodePoint) {
auto model = std::make_unique<TextInputModel>();
model->AddCodePoint('A');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@

#pragma mark - Enums
/**
* The affinity of the current cursor position. If the cursor is at a position representing
* a line break, the cursor may be drawn either at the end of the current line (upstream)
* or at the beginning of the next (downstream).
* The affinity of the current cursor position. If the cursor is at a position
* representing a soft line break, the cursor may be drawn either at the end of
* the current line (upstream) or at the beginning of the next (downstream).
*/
typedef NS_ENUM(NSUInteger, FlutterTextAffinity) {
kFlutterTextAffinityUpstream,
Expand Down Expand Up @@ -852,19 +852,13 @@ - (void)setMarkedText:(id)string

// Input string may be NSString or NSAttributedString.
BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]];
std::string marked_text = isAttributedString ? [[string string] UTF8String] : [string UTF8String];
_activeModel->UpdateComposingText(marked_text);

// Update the selection within the marked text.
long signedLength = static_cast<long>(selectedRange.length);
long location = selectedRange.location + _activeModel->composing_range().base();
long textLength = _activeModel->text_range().end();

size_t base = std::clamp(location, 0L, textLength);
size_t extent = std::clamp(location + signedLength, 0L, textLength);
_activeModel->SetSelection(flutter::TextRange(base, extent));
const NSString* rawString = isAttributedString ? [string string] : string;
_activeModel->UpdateComposingText(
(const char16_t*)[rawString cStringUsingEncoding:NSUTF16StringEncoding],
flutter::TextRange(selectedRange.location, selectedRange.location + selectedRange.length));

if (_enableDeltaModel) {
std::string marked_text = [rawString UTF8String];
[self updateEditStateWithDelta:flutter::TextEditingDelta(textBeforeChange,
selectionBeforeChange.collapsed()
? composingBeforeChange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -945,8 +945,8 @@ - (bool)testOperationsThatTriggerDelta {
@"deltaText" : @"marked text",
@"deltaStart" : @(14),
@"deltaEnd" : @(14),
@"selectionBase" : @(25),
@"selectionExtent" : @(25),
@"selectionBase" : @(14),
@"selectionExtent" : @(15),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(14),
Expand Down Expand Up @@ -1030,7 +1030,7 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"m",
@"deltaStart" : @(0),
@"deltaEnd" : @(0),
@"selectionBase" : @(1),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
Expand Down Expand Up @@ -1060,8 +1060,8 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"ma",
@"deltaStart" : @(0),
@"deltaEnd" : @(1),
@"selectionBase" : @(2),
@"selectionExtent" : @(2),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
Expand Down Expand Up @@ -1090,8 +1090,8 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"mar",
@"deltaStart" : @(0),
@"deltaEnd" : @(2),
@"selectionBase" : @(3),
@"selectionExtent" : @(3),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
Expand Down Expand Up @@ -1120,8 +1120,8 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"mark",
@"deltaStart" : @(0),
@"deltaEnd" : @(3),
@"selectionBase" : @(4),
@"selectionExtent" : @(4),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
Expand Down Expand Up @@ -1150,8 +1150,8 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"marke",
@"deltaStart" : @(0),
@"deltaEnd" : @(4),
@"selectionBase" : @(5),
@"selectionExtent" : @(5),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
Expand Down Expand Up @@ -1180,8 +1180,8 @@ - (bool)testComposingWithDelta {
@"deltaText" : @"marked",
@"deltaStart" : @(0),
@"deltaEnd" : @(5),
@"selectionBase" : @(6),
@"selectionExtent" : @(6),
@"selectionBase" : @(0),
@"selectionExtent" : @(1),
@"selectionAffinity" : @"TextAffinity.upstream",
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
Expand Down
4 changes: 1 addition & 3 deletions shell/platform/windows/text_input_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,7 @@ void TextInputPlugin::ComposeChangeHook(const std::u16string& text,
std::string text_before_change = active_model_->GetText();
TextRange composing_before_change = active_model_->composing_range();
active_model_->AddText(text);
cursor_pos += active_model_->composing_range().start();
active_model_->UpdateComposingText(text);
active_model_->SetSelection(TextRange(cursor_pos, cursor_pos));
active_model_->UpdateComposingText(text, TextRange(cursor_pos, cursor_pos));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really related to this change, but isn't the composing text being added twice here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean between AddText as well as UpdateComposingText? It sort of looks like it, though perhaps we're relying on a side effect of one or the other?

std::string text_after_change = active_model_->GetText();
if (enable_delta_model) {
TextEditingDelta delta = TextEditingDelta(
Expand Down