mirror of
https://github.com/chenasraf/webview_cef.git
synced 2026-05-18 01:49:03 +00:00
Merge branch 'main' into main
This commit is contained in:
@@ -373,49 +373,32 @@ void WebviewHandler::deleteCookie(const std::string& domain, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
bool WebviewHandler::getCookieVisitor(){
|
||||
if(!m_CookieVisitor.get())
|
||||
{
|
||||
m_CookieVisitor = new WebviewCookieVisitor();
|
||||
m_CookieVisitor->setOnVisitComplete([=](std::map<std::string, std::map<std::string, std::string>> cookies){
|
||||
if(cookies.size() == 1){
|
||||
if(onUrlCookieVisitedCb){
|
||||
onUrlCookieVisitedCb(cookies);
|
||||
}
|
||||
}else if(cookies.size() > 1){
|
||||
if(onAllCookieVisitedCb){
|
||||
onAllCookieVisitedCb(cookies);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!m_CookieVisitor.get())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebviewHandler::visitAllCookies(){
|
||||
bool WebviewHandler::visitAllCookies(std::function<void(std::map<std::string, std::map<std::string, std::string>>)> callback){
|
||||
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager(nullptr);
|
||||
if (!manager || !getCookieVisitor())
|
||||
if (!manager)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return manager->VisitAllCookies(m_CookieVisitor);
|
||||
CefRefPtr<WebviewCookieVisitor> cookieVisitor = new WebviewCookieVisitor();
|
||||
cookieVisitor->setOnVisitComplete(callback);
|
||||
|
||||
return manager->VisitAllCookies(cookieVisitor);
|
||||
}
|
||||
|
||||
bool WebviewHandler::visitUrlCookies(const std::string& domain, const bool& isHttpOnly){
|
||||
bool WebviewHandler::visitUrlCookies(const std::string& domain, const bool& isHttpOnly, std::function<void(std::map<std::string, std::map<std::string, std::string>>)> callback){
|
||||
CefRefPtr<CefCookieManager> manager = CefCookieManager::GetGlobalManager(nullptr);
|
||||
if (!manager || !getCookieVisitor())
|
||||
if (!manager)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<WebviewCookieVisitor> cookieVisitor = new WebviewCookieVisitor();
|
||||
cookieVisitor->setOnVisitComplete(callback);
|
||||
|
||||
std::string httpDomain = "https://" + domain + "/cookiestorage";
|
||||
|
||||
return manager->VisitUrlCookies(httpDomain, isHttpOnly, m_CookieVisitor);
|
||||
return manager->VisitUrlCookies(httpDomain, isHttpOnly, cookieVisitor);
|
||||
}
|
||||
|
||||
bool WebviewHandler::setJavaScriptChannels(const std::vector<std::string> channels)
|
||||
|
||||
@@ -26,9 +26,7 @@ public:
|
||||
std::function<void(int type)>onCursorChangedEvent;
|
||||
std::function<void(std::string text)> onTooltipEvent;
|
||||
std::function<void(int level, std::string message, std::string source, int line)>onConsoleMessageEvent;
|
||||
//custom action callback or webpage event
|
||||
std::function<void(std::map<std::string, std::map<std::string, std::string>>)> onAllCookieVisitedCb;
|
||||
std::function<void(std::map<std::string, std::map<std::string, std::string>>)> onUrlCookieVisitedCb;
|
||||
//webpage message
|
||||
std::function<void(std::string, std::string, std::string, std::string)> onJavaScriptChannelMessage;
|
||||
|
||||
explicit WebviewHandler();
|
||||
@@ -124,16 +122,14 @@ public:
|
||||
|
||||
void setCookie(const std::string& domain, const std::string& key, const std::string& value);
|
||||
void deleteCookie(const std::string& domain, const std::string& key);
|
||||
bool visitAllCookies();
|
||||
bool visitUrlCookies(const std::string& domain, const bool& isHttpOnly);
|
||||
bool visitAllCookies(std::function<void(std::map<std::string, std::map<std::string, std::string>>)> callback);
|
||||
bool visitUrlCookies(const std::string& domain, const bool& isHttpOnly, std::function<void(std::map<std::string, std::map<std::string, std::string>>)> callback);
|
||||
|
||||
bool setJavaScriptChannels(const std::vector<std::string> channels);
|
||||
bool sendJavaScriptChannelCallBack(const bool error, const std::string result, const std::string callbackId, const std::string frameId);
|
||||
bool executeJavaScript(const std::string code);
|
||||
|
||||
private:
|
||||
bool getCookieVisitor();
|
||||
|
||||
uint32_t width = 1;
|
||||
uint32_t height = 1;
|
||||
float dpi = 1.0;
|
||||
@@ -146,7 +142,6 @@ private:
|
||||
// Include the default reference counting implementation.
|
||||
IMPLEMENT_REFCOUNTING(WebviewHandler);
|
||||
|
||||
CefRefPtr<WebviewCookieVisitor> m_CookieVisitor;
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
|
||||
|
||||
@@ -90,18 +90,16 @@ namespace webview_cef {
|
||||
CefDoMessageLoopWork();
|
||||
}
|
||||
|
||||
int HandleMethodCall(std::string name, WValue* values, WValue* response) {
|
||||
int result = -1;
|
||||
void HandleMethodCall(std::string name, WValue* values, std::function<void(int ,WValue*)> result) {
|
||||
if(name.compare("dispose") == 0){
|
||||
// we don't need to dispose the texture, texture will be disposed by flutter engine
|
||||
// int64_t textureId = webview_value_get_int(values);
|
||||
CefShutdown();
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("loadUrl") == 0) {
|
||||
if (const auto url = webview_value_get_string(values)) {
|
||||
handler.get()->loadUrl(url);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
}
|
||||
else if (name.compare("setSize") == 0) {
|
||||
@@ -109,13 +107,13 @@ namespace webview_cef {
|
||||
const auto width = webview_value_get_double(webview_value_get_list_value(values, 1));
|
||||
const auto height = webview_value_get_double(webview_value_get_list_value(values, 2));
|
||||
handler.get()->changeSize((float)dpi, (int)std::round(width), (int)std::round(height));
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("cursorClickDown") == 0
|
||||
|| name.compare("cursorClickUp") == 0
|
||||
|| name.compare("cursorMove") == 0
|
||||
|| name.compare("cursorDragging") == 0) {
|
||||
result = cursorAction(values, name);
|
||||
result(cursorAction(values, name), nullptr);
|
||||
}
|
||||
else if (name.compare("setScrollDelta") == 0) {
|
||||
auto x = webview_value_get_int(webview_value_get_list_value(values, 0));
|
||||
@@ -123,50 +121,80 @@ namespace webview_cef {
|
||||
auto deltaX = webview_value_get_int(webview_value_get_list_value(values, 2));
|
||||
auto deltaY = webview_value_get_int(webview_value_get_list_value(values, 3));
|
||||
handler.get()->sendScrollEvent((int)x, (int)y, (int)deltaX, (int)deltaY);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("goForward") == 0) {
|
||||
handler.get()->goForward();
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("goBack") == 0) {
|
||||
handler.get()->goBack();
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("reload") == 0) {
|
||||
handler.get()->reload();
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("openDevTools") == 0) {
|
||||
handler.get()->openDevTools();
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("setClientFocus") == 0) {
|
||||
isFocused = webview_value_get_bool(webview_value_get_list_value(values, 0));
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if(name.compare("setCookie") == 0){
|
||||
const auto domain = webview_value_get_string(webview_value_get_list_value(values, 0));
|
||||
const auto key = webview_value_get_string(webview_value_get_list_value(values, 1));
|
||||
const auto value = webview_value_get_string(webview_value_get_list_value(values, 2));
|
||||
handler.get()->setCookie(domain, key, value);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("deleteCookie") == 0) {
|
||||
const auto domain = webview_value_get_string(webview_value_get_list_value(values, 0));
|
||||
const auto key = webview_value_get_string(webview_value_get_list_value(values, 1));
|
||||
handler.get()->deleteCookie(domain, key);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("visitAllCookies") == 0) {
|
||||
handler.get()->visitAllCookies();
|
||||
result = 1;
|
||||
handler.get()->visitAllCookies([=](std::map<std::string, std::map<std::string, std::string>> cookies){
|
||||
WValue* retMap = webview_value_new_map();
|
||||
for (auto &cookie : cookies)
|
||||
{
|
||||
WValue* tempMap = webview_value_new_map();
|
||||
for (auto &c : cookie.second)
|
||||
{
|
||||
WValue * val = webview_value_new_string(const_cast<char *>(c.second.c_str()));
|
||||
webview_value_set_string(tempMap, c.first.c_str(), val);
|
||||
webview_value_unref(val);
|
||||
}
|
||||
webview_value_set_string(retMap, cookie.first.c_str(), tempMap);
|
||||
webview_value_unref(tempMap);
|
||||
}
|
||||
result(1, retMap);
|
||||
webview_value_unref(retMap);
|
||||
});
|
||||
}
|
||||
else if (name.compare("visitUrlCookies") == 0) {
|
||||
const auto domain = webview_value_get_string(webview_value_get_list_value(values, 0));
|
||||
const auto isHttpOnly = webview_value_get_bool(webview_value_get_list_value(values, 1));
|
||||
handler.get()->visitUrlCookies(domain, isHttpOnly);
|
||||
result = 1;
|
||||
handler.get()->visitUrlCookies(domain, isHttpOnly,[=](std::map<std::string, std::map<std::string, std::string>> cookies){
|
||||
WValue* retMap = webview_value_new_map();
|
||||
for (auto &cookie : cookies)
|
||||
{
|
||||
WValue* tempMap = webview_value_new_map();
|
||||
for (auto &c : cookie.second)
|
||||
{
|
||||
WValue * val = webview_value_new_string(const_cast<char *>(c.second.c_str()));
|
||||
webview_value_set_string(tempMap, c.first.c_str(), val);
|
||||
webview_value_unref(val);
|
||||
}
|
||||
webview_value_set_string(retMap, cookie.first.c_str(), tempMap);
|
||||
webview_value_unref(tempMap);
|
||||
}
|
||||
result(1, retMap);
|
||||
webview_value_unref(retMap);
|
||||
});
|
||||
}
|
||||
else if(name.compare("setJavaScriptChannels") == 0){
|
||||
auto len = webview_value_get_len(values);
|
||||
@@ -176,7 +204,7 @@ namespace webview_cef {
|
||||
channels.push_back(channel);
|
||||
}
|
||||
handler.get()->setJavaScriptChannels(channels);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if (name.compare("sendJavaScriptChannelCallBack") == 0) {
|
||||
const auto error = webview_value_get_bool(webview_value_get_list_value(values, 0));
|
||||
@@ -184,20 +212,16 @@ namespace webview_cef {
|
||||
const auto callbackId = webview_value_get_string(webview_value_get_list_value(values, 2));
|
||||
const auto frameId = webview_value_get_string(webview_value_get_list_value(values, 3));
|
||||
handler.get()->sendJavaScriptChannelCallBack(error, ret,callbackId,frameId);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else if(name.compare("executeJavaScript") == 0){
|
||||
const auto code = webview_value_get_string(webview_value_get_list_value(values, 0));
|
||||
handler.get()->executeJavaScript(code);
|
||||
result = 1;
|
||||
result(1, nullptr);
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
}
|
||||
if(response == nullptr){
|
||||
response = webview_value_new_null();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SwapBufferFromBgraToRgba(void* _dest, const void* _src, int width, int height) {
|
||||
@@ -282,50 +306,6 @@ namespace webview_cef {
|
||||
}
|
||||
};
|
||||
|
||||
handler.get()->onAllCookieVisitedCb = [](std::map<std::string, std::map<std::string, std::string>> cookies)
|
||||
{
|
||||
if (invokeFunc)
|
||||
{
|
||||
WValue* retMap = webview_value_new_map();
|
||||
for (auto &cookie : cookies)
|
||||
{
|
||||
WValue* tempMap = webview_value_new_map();
|
||||
for (auto &c : cookie.second)
|
||||
{
|
||||
WValue * val = webview_value_new_string(const_cast<char *>(c.second.c_str()));
|
||||
webview_value_set_string(tempMap, c.first.c_str(), val);
|
||||
webview_value_unref(val);
|
||||
}
|
||||
webview_value_set_string(retMap, cookie.first.c_str(), tempMap);
|
||||
webview_value_unref(tempMap);
|
||||
}
|
||||
invokeFunc("allCookiesVisited", retMap);
|
||||
webview_value_unref(retMap);
|
||||
}
|
||||
};
|
||||
|
||||
handler.get()->onUrlCookieVisitedCb = [](std::map<std::string, std::map<std::string, std::string>> cookies)
|
||||
{
|
||||
if (invokeFunc)
|
||||
{
|
||||
WValue* retMap = webview_value_new_map();
|
||||
for (auto &cookie : cookies)
|
||||
{
|
||||
WValue* tempMap = webview_value_new_map();
|
||||
for (auto &c : cookie.second)
|
||||
{
|
||||
WValue * val = webview_value_new_string(const_cast<char *>(c.second.c_str()));
|
||||
webview_value_set_string(tempMap, c.first.c_str(), val);
|
||||
webview_value_unref(val);
|
||||
}
|
||||
webview_value_set_string(retMap, cookie.first.c_str(), tempMap);
|
||||
webview_value_unref(tempMap);
|
||||
}
|
||||
invokeFunc("urlCookiesVisited", retMap);
|
||||
webview_value_unref(retMap);
|
||||
}
|
||||
};
|
||||
|
||||
handler.get()->onJavaScriptChannelMessage = [](std::string channelName, std::string message, std::string callbackId, std::string frameId)
|
||||
{
|
||||
if (invokeFunc)
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace webview_cef {
|
||||
void startCEF();
|
||||
void doMessageLoopWork();
|
||||
void sendKeyEvent(CefKeyEvent& ev);
|
||||
int HandleMethodCall(std::string name, WValue* values, WValue* response);
|
||||
void HandleMethodCall(std::string name, WValue* values, std::function<void(int ,WValue*)> result);
|
||||
void SwapBufferFromBgraToRgba(void* _dest, const void* _src, int width, int height);
|
||||
void setPaintCallBack(std::function<void(const void*, int32_t , int32_t )> callback);
|
||||
void setInvokeMethodFunc(std::function<void(std::string, WValue*)> func);
|
||||
|
||||
@@ -18,7 +18,7 @@ class _MyAppState extends State<MyApp> {
|
||||
final _controller = WebViewController();
|
||||
final _textController = TextEditingController();
|
||||
String title = "";
|
||||
Map<String, dynamic> allCookies = {};
|
||||
Map allCookies = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -41,14 +41,6 @@ class _MyAppState extends State<MyApp> {
|
||||
onUrlChanged: (url) {
|
||||
_textController.text = url;
|
||||
},
|
||||
onAllCookiesVisited: (cookies) {
|
||||
allCookies = cookies;
|
||||
},
|
||||
onUrlCookiesVisited: (cookies) {
|
||||
for (final key in cookies.keys) {
|
||||
allCookies[key] = cookies[key];
|
||||
}
|
||||
},
|
||||
));
|
||||
|
||||
// ignore: prefer_collection_literals
|
||||
@@ -130,8 +122,8 @@ class _MyAppState extends State<MyApp> {
|
||||
controller: _textController,
|
||||
onSubmitted: (url) {
|
||||
_controller.loadUrl(url);
|
||||
_controller.visitAllCookies();
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
_controller.visitAllCookies().then((value) {
|
||||
allCookies = Map.of(value);
|
||||
if (url == "baidu.com") {
|
||||
if (!allCookies.containsKey('.$url') ||
|
||||
!Map.of(allCookies['.$url']).containsKey('test')) {
|
||||
|
||||
@@ -41,7 +41,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
::DispatchMessage(&msg);
|
||||
|
||||
//add this line to enable cef keybord input
|
||||
processKeyEventForCEF(msg.message, msg.wParam, msg.lParam);
|
||||
handleWndProcForCEF(msg.message, msg.wParam, msg.lParam);
|
||||
}
|
||||
|
||||
::CoUninitialize();
|
||||
|
||||
@@ -52,12 +52,6 @@ class WebViewController extends ValueNotifier<bool> {
|
||||
case "onTitleChangedEvent":
|
||||
_listener?.onTitleChanged?.call(call.arguments);
|
||||
return;
|
||||
case "allCookiesVisited":
|
||||
_listener?.onAllCookiesVisited?.call(Map.from(call.arguments));
|
||||
return;
|
||||
case "urlCookiesVisited":
|
||||
_listener?.onUrlCookiesVisited?.call(Map.from(call.arguments));
|
||||
return;
|
||||
case 'javascriptChannelMessage':
|
||||
_handleJavascriptChannelMessage(
|
||||
call.arguments['channel'],
|
||||
@@ -159,7 +153,7 @@ class WebViewController extends ValueNotifier<bool> {
|
||||
return _pluginChannel.invokeMethod('deleteCookie', [domain, key]);
|
||||
}
|
||||
|
||||
Future<void> visitAllCookies() async {
|
||||
Future<dynamic> visitAllCookies() async {
|
||||
if (_isDisposed) {
|
||||
return;
|
||||
}
|
||||
@@ -167,7 +161,7 @@ class WebViewController extends ValueNotifier<bool> {
|
||||
return _pluginChannel.invokeMethod('visitAllCookies');
|
||||
}
|
||||
|
||||
Future<void> visitUrlCookies(String domain, bool isHttpOnly) async {
|
||||
Future<dynamic> visitUrlCookies(String domain, bool isHttpOnly) async {
|
||||
if (_isDisposed) {
|
||||
return;
|
||||
}
|
||||
@@ -200,7 +194,7 @@ class WebViewController extends ValueNotifier<bool> {
|
||||
'sendJavaScriptChannelCallBack', [error, result, callbackId, frameId]);
|
||||
}
|
||||
|
||||
Future<void> executeJavaScript(String code) async {
|
||||
Future<dynamic> executeJavaScript(String code) async {
|
||||
if (_isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
typedef TitleChangeCb = void Function(String title);
|
||||
typedef UrlChangeCb = void Function(String url);
|
||||
typedef AllCookieVisitedCb = void Function(Map<String, dynamic> cookies);
|
||||
typedef UrlCookieVisitedCb = void Function(Map<String, dynamic> cookies);
|
||||
/* Log severity levels. from CEF include/internal/cef_types.h
|
||||
0:default logging (currently info logging)
|
||||
1:verbose logging or debug logging
|
||||
@@ -17,15 +15,11 @@ typedef OnConsoleMessage = void Function(
|
||||
class WebviewEventsListener {
|
||||
TitleChangeCb? onTitleChanged;
|
||||
UrlChangeCb? onUrlChanged;
|
||||
AllCookieVisitedCb? onAllCookiesVisited;
|
||||
UrlCookieVisitedCb? onUrlCookiesVisited;
|
||||
OnConsoleMessage? onConsoleMessage;
|
||||
|
||||
WebviewEventsListener({
|
||||
this.onTitleChanged,
|
||||
this.onUrlChanged,
|
||||
this.onAllCookiesVisited,
|
||||
this.onUrlCookiesVisited,
|
||||
this.onConsoleMessage,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ class WebviewTooltip {
|
||||
locale: Localizations.localeOf(context),
|
||||
textDirection: TextDirection.ltr,
|
||||
text: TextSpan(text: text, style: _textStyle),
|
||||
)..layout(maxWidth: 500, minWidth: 1);
|
||||
maxLines: 5,
|
||||
ellipsis: '...',
|
||||
)..layout(maxWidth: width - 16);
|
||||
if (cursorOffset.dy + textPainter.height + 25 > height) {
|
||||
cursorOffset =
|
||||
Offset(cursorOffset.dx, height - textPainter.height - 10);
|
||||
@@ -61,9 +63,10 @@ class WebviewTooltip {
|
||||
BoxShadow(blurRadius: 2, color: Colors.black.withOpacity(.2))
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: _textStyle,
|
||||
child: RichText(
|
||||
text: TextSpan(text: text, style: _textStyle),
|
||||
maxLines: 5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -155,11 +155,8 @@ static void webview_cef_plugin_handle_method_call(
|
||||
WebviewCefPlugin *self,
|
||||
FlMethodCall *method_call)
|
||||
{
|
||||
g_autoptr(FlMethodResponse) response = nullptr;
|
||||
|
||||
const gchar *method = fl_method_call_get_name(method_call);
|
||||
FlValue *args = fl_method_call_get_args(method_call);
|
||||
FlValue *result = nullptr;
|
||||
if(strcmp(method, "init") == 0){
|
||||
auto texture = webview_cef_texture_new();
|
||||
fl_texture_registrar_register_texture(texture_register, FL_TEXTURE(texture));
|
||||
@@ -177,29 +174,24 @@ static void webview_cef_plugin_handle_method_call(
|
||||
webview_cef::doMessageLoopWork();
|
||||
return TRUE;
|
||||
}, NULL);
|
||||
result = fl_value_new_int((int64_t)texture);
|
||||
response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
fl_method_call_respond_success(method_call, fl_value_new_int((int64_t)texture), nullptr);
|
||||
}else{
|
||||
WValue *encodeArgs = encode_flvalue_to_wvalue(args);
|
||||
WValue *responseArgs = nullptr;
|
||||
int ret = webview_cef::HandleMethodCall(method, encodeArgs, responseArgs);
|
||||
g_object_ref(method_call);
|
||||
webview_cef::HandleMethodCall(method, encodeArgs, [=](int ret, WValue* responseArgs){
|
||||
if (ret > 0){
|
||||
fl_method_call_respond_success(method_call, encode_wavlue_to_flvalue(responseArgs), nullptr);
|
||||
}
|
||||
else if (ret < 0){
|
||||
fl_method_call_respond_error(method_call, "error", "error", encode_wavlue_to_flvalue(responseArgs), nullptr);
|
||||
}
|
||||
else{
|
||||
fl_method_call_respond_not_implemented(method_call, nullptr);
|
||||
}
|
||||
g_object_unref(method_call);
|
||||
});
|
||||
webview_value_unref(encodeArgs);
|
||||
if (ret > 0){
|
||||
result = encode_wavlue_to_flvalue(responseArgs);
|
||||
response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
}
|
||||
else if (ret < 0){
|
||||
result = encode_wavlue_to_flvalue(responseArgs);
|
||||
response = FL_METHOD_RESPONSE(fl_method_error_response_new("error", "error", result));
|
||||
}
|
||||
else{
|
||||
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
|
||||
}
|
||||
webview_value_unref(responseArgs);
|
||||
}
|
||||
|
||||
fl_method_call_respond(method_call, response, nullptr);
|
||||
fl_value_unref(result);
|
||||
}
|
||||
|
||||
static void webview_cef_plugin_dispose(GObject *object)
|
||||
@@ -276,7 +268,7 @@ FLUTTER_PLUGIN_EXPORT gboolean processKeyEventForCEF(GtkWidget *widget, GdkEvent
|
||||
// is apparently just how webkit handles it and what it expects.
|
||||
key_event.unmodified_character = '\r';
|
||||
}
|
||||
else if(windows_key_code == VKEY_V && EVENTFLAG_CONTROL_DOWN && event->type == GDK_KEY_PRESS){
|
||||
else if((windows_key_code == KeyboardCode::VKEY_V) && (key_event.modifiers & EVENTFLAG_CONTROL_DOWN) && (event->type == GDK_KEY_PRESS)){
|
||||
//try to fix copy request freeze process problem,(flutter engine will send a copy request when ctrl+v pressed)
|
||||
int res = 0;
|
||||
if(system("xclip -o -sel clipboard | xclip -i -sel clipboard &>/dev/null") == 0){
|
||||
|
||||
@@ -15,7 +15,7 @@ extern CGFloat scaleFactor;
|
||||
@interface CefWrapper : NSObject<FlutterTexture>
|
||||
|
||||
+ (void)setMethodChannel: (FlutterMethodChannel*)channel;
|
||||
+ (FlutterResult) handleMethodCallWrapper: (FlutterMethodCall*)call;
|
||||
+ (void) handleMethodCallWrapper: (FlutterMethodCall*)call result:(FlutterResult)result;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ FlutterMethodChannel* f_channel;
|
||||
webview_cef::doMessageLoopWork();
|
||||
}
|
||||
|
||||
+ (NSObject*) handleMethodCallWrapper: (FlutterMethodCall*)call{
|
||||
+ (void) handleMethodCallWrapper: (FlutterMethodCall*)call result:(FlutterResult)result{
|
||||
std::string name = std::string([call.method cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
if(name.compare("init") == 0){
|
||||
textureId = [tr registerTexture:[CefWrapper alloc]];
|
||||
@@ -285,21 +285,18 @@ FlutterMethodChannel* f_channel;
|
||||
[self processKeyboardEvent:event];
|
||||
return event;
|
||||
}];
|
||||
return [NSNumber numberWithLong:textureId];
|
||||
result([NSNumber numberWithLong:textureId]);
|
||||
}else{
|
||||
WValue *encodeArgs = [self encode_flvalue_to_wvalue:call.arguments];
|
||||
WValue *responseArgs = nullptr;
|
||||
int ret = webview_cef::HandleMethodCall(name, encodeArgs, responseArgs);
|
||||
int ret = webview_cef::HandleMethodCall(name, encodeArgs, [=](int ret, WValue* args){
|
||||
if(ret != 0){
|
||||
result([self encode_wvalue_to_flvalue:args])
|
||||
}
|
||||
else{
|
||||
result(nil);
|
||||
}
|
||||
});
|
||||
webview_value_unref(encodeArgs);
|
||||
if(ret != 0){
|
||||
NSObject *result = [self encode_wvalue_to_flvalue:responseArgs];
|
||||
webview_value_unref(responseArgs);
|
||||
return result;
|
||||
}
|
||||
else{
|
||||
webview_value_unref(responseArgs);
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
result([CefWrapper handleMethodCallWrapper:call]);
|
||||
[CefWrapper handleMethodCallWrapper:call result:result];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -18,7 +18,7 @@ FLUTTER_PLUGIN_EXPORT void WebviewCefPluginCApiRegisterWithRegistrar(
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void initCEFProcesses();
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void processKeyEventForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam);
|
||||
FLUTTER_PLUGIN_EXPORT void handleWndProcForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
namespace webview_cef {
|
||||
int64_t texture_id;
|
||||
|
||||
flutter::TextureRegistrar* texture_registrar;
|
||||
FlutterDesktopTextureRegistrarRef texture_registrar;
|
||||
std::shared_ptr<FlutterDesktopPixelBuffer> pixel_buffer;
|
||||
std::unique_ptr<uint8_t> backing_pixel_buffer;
|
||||
std::mutex buffer_mutex_;
|
||||
@@ -148,12 +148,13 @@ namespace webview_cef {
|
||||
}
|
||||
|
||||
// static
|
||||
void WebviewCefPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarWindows* registrar) {
|
||||
texture_registrar = registrar->texture_registrar();
|
||||
void WebviewCefPlugin::RegisterWithRegistrar(FlutterDesktopPluginRegistrarRef registrar) {
|
||||
texture_registrar = FlutterDesktopRegistrarGetTextureRegistrar(registrar);
|
||||
flutter::PluginRegistrarWindows* window_registrar = flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar);
|
||||
channel =
|
||||
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
|
||||
registrar->messenger(), "webview_cef",
|
||||
window_registrar->messenger(), "webview_cef",
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
|
||||
auto plugin = std::make_unique<WebviewCefPlugin>();
|
||||
@@ -163,13 +164,15 @@ namespace webview_cef {
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
|
||||
DWORD threadId = GetCurrentThreadId();
|
||||
auto invoke = [=](std::string method, WValue* arguments) {
|
||||
flutter::EncodableValue args = encode_wvalue_to_flvalue(arguments);
|
||||
channel->InvokeMethod(method, std::make_unique<flutter::EncodableValue>(args));
|
||||
flutter::EncodableValue *methodValue = new flutter::EncodableValue(method);
|
||||
flutter::EncodableValue *args = new flutter::EncodableValue(encode_wvalue_to_flvalue(arguments));
|
||||
PostThreadMessage(threadId, WM_USER + 1, WPARAM(methodValue), LPARAM(args));
|
||||
};
|
||||
webview_cef::setInvokeMethodFunc(invoke);
|
||||
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
window_registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
|
||||
WebviewCefPlugin::WebviewCefPlugin() {}
|
||||
@@ -178,9 +181,16 @@ namespace webview_cef {
|
||||
|
||||
void WebviewCefPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (method_call.method_name().compare("init") == 0) {
|
||||
texture_id = texture_registrar->RegisterTexture(m_texture.get());
|
||||
FlutterDesktopTextureInfo info = {};
|
||||
info.type = kFlutterDesktopPixelBufferTexture;
|
||||
info.pixel_buffer_config.user_data = std::get_if<flutter::PixelBufferTexture>(m_texture.get());
|
||||
info.pixel_buffer_config.callback = [](size_t width, size_t height, void* user_data) -> const FlutterDesktopPixelBuffer* {
|
||||
auto texture = static_cast<flutter::PixelBufferTexture*>(user_data);
|
||||
return texture->CopyPixelBuffer(width, height);
|
||||
};
|
||||
texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(texture_registrar, &info);
|
||||
auto callback = [=](const void* buffer, int32_t width, int32_t height) {
|
||||
const std::lock_guard<std::mutex> lock(buffer_mutex_);
|
||||
if (!pixel_buffer.get() || pixel_buffer.get()->width != width || pixel_buffer.get()->height != height) {
|
||||
@@ -203,26 +213,39 @@ namespace webview_cef {
|
||||
}
|
||||
|
||||
webview_cef::SwapBufferFromBgraToRgba((void*)pixel_buffer->buffer, buffer, width, height);
|
||||
texture_registrar->MarkTextureFrameAvailable(texture_id);
|
||||
FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(texture_registrar, texture_id);
|
||||
};
|
||||
webview_cef::setPaintCallBack(callback);
|
||||
result->Success(flutter::EncodableValue(texture_id));
|
||||
}
|
||||
else{
|
||||
WValue *encodeArgs = encode_flvalue_to_wvalue(const_cast<flutter::EncodableValue *>(method_call.arguments()));
|
||||
WValue *responseArgs = nullptr;
|
||||
int ret = webview_cef::HandleMethodCall(method_call.method_name(), encodeArgs, responseArgs);
|
||||
if (ret > 0){
|
||||
result->Success(encode_wvalue_to_flvalue(responseArgs));
|
||||
}
|
||||
else if (ret < 0){
|
||||
result->Error("error", "error", encode_wvalue_to_flvalue(responseArgs));
|
||||
}
|
||||
else{
|
||||
result->NotImplemented();
|
||||
}
|
||||
webview_cef::HandleMethodCall(method_call.method_name(), encodeArgs, [=](int ret, WValue* args){
|
||||
if (ret > 0){
|
||||
result->Success(encode_wvalue_to_flvalue(args));
|
||||
}
|
||||
else if (ret < 0){
|
||||
result->Error("error", "error", encode_wvalue_to_flvalue(args));
|
||||
}
|
||||
else{
|
||||
result->NotImplemented();
|
||||
}
|
||||
});
|
||||
webview_value_unref(encodeArgs);
|
||||
webview_value_unref(responseArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void WebviewCefPlugin::handleMessageProc(UINT message, WPARAM wparam, LPARAM lparam) {
|
||||
switch (message) {
|
||||
case WM_USER + 1:
|
||||
{
|
||||
flutter::EncodableValue *method = (flutter::EncodableValue *)wparam;
|
||||
flutter::EncodableValue *args = (flutter::EncodableValue *)lparam;
|
||||
channel->InvokeMethod(*std::get_if<std::string>(method), std::make_unique<flutter::EncodableValue>(*args));
|
||||
break;
|
||||
}
|
||||
case WM_QUIT:
|
||||
webview_cef::HandleMethodCall("dispose", nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace webview_cef {
|
||||
|
||||
class WebviewCefPlugin : public flutter::Plugin {
|
||||
public:
|
||||
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
|
||||
static void RegisterWithRegistrar(FlutterDesktopPluginRegistrarRef registrar);
|
||||
|
||||
WebviewCefPlugin();
|
||||
|
||||
@@ -21,11 +21,13 @@ class WebviewCefPlugin : public flutter::Plugin {
|
||||
WebviewCefPlugin(const WebviewCefPlugin&) = delete;
|
||||
WebviewCefPlugin& operator=(const WebviewCefPlugin&) = delete;
|
||||
|
||||
static void handleMessageProc(UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
private:
|
||||
// Called when a method is called on this plugin's channel from Dart.
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
};
|
||||
|
||||
} // namespace webview_cef
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
|
||||
void WebviewCefPluginCApiRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar) {
|
||||
webview_cef::WebviewCefPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
|
||||
webview_cef::WebviewCefPlugin::RegisterWithRegistrar(registrar);
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void initCEFProcesses() {
|
||||
@@ -99,8 +97,12 @@ int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam) {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void processKeyEventForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam)
|
||||
FLUTTER_PLUGIN_EXPORT void handleWndProcForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam)
|
||||
{
|
||||
if(message == WM_USER + 1){
|
||||
webview_cef::WebviewCefPlugin::handleMessageProc(message, wParam, lParam);
|
||||
return;
|
||||
}
|
||||
if (message != WM_SYSCHAR && message != WM_SYSKEYDOWN && message != WM_SYSKEYUP && message != WM_KEYDOWN && message != WM_KEYUP && message != WM_CHAR) return;
|
||||
CefKeyEvent event;
|
||||
event.windows_key_code = (int)wParam;
|
||||
|
||||
Reference in New Issue
Block a user