Skip to content

Commit cb8ee9b

Browse files
seungsoo47bwikbs
authored andcommitted
Handle key events for tizen webview (#11)
* Implement dispatchKeyDownEvent and dispatchKeyUpEvent * Translate ecore key values to KeyValues for webview
1 parent 44987de commit cb8ee9b

File tree

5 files changed

+319
-1
lines changed

5 files changed

+319
-1
lines changed

packages/webview_flutter/lib/webview_flutter_tizen.dart

+5-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,11 @@ class PlatformViewsServiceTizen {
275275
case 'viewFocused':
276276
final int id = call.arguments as int;
277277
if (_focusCallbacks.containsKey(id)) {
278-
_focusCallbacks[id]();
278+
if (_focusCallbacks[id] != null) {
279+
_focusCallbacks[id]();
280+
} else {
281+
throw FlutterError('FocusCallbacks[$id] must not be null.');
282+
}
279283
}
280284
break;
281285
default:
Binary file not shown.
Binary file not shown.

packages/webview_flutter/tizen/src/webview.cc

+310
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "lwe/PlatformIntegrationData.h"
1919
#include "webview_factory.h"
2020

21+
#include <Ecore_Input_Evas.h>
22+
#include <Ecore_IMF_Evas.h>
23+
2124
std::string extractStringFromMap(const flutter::EncodableValue& arguments,
2225
const char* key) {
2326
if (std::holds_alternative<flutter::EncodableMap>(arguments)) {
@@ -114,6 +117,313 @@ void WebView::touch(int type, int button, double x, double y, double dx,
114117
}
115118
}
116119

120+
static LWE::KeyValue ecoreEventKeyToKeyValue(const char* ecoreKeyString,
121+
bool isShiftPressed) {
122+
if (strcmp("Left", ecoreKeyString) == 0) {
123+
return LWE::KeyValue::ArrowLeftKey;
124+
} else if (strcmp("Right", ecoreKeyString) == 0) {
125+
return LWE::KeyValue::ArrowRightKey;
126+
} else if (strcmp("Up", ecoreKeyString) == 0) {
127+
return LWE::KeyValue::ArrowUpKey;
128+
} else if (strcmp("Down", ecoreKeyString) == 0) {
129+
return LWE::KeyValue::ArrowDownKey;
130+
} else if (strcmp("space", ecoreKeyString) == 0) {
131+
return LWE::KeyValue::SpaceKey;
132+
} else if (strcmp("Return", ecoreKeyString) == 0) {
133+
return LWE::KeyValue::EnterKey;
134+
} else if (strcmp("Tab", ecoreKeyString) == 0) {
135+
return LWE::KeyValue::TabKey;
136+
} else if (strcmp("BackSpace", ecoreKeyString) == 0) {
137+
return LWE::KeyValue::BackspaceKey;
138+
} else if (strcmp("Escape", ecoreKeyString) == 0) {
139+
return LWE::KeyValue::EscapeKey;
140+
} else if (strcmp("Delete", ecoreKeyString) == 0) {
141+
return LWE::KeyValue::DeleteKey;
142+
} else if (strcmp("at", ecoreKeyString) == 0) {
143+
return LWE::KeyValue::AtMarkKey;
144+
} else if (strcmp("minus", ecoreKeyString) == 0) {
145+
if (isShiftPressed) {
146+
return LWE::KeyValue::UnderScoreMarkKey;
147+
} else {
148+
return LWE::KeyValue::MinusMarkKey;
149+
}
150+
} else if (strcmp("equal", ecoreKeyString) == 0) {
151+
if (isShiftPressed) {
152+
return LWE::KeyValue::PlusMarkKey;
153+
} else {
154+
return LWE::KeyValue::EqualitySignKey;
155+
}
156+
} else if (strcmp("bracketleft", ecoreKeyString) == 0) {
157+
if (isShiftPressed) {
158+
return LWE::KeyValue::LeftCurlyBracketMarkKey;
159+
} else {
160+
return LWE::KeyValue::LeftSquareBracketKey;
161+
}
162+
} else if (strcmp("bracketright", ecoreKeyString) == 0) {
163+
if (isShiftPressed) {
164+
return LWE::KeyValue::RightCurlyBracketMarkKey;
165+
} else {
166+
return LWE::KeyValue::RightSquareBracketKey;
167+
}
168+
} else if (strcmp("semicolon", ecoreKeyString) == 0) {
169+
if (isShiftPressed) {
170+
return LWE::KeyValue::ColonMarkKey;
171+
} else {
172+
return LWE::KeyValue::SemiColonMarkKey;
173+
}
174+
} else if (strcmp("apostrophe", ecoreKeyString) == 0) {
175+
if (isShiftPressed) {
176+
return LWE::KeyValue::DoubleQuoteMarkKey;
177+
} else {
178+
return LWE::KeyValue::SingleQuoteMarkKey;
179+
}
180+
} else if (strcmp("comma", ecoreKeyString) == 0) {
181+
if (isShiftPressed) {
182+
return LWE::KeyValue::LessThanMarkKey;
183+
} else {
184+
return LWE::KeyValue::CommaMarkKey;
185+
}
186+
} else if (strcmp("period", ecoreKeyString) == 0) {
187+
if (isShiftPressed) {
188+
return LWE::KeyValue::GreaterThanSignKey;
189+
} else {
190+
return LWE::KeyValue::PeriodKey;
191+
}
192+
} else if (strcmp("slash", ecoreKeyString) == 0) {
193+
if (isShiftPressed) {
194+
return LWE::KeyValue::QuestionMarkKey;
195+
} else {
196+
return LWE::KeyValue::SlashKey;
197+
}
198+
} else if (strlen(ecoreKeyString) == 1) {
199+
char ch = ecoreKeyString[0];
200+
if (ch >= '0' && ch <= '9') {
201+
if (isShiftPressed) {
202+
switch (ch) {
203+
case '1':
204+
return LWE::KeyValue::ExclamationMarkKey;
205+
case '2':
206+
return LWE::KeyValue::AtMarkKey;
207+
case '3':
208+
return LWE::KeyValue::SharpMarkKey;
209+
case '4':
210+
return LWE::KeyValue::DollarMarkKey;
211+
case '5':
212+
return LWE::KeyValue::PercentMarkKey;
213+
case '6':
214+
return LWE::KeyValue::CaretMarkKey;
215+
case '7':
216+
return LWE::KeyValue::AmpersandMarkKey;
217+
case '8':
218+
return LWE::KeyValue::AsteriskMarkKey;
219+
case '9':
220+
return LWE::KeyValue::LeftParenthesisMarkKey;
221+
case '0':
222+
return LWE::KeyValue::RightParenthesisMarkKey;
223+
}
224+
}
225+
return (LWE::KeyValue)(LWE::KeyValue::Digit0Key + ch - '0');
226+
} else if (ch >= 'a' && ch <= 'z') {
227+
return (LWE::KeyValue)(LWE::KeyValue::LowerAKey + ch - 'a');
228+
} else if (ch >= 'A' && ch <= 'Z') {
229+
return (LWE::KeyValue)(LWE::KeyValue::AKey + ch - 'A');
230+
}
231+
} else if (strcmp("XF86AudioRaiseVolume", ecoreKeyString) == 0) {
232+
return LWE::KeyValue::TVVolumeUpKey;
233+
} else if (strcmp("XF86AudioLowerVolume", ecoreKeyString) == 0) {
234+
return LWE::KeyValue::TVVolumeDownKey;
235+
} else if (strcmp("XF86AudioMute", ecoreKeyString) == 0) {
236+
return LWE::KeyValue::TVMuteKey;
237+
} else if (strcmp("XF86RaiseChannel", ecoreKeyString) == 0) {
238+
return LWE::KeyValue::TVChannelUpKey;
239+
} else if (strcmp("XF86LowerChannel", ecoreKeyString) == 0) {
240+
return LWE::KeyValue::TVChannelDownKey;
241+
} else if (strcmp("XF86AudioRewind", ecoreKeyString) == 0) {
242+
return LWE::KeyValue::MediaTrackPreviousKey;
243+
} else if (strcmp("XF86AudioNext", ecoreKeyString) == 0) {
244+
return LWE::KeyValue::MediaTrackNextKey;
245+
} else if (strcmp("XF86AudioPause", ecoreKeyString) == 0) {
246+
return LWE::KeyValue::MediaPauseKey;
247+
} else if (strcmp("XF86AudioRecord", ecoreKeyString) == 0) {
248+
return LWE::KeyValue::MediaRecordKey;
249+
} else if (strcmp("XF86AudioPlay", ecoreKeyString) == 0) {
250+
return LWE::KeyValue::MediaPlayKey;
251+
} else if (strcmp("XF86AudioStop", ecoreKeyString) == 0) {
252+
return LWE::KeyValue::MediaStopKey;
253+
} else if (strcmp("XF86Info", ecoreKeyString) == 0) {
254+
return LWE::KeyValue::TVInfoKey;
255+
} else if (strcmp("XF86Back", ecoreKeyString) == 0) {
256+
return LWE::KeyValue::TVReturnKey;
257+
} else if (strcmp("XF86Red", ecoreKeyString) == 0) {
258+
return LWE::KeyValue::TVRedKey;
259+
} else if (strcmp("XF86Green", ecoreKeyString) == 0) {
260+
return LWE::KeyValue::TVGreenKey;
261+
} else if (strcmp("XF86Yellow", ecoreKeyString) == 0) {
262+
return LWE::KeyValue::TVYellowKey;
263+
} else if (strcmp("XF86Blue", ecoreKeyString) == 0) {
264+
return LWE::KeyValue::TVBlueKey;
265+
} else if (strcmp("XF86SysMenu", ecoreKeyString) == 0) {
266+
return LWE::KeyValue::TVMenuKey;
267+
} else if (strcmp("XF86Home", ecoreKeyString) == 0) {
268+
return LWE::KeyValue::TVHomeKey;
269+
} else if (strcmp("XF86Exit", ecoreKeyString) == 0) {
270+
return LWE::KeyValue::TVExitKey;
271+
} else if (strcmp("XF86PreviousChannel", ecoreKeyString) == 0) {
272+
return LWE::KeyValue::TVPreviousChannel;
273+
} else if (strcmp("XF86ChannelList", ecoreKeyString) == 0) {
274+
return LWE::KeyValue::TVChannelList;
275+
} else if (strcmp("XF86ChannelGuide", ecoreKeyString) == 0) {
276+
return LWE::KeyValue::TVChannelGuide;
277+
} else if (strcmp("XF86SimpleMenu", ecoreKeyString) == 0) {
278+
return LWE::KeyValue::TVSimpleMenu;
279+
} else if (strcmp("XF86EManual", ecoreKeyString) == 0) {
280+
return LWE::KeyValue::TVEManual;
281+
} else if (strcmp("XF86ExtraApp", ecoreKeyString) == 0) {
282+
return LWE::KeyValue::TVExtraApp;
283+
} else if (strcmp("XF86Search", ecoreKeyString) == 0) {
284+
return LWE::KeyValue::TVSearch;
285+
} else if (strcmp("XF86PictureSize", ecoreKeyString) == 0) {
286+
return LWE::KeyValue::TVPictureSize;
287+
} else if (strcmp("XF86Sleep", ecoreKeyString) == 0) {
288+
return LWE::KeyValue::TVSleep;
289+
} else if (strcmp("XF86Caption", ecoreKeyString) == 0) {
290+
return LWE::KeyValue::TVCaption;
291+
} else if (strcmp("XF86More", ecoreKeyString) == 0) {
292+
return LWE::KeyValue::TVMore;
293+
} else if (strcmp("XF86BTVoice", ecoreKeyString) == 0) {
294+
return LWE::KeyValue::TVBTVoice;
295+
} else if (strcmp("XF86Color", ecoreKeyString) == 0) {
296+
return LWE::KeyValue::TVColor;
297+
} else if (strcmp("XF86PlayBack", ecoreKeyString) == 0) {
298+
return LWE::KeyValue::TVPlayBack;
299+
}
300+
301+
LOG_DEBUG("WebViewEFL - unimplemented key %s\n", ecoreKeyString);
302+
return LWE::KeyValue::UnidentifiedKey;
303+
}
304+
305+
void WebView::dispatchKeyDownEvent(Ecore_Event_Key* keyEvent) {
306+
std::string keyName = keyEvent->keyname;
307+
LOG_DEBUG("ECORE_EVENT_KEY_DOWN [%s, %d]\n", keyName.data(),
308+
(keyEvent->modifiers & 1) || (keyEvent->modifiers & 2));
309+
310+
bool lastInputTimeWasZeroBefore = false;
311+
// if (webViewInstance_->m_lastInputTime == 0) {
312+
// lastInputTimeWasZeroBefore = true;
313+
// webViewInstance_->m_lastInputTime = Starfish::longTickCount();
314+
// }
315+
316+
if (!isFocused()) {
317+
LOG_DEBUG("ignore keydown because we dont have focus");
318+
return;
319+
}
320+
321+
#ifdef TV_PROFILE
322+
if ((strncmp(keyName.data(), "XF86Back", 8) == 0)) {
323+
keyName = "Escape";
324+
}
325+
#endif
326+
327+
if ((strcmp(keyName.data(), "XF86Exit") == 0) ||
328+
(strcmp(keyName.data(), "Select") == 0) ||
329+
(strcmp(keyName.data(), "Cancel") == 0)) {
330+
if (strcmp(keyName.data(), "Select") == 0) {
331+
webViewInstance_->AddIdleCallback(
332+
[](void* data) {
333+
LWE::WebContainer* self = (LWE::WebContainer*)data;
334+
LWE::KeyValue kv = LWE::KeyValue::EnterKey;
335+
self->DispatchKeyDownEvent(kv);
336+
self->DispatchKeyPressEvent(kv);
337+
self->DispatchKeyUpEvent(kv);
338+
// self->HideSoftwareKeyboardIfPossible();
339+
},
340+
webViewInstance_);
341+
} else {
342+
webViewInstance_->AddIdleCallback(
343+
[](void* data) {
344+
LWE::WebContainer* self = (LWE::WebContainer*)data;
345+
// self->HideSoftwareKeyboardIfPossible();
346+
},
347+
webViewInstance_);
348+
}
349+
}
350+
351+
auto keyValue = ecoreEventKeyToKeyValue(keyName.data(), false);
352+
353+
// if (keyValue >= LWE::KeyValue::ArrowDownKey &&
354+
// keyValue <= LWE::KeyValue::ArrowRightKey) {
355+
// int currentTimestamp = keyEvent->timestamp;
356+
// if (currentTimestamp -
357+
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] <
358+
// g_arrowKeyDownMinimumDelayInMS) {
359+
// return;
360+
// }
361+
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] =
362+
// currentTimestamp;
363+
// }
364+
365+
if (lastInputTimeWasZeroBefore) {
366+
webViewInstance_->DispatchKeyDownEvent(keyValue);
367+
webViewInstance_->DispatchKeyPressEvent(keyValue);
368+
} else {
369+
struct Param {
370+
LWE::WebContainer* webViewInstance;
371+
LWE::KeyValue keyValue;
372+
};
373+
Param* p = new Param();
374+
p->webViewInstance = webViewInstance_;
375+
p->keyValue = keyValue;
376+
377+
webViewInstance_->AddIdleCallback(
378+
[](void* data) {
379+
Param* p = (Param*)data;
380+
p->webViewInstance->DispatchKeyDownEvent(p->keyValue);
381+
p->webViewInstance->DispatchKeyPressEvent(p->keyValue);
382+
delete p;
383+
},
384+
p);
385+
}
386+
}
387+
388+
void WebView::dispatchKeyUpEvent(Ecore_Event_Key* keyEvent) {
389+
std::string keyName = keyEvent->keyname;
390+
LOG_DEBUG("ECORE_EVENT_KEY_UP [%s, %d]\n", keyName.data(),
391+
(keyEvent->modifiers & 1) || (keyEvent->modifiers & 2));
392+
393+
if (!isFocused()) {
394+
LOG_DEBUG("ignore keyup because we dont have focus");
395+
return;
396+
}
397+
398+
#ifdef TV_PROFILE
399+
if ((strncmp(keyName.data(), "XF86Back", 8) == 0)) {
400+
keyName = "Escape";
401+
}
402+
#endif
403+
auto keyValue = ecoreEventKeyToKeyValue(keyName.data(), false);
404+
405+
// if (keyValue >= LWE::KeyValue::ArrowDownKey &&
406+
// keyValue <= LWE::KeyValue::ArrowRightKey) {
407+
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] = 0;
408+
// }
409+
410+
struct Param {
411+
LWE::WebContainer* webView;
412+
LWE::KeyValue keyValue;
413+
};
414+
Param* p = new Param();
415+
p->webView = webViewInstance_;
416+
p->keyValue = keyValue;
417+
418+
webViewInstance_->AddIdleCallback(
419+
[](void* data) {
420+
Param* p = (Param*)data;
421+
p->webView->DispatchKeyUpEvent(p->keyValue);
422+
delete p;
423+
},
424+
p);
425+
}
426+
117427
void WebView::clearFocus() { LOG_DEBUG("WebView::clearFocus \n"); }
118428

119429
void WebView::setDirection(int direction) {

packages/webview_flutter/tizen/src/webview.h

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class WebView : public PlatformView {
2424
virtual void setDirection(int direction) override;
2525
virtual void clearFocus() override;
2626

27+
// Key input event
28+
virtual void dispatchKeyDownEvent(Ecore_Event_Key* key) override;
29+
virtual void dispatchKeyUpEvent(Ecore_Event_Key* key) override;
30+
2731
private:
2832
void HandleMethodCall(
2933
const flutter::MethodCall<flutter::EncodableValue>& method_call,

0 commit comments

Comments
 (0)