@@ -63,59 +63,63 @@ TextInputChannel::TextInputChannel(
6363 HandleMethodCall (call, std::move (result));
6464 });
6565
66- // Set input method callbacks
67- input_method_context_->SetOnCommitCallback ([this ](std::string str) -> void {
68- FT_LOG (Debug) << " OnCommit: " << str;
69- text_editing_context_.edit_status_ = EditStatus::kCommit ;
70- ConsumeLastPreedit ();
71- active_model_->AddText (str);
72- SendStateUpdate (*active_model_);
66+ // Set input method callbacks.
67+ input_method_context_->SetOnPreeditStart ([this ]() {
68+ FT_LOG (Debug) << " onPreeditStart" ;
69+ text_editing_context_.edit_status_ = EditStatus::kPreeditStart ;
70+ active_model_->BeginComposing ();
7371 });
7472
75- input_method_context_->SetOnPreeditCallback (
73+ input_method_context_->SetOnPreeditChanged (
7674 [this ](std::string str, int cursor_pos) -> void {
77- text_editing_context_.edit_status_ = EditStatus::kPreeditStart ;
78- if (str.compare (" " ) == 0 ) {
79- text_editing_context_.edit_status_ = EditStatus::kPreeditEnd ;
75+ FT_LOG (Debug) << " onPreedit: str[" << str << " ] cursor_pos["
76+ << cursor_pos << " ]" ;
77+ if (str == " " ) {
78+ // Enter pre-edit end stage.
79+ return ;
8080 }
81+ active_model_->UpdateComposingText (str);
82+ SendStateUpdate (*active_model_);
83+ });
8184
82- if (text_editing_context_.edit_status_ == EditStatus::kPreeditStart ||
83- (text_editing_context_.edit_status_ == EditStatus::kPreeditEnd &&
84- // For tv, fix me
85- text_editing_context_.last_handled_ecore_event_keyname_ .compare (
86- " Return" ) != 0 )) {
87- text_editing_context_.last_handled_ecore_event_keyname_ = " " ;
88- ConsumeLastPreedit ();
89- }
85+ input_method_context_->SetOnPreeditEnd ([this ]() {
86+ text_editing_context_.edit_status_ = EditStatus::kPreeditEnd ;
87+ FT_LOG (Debug) << " onPreeditEnd" ;
9088
91- text_editing_context_.has_preedit_ = false ;
92- if (text_editing_context_.edit_status_ == EditStatus::kPreeditStart ) {
93- text_editing_context_.preedit_start_pos_ =
94- active_model_->selection ().base ();
95- active_model_->AddText (str);
96- text_editing_context_.preedit_end_pos_ =
97- active_model_->selection ().base ();
98- text_editing_context_.has_preedit_ = true ;
99- SendStateUpdate (*active_model_);
100- FT_LOG (Debug) << " Preedit start position: "
101- << text_editing_context_.preedit_start_pos_
102- << " , end position: "
103- << text_editing_context_.preedit_end_pos_ ;
104- }
105- });
89+ // Delete preedit-string, it will be committed.
90+ int count = active_model_->composing_range ().extent () -
91+ active_model_->composing_range ().base ();
10692
107- input_method_context_->SetOnInputPannelStateChangedCallback (
108- [this ](int state) {
109- if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
110- // Fallback for HW back-key
111- input_method_context_->HideInputPannel ();
112- input_method_context_->ResetInputMethodContext ();
113- ResetTextEditingContext ();
114- is_software_keyboard_showing_ = false ;
115- } else {
116- is_software_keyboard_showing_ = true ;
117- }
118- });
93+ active_model_->CommitComposing ();
94+ active_model_->EndComposing ();
95+
96+ active_model_->DeleteSurrounding (-count, count);
97+
98+ SendStateUpdate (*active_model_);
99+ });
100+
101+ input_method_context_->SetOnCommit ([this ](std::string str) -> void {
102+ FT_LOG (Debug) << " OnCommit: str[" << str << " ]" ;
103+ text_editing_context_.edit_status_ = EditStatus::kCommit ;
104+ active_model_->AddText (str);
105+ if (active_model_->composing ()) {
106+ active_model_->CommitComposing ();
107+ active_model_->EndComposing ();
108+ }
109+ SendStateUpdate (*active_model_);
110+ });
111+
112+ input_method_context_->SetOnInputPannelStateChanged ([this ](int state) {
113+ if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
114+ // Fallback for HW back-key.
115+ input_method_context_->HideInputPannel ();
116+ input_method_context_->ResetInputMethodContext ();
117+ ResetTextEditingContext ();
118+ is_software_keyboard_showing_ = false ;
119+ } else {
120+ is_software_keyboard_showing_ = true ;
121+ }
122+ });
119123}
120124
121125TextInputChannel::~TextInputChannel () {}
@@ -125,7 +129,7 @@ bool TextInputChannel::SendKeyEvent(Ecore_Event_Key* key, bool is_down) {
125129 return false ;
126130 }
127131
128- if (!FilterEvent (key) && !text_editing_context_. has_preedit_ ) {
132+ if (!FilterEvent (key)) {
129133 HandleUnfilteredEvent (key);
130134 }
131135
@@ -136,7 +140,7 @@ void TextInputChannel::HandleMethodCall(
136140 const MethodCall<rapidjson::Document>& method_call,
137141 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
138142 const std::string& method = method_call.method_name ();
139- FT_LOG (Debug) << " Handle a method: " << method;
143+ FT_LOG (Debug) << " method: " << method;
140144
141145 if (method.compare (kShowMethod ) == 0 ) {
142146 input_method_context_->ShowInputPannel ();
@@ -194,6 +198,9 @@ void TextInputChannel::HandleMethodCall(
194198
195199 active_model_ = std::make_unique<TextInputModel>();
196200 } else if (method.compare (kSetEditingStateMethod ) == 0 ) {
201+ input_method_context_->ResetInputMethodContext ();
202+ ResetTextEditingContext ();
203+
197204 if (!method_call.arguments () || method_call.arguments ()->IsNull ()) {
198205 result->Error (kBadArgumentError , " Method invoked without args" );
199206 return ;
@@ -224,10 +231,34 @@ void TextInputChannel::HandleMethodCall(
224231 " Selection base/extent values invalid." );
225232 return ;
226233 }
234+ auto selection_base_value = selection_base->value .GetInt ();
235+ auto selection_extent_value = selection_extent->value .GetInt ();
227236
228237 active_model_->SetText (text->value .GetString ());
229- active_model_->SetSelection (TextRange (selection_base->value .GetInt (),
230- selection_extent->value .GetInt ()));
238+ active_model_->SetSelection (
239+ TextRange (selection_base_value, selection_extent_value));
240+
241+ auto composing_base = args.FindMember (kComposingBaseKey );
242+ auto composing_extent = args.FindMember (kComposingBaseKey );
243+ auto composing_base_value = composing_base != args.MemberEnd ()
244+ ? composing_base->value .GetInt ()
245+ : -1 ;
246+ auto composing_extent_value = composing_extent != args.MemberEnd ()
247+ ? composing_extent->value .GetInt ()
248+ : -1 ;
249+
250+ if (composing_base_value == -1 && composing_extent_value == -1 ) {
251+ active_model_->EndComposing ();
252+ } else {
253+ size_t composing_start =
254+ std::min (composing_base_value, composing_extent_value);
255+ size_t cursor_offset = selection_base_value - composing_start;
256+
257+ active_model_->SetComposingRange (
258+ flutter::TextRange (composing_base_value, composing_extent_value),
259+ cursor_offset);
260+ }
261+ SendStateUpdate (*active_model_);
231262 } else {
232263 result->NotImplemented ();
233264 return ;
@@ -244,8 +275,14 @@ void TextInputChannel::SendStateUpdate(const TextInputModel& model) {
244275
245276 TextRange selection = model.selection ();
246277 rapidjson::Value editing_state (rapidjson::kObjectType );
247- editing_state.AddMember (kComposingBaseKey , -1 , allocator);
248- editing_state.AddMember (kComposingExtentKey , -1 , allocator);
278+ int composing_base =
279+ active_model_->composing () ? active_model_->composing_range ().base () : -1 ;
280+ int composing_extent = active_model_->composing ()
281+ ? active_model_->composing_range ().extent ()
282+ : -1 ;
283+
284+ editing_state.AddMember (kComposingBaseKey , composing_base, allocator);
285+ editing_state.AddMember (kComposingExtentKey , composing_extent, allocator);
249286 editing_state.AddMember (kSelectionAffinityKey , kAffinityDownstream ,
250287 allocator);
251288 editing_state.AddMember (kSelectionBaseKey , selection.base (), allocator);
@@ -255,7 +292,7 @@ void TextInputChannel::SendStateUpdate(const TextInputModel& model) {
255292 kTextKey , rapidjson::Value (model.GetText (), allocator).Move (), allocator);
256293 args->PushBack (editing_state, allocator);
257294
258- FT_LOG (Info ) << " Send text: " << model.GetText ();
295+ FT_LOG (Debug ) << " Send text:[ " << model.GetText () << " ] " ;
259296 channel_->InvokeMethod (kUpdateEditingStateMethod , std::move (args));
260297}
261298
@@ -285,10 +322,6 @@ bool TextInputChannel::FilterEvent(Ecore_Event_Key* event) {
285322
286323 handled = input_method_context_->FilterEvent (event, is_ime ? " ime" : " " );
287324
288- if (handled) {
289- text_editing_context_.last_handled_ecore_event_keyname_ = event->keyname ;
290- }
291-
292325#ifdef WEARABLE_PROFILE
293326 if (!handled && !strcmp (event->key , " Return" ) &&
294327 text_editing_context_.is_in_select_mode_ ) {
@@ -306,7 +339,7 @@ void TextInputChannel::HandleUnfilteredEvent(Ecore_Event_Key* event) {
306339#ifdef MOBILE_PROFILE
307340 // FIXME: Only for mobile.
308341 if (text_editing_context_.edit_status_ == EditStatus::kPreeditEnd ) {
309- FT_LOG (Warn ) << " Ignore a key event: " << event->keyname ;
342+ FT_LOG (Debug ) << " Ignore a key event: " << event->keyname ;
310343 ResetTextEditingContext ();
311344 return ;
312345 }
@@ -378,22 +411,6 @@ void TextInputChannel::EnterPressed(TextInputModel* model, bool select) {
378411 channel_->InvokeMethod (kPerformActionMethod , std::move (args));
379412}
380413
381- void TextInputChannel::ConsumeLastPreedit () {
382- if (text_editing_context_.has_preedit_ ) {
383- std::string before = active_model_->GetText ();
384- int count = text_editing_context_.preedit_end_pos_ -
385- text_editing_context_.preedit_start_pos_ ;
386- active_model_->DeleteSurrounding (-count, count);
387- std::string after = active_model_->GetText ();
388- FT_LOG (Debug) << " Last preedit count: " << count << " , text: " << before
389- << " -> " << after;
390- SendStateUpdate (*active_model_);
391- }
392- text_editing_context_.has_preedit_ = false ;
393- text_editing_context_.preedit_end_pos_ = 0 ;
394- text_editing_context_.preedit_start_pos_ = 0 ;
395- }
396-
397414bool TextInputChannel::ShouldNotFilterEvent (std::string key, bool is_ime) {
398415 // Force redirect to HandleUnfilteredEvent(especially on TV)
399416 // If you don't do this, it will affects the input panel.
0 commit comments