Skip to content

[webview_flutter_dev] Handle key events for tizen webview #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 23, 2020
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
6 changes: 5 additions & 1 deletion packages/webview_flutter/lib/webview_flutter_tizen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,11 @@ class PlatformViewsServiceTizen {
case 'viewFocused':
final int id = call.arguments as int;
if (_focusCallbacks.containsKey(id)) {
_focusCallbacks[id]();
if (_focusCallbacks[id] != null) {
_focusCallbacks[id]();
} else {
throw FlutterError('FocusCallbacks[$id] must not be null.');
}
}
break;
default:
Expand Down
Binary file modified packages/webview_flutter/tizen/lib/liblightweight-web-engine.so
Binary file not shown.
Binary file not shown.
310 changes: 310 additions & 0 deletions packages/webview_flutter/tizen/src/webview.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include "lwe/PlatformIntegrationData.h"
#include "webview_factory.h"

#include <Ecore_Input_Evas.h>
#include <Ecore_IMF_Evas.h>

std::string extractStringFromMap(const flutter::EncodableValue& arguments,
const char* key) {
if (std::holds_alternative<flutter::EncodableMap>(arguments)) {
Expand Down Expand Up @@ -114,6 +117,313 @@ void WebView::touch(int type, int button, double x, double y, double dx,
}
}

static LWE::KeyValue ecoreEventKeyToKeyValue(const char* ecoreKeyString,
bool isShiftPressed) {
if (strcmp("Left", ecoreKeyString) == 0) {
return LWE::KeyValue::ArrowLeftKey;
} else if (strcmp("Right", ecoreKeyString) == 0) {
return LWE::KeyValue::ArrowRightKey;
} else if (strcmp("Up", ecoreKeyString) == 0) {
return LWE::KeyValue::ArrowUpKey;
} else if (strcmp("Down", ecoreKeyString) == 0) {
return LWE::KeyValue::ArrowDownKey;
} else if (strcmp("space", ecoreKeyString) == 0) {
return LWE::KeyValue::SpaceKey;
} else if (strcmp("Return", ecoreKeyString) == 0) {
return LWE::KeyValue::EnterKey;
} else if (strcmp("Tab", ecoreKeyString) == 0) {
return LWE::KeyValue::TabKey;
} else if (strcmp("BackSpace", ecoreKeyString) == 0) {
return LWE::KeyValue::BackspaceKey;
} else if (strcmp("Escape", ecoreKeyString) == 0) {
return LWE::KeyValue::EscapeKey;
} else if (strcmp("Delete", ecoreKeyString) == 0) {
return LWE::KeyValue::DeleteKey;
} else if (strcmp("at", ecoreKeyString) == 0) {
return LWE::KeyValue::AtMarkKey;
} else if (strcmp("minus", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::UnderScoreMarkKey;
} else {
return LWE::KeyValue::MinusMarkKey;
}
} else if (strcmp("equal", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::PlusMarkKey;
} else {
return LWE::KeyValue::EqualitySignKey;
}
} else if (strcmp("bracketleft", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::LeftCurlyBracketMarkKey;
} else {
return LWE::KeyValue::LeftSquareBracketKey;
}
} else if (strcmp("bracketright", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::RightCurlyBracketMarkKey;
} else {
return LWE::KeyValue::RightSquareBracketKey;
}
} else if (strcmp("semicolon", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::ColonMarkKey;
} else {
return LWE::KeyValue::SemiColonMarkKey;
}
} else if (strcmp("apostrophe", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::DoubleQuoteMarkKey;
} else {
return LWE::KeyValue::SingleQuoteMarkKey;
}
} else if (strcmp("comma", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::LessThanMarkKey;
} else {
return LWE::KeyValue::CommaMarkKey;
}
} else if (strcmp("period", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::GreaterThanSignKey;
} else {
return LWE::KeyValue::PeriodKey;
}
} else if (strcmp("slash", ecoreKeyString) == 0) {
if (isShiftPressed) {
return LWE::KeyValue::QuestionMarkKey;
} else {
return LWE::KeyValue::SlashKey;
}
} else if (strlen(ecoreKeyString) == 1) {
char ch = ecoreKeyString[0];
if (ch >= '0' && ch <= '9') {
if (isShiftPressed) {
switch (ch) {
case '1':
return LWE::KeyValue::ExclamationMarkKey;
case '2':
return LWE::KeyValue::AtMarkKey;
case '3':
return LWE::KeyValue::SharpMarkKey;
case '4':
return LWE::KeyValue::DollarMarkKey;
case '5':
return LWE::KeyValue::PercentMarkKey;
case '6':
return LWE::KeyValue::CaretMarkKey;
case '7':
return LWE::KeyValue::AmpersandMarkKey;
case '8':
return LWE::KeyValue::AsteriskMarkKey;
case '9':
return LWE::KeyValue::LeftParenthesisMarkKey;
case '0':
return LWE::KeyValue::RightParenthesisMarkKey;
}
}
return (LWE::KeyValue)(LWE::KeyValue::Digit0Key + ch - '0');
} else if (ch >= 'a' && ch <= 'z') {
return (LWE::KeyValue)(LWE::KeyValue::LowerAKey + ch - 'a');
} else if (ch >= 'A' && ch <= 'Z') {
return (LWE::KeyValue)(LWE::KeyValue::AKey + ch - 'A');
}
} else if (strcmp("XF86AudioRaiseVolume", ecoreKeyString) == 0) {
return LWE::KeyValue::TVVolumeUpKey;
} else if (strcmp("XF86AudioLowerVolume", ecoreKeyString) == 0) {
return LWE::KeyValue::TVVolumeDownKey;
} else if (strcmp("XF86AudioMute", ecoreKeyString) == 0) {
return LWE::KeyValue::TVMuteKey;
} else if (strcmp("XF86RaiseChannel", ecoreKeyString) == 0) {
return LWE::KeyValue::TVChannelUpKey;
} else if (strcmp("XF86LowerChannel", ecoreKeyString) == 0) {
return LWE::KeyValue::TVChannelDownKey;
} else if (strcmp("XF86AudioRewind", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaTrackPreviousKey;
} else if (strcmp("XF86AudioNext", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaTrackNextKey;
} else if (strcmp("XF86AudioPause", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaPauseKey;
} else if (strcmp("XF86AudioRecord", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaRecordKey;
} else if (strcmp("XF86AudioPlay", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaPlayKey;
} else if (strcmp("XF86AudioStop", ecoreKeyString) == 0) {
return LWE::KeyValue::MediaStopKey;
} else if (strcmp("XF86Info", ecoreKeyString) == 0) {
return LWE::KeyValue::TVInfoKey;
} else if (strcmp("XF86Back", ecoreKeyString) == 0) {
return LWE::KeyValue::TVReturnKey;
} else if (strcmp("XF86Red", ecoreKeyString) == 0) {
return LWE::KeyValue::TVRedKey;
} else if (strcmp("XF86Green", ecoreKeyString) == 0) {
return LWE::KeyValue::TVGreenKey;
} else if (strcmp("XF86Yellow", ecoreKeyString) == 0) {
return LWE::KeyValue::TVYellowKey;
} else if (strcmp("XF86Blue", ecoreKeyString) == 0) {
return LWE::KeyValue::TVBlueKey;
} else if (strcmp("XF86SysMenu", ecoreKeyString) == 0) {
return LWE::KeyValue::TVMenuKey;
} else if (strcmp("XF86Home", ecoreKeyString) == 0) {
return LWE::KeyValue::TVHomeKey;
} else if (strcmp("XF86Exit", ecoreKeyString) == 0) {
return LWE::KeyValue::TVExitKey;
} else if (strcmp("XF86PreviousChannel", ecoreKeyString) == 0) {
return LWE::KeyValue::TVPreviousChannel;
} else if (strcmp("XF86ChannelList", ecoreKeyString) == 0) {
return LWE::KeyValue::TVChannelList;
} else if (strcmp("XF86ChannelGuide", ecoreKeyString) == 0) {
return LWE::KeyValue::TVChannelGuide;
} else if (strcmp("XF86SimpleMenu", ecoreKeyString) == 0) {
return LWE::KeyValue::TVSimpleMenu;
} else if (strcmp("XF86EManual", ecoreKeyString) == 0) {
return LWE::KeyValue::TVEManual;
} else if (strcmp("XF86ExtraApp", ecoreKeyString) == 0) {
return LWE::KeyValue::TVExtraApp;
} else if (strcmp("XF86Search", ecoreKeyString) == 0) {
return LWE::KeyValue::TVSearch;
} else if (strcmp("XF86PictureSize", ecoreKeyString) == 0) {
return LWE::KeyValue::TVPictureSize;
} else if (strcmp("XF86Sleep", ecoreKeyString) == 0) {
return LWE::KeyValue::TVSleep;
} else if (strcmp("XF86Caption", ecoreKeyString) == 0) {
return LWE::KeyValue::TVCaption;
} else if (strcmp("XF86More", ecoreKeyString) == 0) {
return LWE::KeyValue::TVMore;
} else if (strcmp("XF86BTVoice", ecoreKeyString) == 0) {
return LWE::KeyValue::TVBTVoice;
} else if (strcmp("XF86Color", ecoreKeyString) == 0) {
return LWE::KeyValue::TVColor;
} else if (strcmp("XF86PlayBack", ecoreKeyString) == 0) {
return LWE::KeyValue::TVPlayBack;
}

LOG_DEBUG("WebViewEFL - unimplemented key %s\n", ecoreKeyString);
return LWE::KeyValue::UnidentifiedKey;
}

void WebView::dispatchKeyDownEvent(Ecore_Event_Key* keyEvent) {
std::string keyName = keyEvent->keyname;
LOG_DEBUG("ECORE_EVENT_KEY_DOWN [%s, %d]\n", keyName.data(),
(keyEvent->modifiers & 1) || (keyEvent->modifiers & 2));

bool lastInputTimeWasZeroBefore = false;
// if (webViewInstance_->m_lastInputTime == 0) {
// lastInputTimeWasZeroBefore = true;
// webViewInstance_->m_lastInputTime = Starfish::longTickCount();
// }

if (!isFocused()) {
LOG_DEBUG("ignore keydown because we dont have focus");
return;
}

#ifdef TV_PROFILE
if ((strncmp(keyName.data(), "XF86Back", 8) == 0)) {
keyName = "Escape";
}
#endif

if ((strcmp(keyName.data(), "XF86Exit") == 0) ||
(strcmp(keyName.data(), "Select") == 0) ||
(strcmp(keyName.data(), "Cancel") == 0)) {
if (strcmp(keyName.data(), "Select") == 0) {
webViewInstance_->AddIdleCallback(
[](void* data) {
LWE::WebContainer* self = (LWE::WebContainer*)data;
LWE::KeyValue kv = LWE::KeyValue::EnterKey;
self->DispatchKeyDownEvent(kv);
self->DispatchKeyPressEvent(kv);
self->DispatchKeyUpEvent(kv);
// self->HideSoftwareKeyboardIfPossible();
},
webViewInstance_);
} else {
webViewInstance_->AddIdleCallback(
[](void* data) {
LWE::WebContainer* self = (LWE::WebContainer*)data;
// self->HideSoftwareKeyboardIfPossible();
},
webViewInstance_);
}
}

auto keyValue = ecoreEventKeyToKeyValue(keyName.data(), false);

// if (keyValue >= LWE::KeyValue::ArrowDownKey &&
// keyValue <= LWE::KeyValue::ArrowRightKey) {
// int currentTimestamp = keyEvent->timestamp;
// if (currentTimestamp -
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] <
// g_arrowKeyDownMinimumDelayInMS) {
// return;
// }
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] =
// currentTimestamp;
// }

if (lastInputTimeWasZeroBefore) {
webViewInstance_->DispatchKeyDownEvent(keyValue);
webViewInstance_->DispatchKeyPressEvent(keyValue);
} else {
struct Param {
LWE::WebContainer* webViewInstance;
LWE::KeyValue keyValue;
};
Param* p = new Param();
p->webViewInstance = webViewInstance_;
p->keyValue = keyValue;

webViewInstance_->AddIdleCallback(
[](void* data) {
Param* p = (Param*)data;
p->webViewInstance->DispatchKeyDownEvent(p->keyValue);
p->webViewInstance->DispatchKeyPressEvent(p->keyValue);
delete p;
},
p);
}
}

void WebView::dispatchKeyUpEvent(Ecore_Event_Key* keyEvent) {
std::string keyName = keyEvent->keyname;
LOG_DEBUG("ECORE_EVENT_KEY_UP [%s, %d]\n", keyName.data(),
(keyEvent->modifiers & 1) || (keyEvent->modifiers & 2));

if (!isFocused()) {
LOG_DEBUG("ignore keyup because we dont have focus");
return;
}

#ifdef TV_PROFILE
if ((strncmp(keyName.data(), "XF86Back", 8) == 0)) {
keyName = "Escape";
}
#endif
auto keyValue = ecoreEventKeyToKeyValue(keyName.data(), false);

// if (keyValue >= LWE::KeyValue::ArrowDownKey &&
// keyValue <= LWE::KeyValue::ArrowRightKey) {
// g_arrowKeyDownTimestamp[keyValue - LWE::KeyValue::ArrowDownKey] = 0;
// }

struct Param {
LWE::WebContainer* webView;
LWE::KeyValue keyValue;
};
Param* p = new Param();
p->webView = webViewInstance_;
p->keyValue = keyValue;

webViewInstance_->AddIdleCallback(
[](void* data) {
Param* p = (Param*)data;
p->webView->DispatchKeyUpEvent(p->keyValue);
delete p;
},
p);
}

void WebView::clearFocus() { LOG_DEBUG("WebView::clearFocus \n"); }

void WebView::setDirection(int direction) {
Expand Down
4 changes: 4 additions & 0 deletions packages/webview_flutter/tizen/src/webview.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class WebView : public PlatformView {
virtual void setDirection(int direction) override;
virtual void clearFocus() override;

// Key input event
virtual void dispatchKeyDownEvent(Ecore_Event_Key* key) override;
virtual void dispatchKeyUpEvent(Ecore_Event_Key* key) override;

private:
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
Expand Down