Merge branch 'main' into main

This commit is contained in:
SinyimZhi
2024-01-11 19:48:36 +08:00
committed by GitHub
17 changed files with 164 additions and 207 deletions

View File

@@ -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)

View File

@@ -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_

View File

@@ -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)

View File

@@ -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);

View File

@@ -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')) {

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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,
});
}

View File

@@ -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,
),
),
),

View File

@@ -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){

View File

@@ -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

View File

@@ -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

View File

@@ -17,6 +17,6 @@
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
result([CefWrapper handleMethodCallWrapper:call]);
[CefWrapper handleMethodCallWrapper:call result:result];
}
@end

View File

@@ -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"

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;