4
4
5
5
#include " text_input_channel.h"
6
6
7
+ #include < Ecore.h>
7
8
#include < Ecore_IMF_Evas.h>
8
9
9
10
#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"
10
13
#include " stdlib.h"
11
14
#include " string.h"
12
-
13
15
static constexpr char kSetEditingStateMethod [] = " TextInput.setEditingState" ;
14
16
static constexpr char kClearClientMethod [] = " TextInput.clearClient" ;
15
17
static constexpr char kSetClientMethod [] = " TextInput.setClient" ;
@@ -54,15 +56,15 @@ static bool IsASCIIPrintableKey(char c) {
54
56
return false ;
55
57
}
56
58
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) {
59
61
TextInputChannel* self = (TextInputChannel*)data;
60
62
char * str = (char *)event_info;
61
63
self->OnCommit (str);
62
64
}
63
65
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) {
66
68
TextInputChannel* self = (TextInputChannel*)data;
67
69
char * preedit_string = nullptr ;
68
70
int cursor_pos;
@@ -73,34 +75,54 @@ static void PreeditCallback(void* data, Ecore_IMF_Context* ctx,
73
75
}
74
76
}
75
77
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) {
78
81
// TODO
79
82
LoggerD (" Unimplemented" );
80
83
}
81
84
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) {
84
88
// TODO
85
89
LoggerD (" Unimplemented" );
86
90
}
87
91
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) {
91
94
if (!data) {
92
95
LoggerD (" [No Data]\n " );
93
96
return ;
94
97
}
95
98
TextInputChannel* self = (TextInputChannel*)data;
96
99
switch (value) {
97
- case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
100
+ case ECORE_IMF_INPUT_PANEL_STATE_SHOW: {
98
101
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 ;
101
123
case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
124
+ self->HideSoftwareKeyboard (); // FIXME: Fallback for HW back-key
102
125
LoggerD (" [PANEL_STATE_HIDE]\n " );
103
- self->HideSoftwareKeyboard ();
104
126
break ;
105
127
case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
106
128
LoggerD (" [PANEL_STATE_WILL_SHOW]\n " );
@@ -111,8 +133,28 @@ static void InputPanelStatChangedCallback(void* data,
111
133
}
112
134
}
113
135
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) {
116
158
// TODO
117
159
if (text) {
118
160
*text = strdup (" " );
@@ -226,21 +268,15 @@ Ecore_IMF_Device_Subclass EoreDeviceSubClassToEcoreIMFDeviceSubClass(
226
268
}
227
269
228
270
TextInputChannel::TextInputChannel (flutter::BinaryMessenger* messenger,
229
- Ecore_Wl2_Window* ecoreWindow )
271
+ TizenEmbedderEngine* engine )
230
272
: channel_(std::make_unique<flutter::MethodChannel<rapidjson::Document>>(
231
273
messenger, kChannelName , &flutter::JsonMethodCodec::GetInstance ())),
232
274
active_model_(nullptr ),
233
275
isSoftwareKeyboardShowing_(false ),
234
276
lastPreeditStringLength_(0 ),
235
277
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) {
244
280
channel_->SetMethodCallHandler (
245
281
[this ](
246
282
const flutter::MethodCall<rapidjson::Document>& call,
@@ -256,6 +292,8 @@ TextInputChannel::TextInputChannel(flutter::BinaryMessenger* messenger,
256
292
imfContext_ = ecore_imf_context_add (getImfMethod ());
257
293
}
258
294
if (imfContext_) {
295
+ Ecore_Wl2_Window* ecoreWindow =
296
+ ((TizenSurfaceGL*)engine_->tizen_surface .get ())->wl2_window ();
259
297
ecore_imf_context_client_window_set (
260
298
imfContext_, (void *)ecore_wl2_window_id_get (ecoreWindow));
261
299
RegisterIMFCallback (ecoreWindow);
@@ -391,8 +429,8 @@ void TextInputChannel::SendStateUpdate(const flutter::TextInputModel& model) {
391
429
}
392
430
393
431
bool TextInputChannel::FilterEvent (Ecore_Event_Key* keyDownEvent) {
432
+ LoggerD (" NonIMFFallback key name [%s]" , keyDownEvent->keyname );
394
433
bool handled = false ;
395
-
396
434
const char * device = ecore_device_name_get (keyDownEvent->dev );
397
435
398
436
Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
@@ -414,7 +452,7 @@ bool TextInputChannel::FilterEvent(Ecore_Event_Key* keyDownEvent) {
414
452
415
453
bool isIME = strcmp (device, " ime" ) == 0 ;
416
454
if (isIME && strcmp (keyDownEvent->key , " Select" ) == 0 ) {
417
- if (isWearable_ ) {
455
+ if (engine_-> device_profile == " wearable " ) {
418
456
inSelectMode_ = true ;
419
457
} else {
420
458
SelectPressed (active_model_.get ());
@@ -563,9 +601,33 @@ void TextInputChannel::HideSoftwareKeyboard() {
563
601
isSoftwareKeyboardShowing_);
564
602
if (imfContext_ && isSoftwareKeyboardShowing_) {
565
603
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
+ }
569
631
}
570
632
}
571
633
@@ -583,7 +645,10 @@ void TextInputChannel::RegisterIMFCallback(Ecore_Wl2_Window* ecoreWindow) {
583
645
PrivateCommandCallback, this );
584
646
ecore_imf_context_input_panel_event_callback_add (
585
647
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 );
587
652
ecore_imf_context_retrieve_surrounding_callback_set (
588
653
imfContext_, RetrieveSurroundingCallback, this );
589
654
@@ -613,5 +678,8 @@ void TextInputChannel::UnregisterIMFCallback() {
613
678
PrivateCommandCallback);
614
679
ecore_imf_context_input_panel_event_callback_del (
615
680
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);
617
685
}
0 commit comments