44
55#include " text_input_channel.h"
66
7+ #include < Ecore.h>
78#include < Ecore_IMF_Evas.h>
89
910#include " flutter/shell/platform/tizen/logger.h"
11+ #include " flutter/shell/platform/tizen/tizen_embedder_engine.h"
12+ #include " flutter/shell/platform/tizen/tizen_surface.h"
1013#include " stdlib.h"
1114#include " string.h"
12-
1315static constexpr char kSetEditingStateMethod [] = " TextInput.setEditingState" ;
1416static constexpr char kClearClientMethod [] = " TextInput.clearClient" ;
1517static constexpr char kSetClientMethod [] = " TextInput.setClient" ;
@@ -54,15 +56,15 @@ static bool IsASCIIPrintableKey(char c) {
5456 return false ;
5557}
5658
57- static void CommitCallback (void * data, Ecore_IMF_Context* ctx,
58- void * event_info) {
59+ void TextInputChannel:: CommitCallback (void * data, Ecore_IMF_Context* ctx,
60+ void * event_info) {
5961 TextInputChannel* self = (TextInputChannel*)data;
6062 char * str = (char *)event_info;
6163 self->OnCommit (str);
6264}
6365
64- static void PreeditCallback (void * data, Ecore_IMF_Context* ctx,
65- void * event_info) {
66+ void TextInputChannel:: PreeditCallback (void * data, Ecore_IMF_Context* ctx,
67+ void * event_info) {
6668 TextInputChannel* self = (TextInputChannel*)data;
6769 char * preedit_string = nullptr ;
6870 int cursor_pos;
@@ -73,34 +75,54 @@ static void PreeditCallback(void* data, Ecore_IMF_Context* ctx,
7375 }
7476}
7577
76- static void PrivateCommandCallback (void * data, Ecore_IMF_Context* ctx,
77- void * event_info) {
78+ void TextInputChannel::PrivateCommandCallback (void * data,
79+ Ecore_IMF_Context* ctx,
80+ void * event_info) {
7881 // TODO
7982 LoggerD (" Unimplemented" );
8083}
8184
82- static void DeleteSurroundingCallback (void * data, Ecore_IMF_Context* ctx,
83- void * event_info) {
85+ void TextInputChannel::DeleteSurroundingCallback (void * data,
86+ Ecore_IMF_Context* ctx,
87+ void * event_info) {
8488 // TODO
8589 LoggerD (" Unimplemented" );
8690}
8791
88- static void InputPanelStatChangedCallback (void * data,
89- Ecore_IMF_Context* context,
90- int value) {
92+ void TextInputChannel::InputPanelStateChangedCallback (
93+ void * data, Ecore_IMF_Context* context, int value) {
9194 if (!data) {
9295 LoggerD (" [No Data]\n " );
9396 return ;
9497 }
9598 TextInputChannel* self = (TextInputChannel*)data;
9699 switch (value) {
97- case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
100+ case ECORE_IMF_INPUT_PANEL_STATE_SHOW: {
98101 LoggerD (" [PANEL_STATE_SHOW]\n " );
99- self->ShowSoftwareKeyboard ();
100- break ;
102+ if (self->engine_ ->device_profile ==
103+ " mobile" ) { // FIXME : Needs improvement on other devices.
104+ ecore_timer_add (
105+ 0.25 ,
106+ [](void * data) -> Eina_Bool {
107+ TextInputChannel* self = (TextInputChannel*)data;
108+ int32_t surface_w = self->engine_ ->tizen_surface ->GetWidth ();
109+ int32_t surface_h = self->engine_ ->tizen_surface ->GetHeight () -
110+ self->current_keyboard_geometry_ .h ;
111+ self->engine_ ->tizen_surface ->SetSize (surface_w, surface_h);
112+ if (self->rotation == 90 || self->rotation == 270 ) {
113+ self->engine_ ->SendWindowMetrics (surface_h, surface_w, 0 );
114+ } else {
115+ self->engine_ ->SendWindowMetrics (surface_w, surface_h, 0 );
116+ }
117+
118+ return ECORE_CALLBACK_CANCEL;
119+ },
120+ self);
121+ }
122+ } break ;
101123 case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
124+ self->HideSoftwareKeyboard (); // FIXME: Fallback for HW back-key
102125 LoggerD (" [PANEL_STATE_HIDE]\n " );
103- self->HideSoftwareKeyboard ();
104126 break ;
105127 case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
106128 LoggerD (" [PANEL_STATE_WILL_SHOW]\n " );
@@ -111,8 +133,28 @@ static void InputPanelStatChangedCallback(void* data,
111133 }
112134}
113135
114- static Eina_Bool RetrieveSurroundingCallback (void * data, Ecore_IMF_Context* ctx,
115- char ** text, int * cursor_pos) {
136+ void TextInputChannel::InputPanelGeometryChangedCallback (
137+ void * data, Ecore_IMF_Context* context, int value) {
138+ if (!data) {
139+ LoggerD (" [No Data]\n " );
140+ return ;
141+ }
142+ TextInputChannel* self = (TextInputChannel*)data;
143+ ecore_imf_context_input_panel_geometry_get (
144+ self->imfContext_ , &self->current_keyboard_geometry_ .x ,
145+ &self->current_keyboard_geometry_ .y , &self->current_keyboard_geometry_ .w ,
146+ &self->current_keyboard_geometry_ .h );
147+
148+ LoggerD (
149+ " [Current keyboard geometry] x:%d y:%d w:%d h:%d\n " ,
150+ self->current_keyboard_geometry_ .x , self->current_keyboard_geometry_ .y ,
151+ self->current_keyboard_geometry_ .w , self->current_keyboard_geometry_ .h );
152+ }
153+
154+ Eina_Bool TextInputChannel::RetrieveSurroundingCallback (void * data,
155+ Ecore_IMF_Context* ctx,
156+ char ** text,
157+ int * cursor_pos) {
116158 // TODO
117159 if (text) {
118160 *text = strdup (" " );
@@ -226,21 +268,15 @@ Ecore_IMF_Device_Subclass EoreDeviceSubClassToEcoreIMFDeviceSubClass(
226268}
227269
228270TextInputChannel::TextInputChannel (flutter::BinaryMessenger* messenger,
229- Ecore_Wl2_Window* ecoreWindow )
271+ TizenEmbedderEngine* engine )
230272 : channel_(std::make_unique<flutter::MethodChannel<rapidjson::Document>>(
231273 messenger, kChannelName , &flutter::JsonMethodCodec::GetInstance ())),
232274 active_model_(nullptr ),
233275 isSoftwareKeyboardShowing_(false ),
234276 lastPreeditStringLength_(0 ),
235277 imfContext_(nullptr ),
236- isWearable_(false ),
237- inSelectMode_(false ) {
238- const char * elmProfile = getenv (" ELM_PROFILE" );
239- if (!elmProfile || strcmp (elmProfile, " wearable" ) == 0 ) {
240- LoggerD (" ELM_PROFILE is wearable" );
241- isWearable_ = true ;
242- }
243-
278+ inSelectMode_(false ),
279+ engine_(engine) {
244280 channel_->SetMethodCallHandler (
245281 [this ](
246282 const flutter::MethodCall<rapidjson::Document>& call,
@@ -256,6 +292,8 @@ TextInputChannel::TextInputChannel(flutter::BinaryMessenger* messenger,
256292 imfContext_ = ecore_imf_context_add (getImfMethod ());
257293 }
258294 if (imfContext_) {
295+ Ecore_Wl2_Window* ecoreWindow =
296+ ((TizenSurfaceGL*)engine_->tizen_surface .get ())->wl2_window ();
259297 ecore_imf_context_client_window_set (
260298 imfContext_, (void *)ecore_wl2_window_id_get (ecoreWindow));
261299 RegisterIMFCallback (ecoreWindow);
@@ -391,8 +429,8 @@ void TextInputChannel::SendStateUpdate(const flutter::TextInputModel& model) {
391429}
392430
393431bool TextInputChannel::FilterEvent (Ecore_Event_Key* keyDownEvent) {
432+ LoggerD (" NonIMFFallback key name [%s]" , keyDownEvent->keyname );
394433 bool handled = false ;
395-
396434 const char * device = ecore_device_name_get (keyDownEvent->dev );
397435
398436 Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
@@ -414,7 +452,7 @@ bool TextInputChannel::FilterEvent(Ecore_Event_Key* keyDownEvent) {
414452
415453 bool isIME = strcmp (device, " ime" ) == 0 ;
416454 if (isIME && strcmp (keyDownEvent->key , " Select" ) == 0 ) {
417- if (isWearable_ ) {
455+ if (engine_-> device_profile == " wearable " ) {
418456 inSelectMode_ = true ;
419457 } else {
420458 SelectPressed (active_model_.get ());
@@ -563,9 +601,33 @@ void TextInputChannel::HideSoftwareKeyboard() {
563601 isSoftwareKeyboardShowing_);
564602 if (imfContext_ && isSoftwareKeyboardShowing_) {
565603 isSoftwareKeyboardShowing_ = false ;
566- ecore_imf_context_reset (imfContext_);
567- ecore_imf_context_focus_out (imfContext_);
568- ecore_imf_context_input_panel_hide (imfContext_);
604+
605+ if (engine_->device_profile ==
606+ " mobile" ) { // FIXME : Needs improvement on other devices.
607+ auto w = engine_->tizen_surface ->GetWidth ();
608+ auto h = engine_->tizen_surface ->GetHeight ();
609+
610+ if (rotation == 90 || rotation == 270 ) {
611+ engine_->SendWindowMetrics (h, w, 0 );
612+ } else {
613+ engine_->SendWindowMetrics (w, h, 0 );
614+ }
615+ engine_->tizen_surface ->SetSize (w, h);
616+ ecore_timer_add (
617+ 0.05 ,
618+ [](void * data) -> Eina_Bool {
619+ Ecore_IMF_Context* imfContext = (Ecore_IMF_Context*)data;
620+ ecore_imf_context_reset (imfContext);
621+ ecore_imf_context_focus_out (imfContext);
622+ ecore_imf_context_input_panel_hide (imfContext);
623+ return ECORE_CALLBACK_CANCEL;
624+ },
625+ imfContext_);
626+ } else {
627+ ecore_imf_context_reset (imfContext_);
628+ ecore_imf_context_focus_out (imfContext_);
629+ ecore_imf_context_input_panel_hide (imfContext_);
630+ }
569631 }
570632}
571633
@@ -583,7 +645,10 @@ void TextInputChannel::RegisterIMFCallback(Ecore_Wl2_Window* ecoreWindow) {
583645 PrivateCommandCallback, this );
584646 ecore_imf_context_input_panel_event_callback_add (
585647 imfContext_, ECORE_IMF_INPUT_PANEL_STATE_EVENT,
586- InputPanelStatChangedCallback, this );
648+ InputPanelStateChangedCallback, this );
649+ ecore_imf_context_input_panel_event_callback_add (
650+ imfContext_, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT,
651+ InputPanelGeometryChangedCallback, this );
587652 ecore_imf_context_retrieve_surrounding_callback_set (
588653 imfContext_, RetrieveSurroundingCallback, this );
589654
@@ -613,5 +678,8 @@ void TextInputChannel::UnregisterIMFCallback() {
613678 PrivateCommandCallback);
614679 ecore_imf_context_input_panel_event_callback_del (
615680 imfContext_, ECORE_IMF_INPUT_PANEL_STATE_EVENT,
616- InputPanelStatChangedCallback);
681+ InputPanelStateChangedCallback);
682+ ecore_imf_context_input_panel_event_callback_del (
683+ imfContext_, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT,
684+ InputPanelGeometryChangedCallback);
617685}
0 commit comments