From 7721deb062d0c4f2e7b82b276ace5b85f4bfc9a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Jan 2024 02:11:28 +0100 Subject: [PATCH] windows: added headless inappwebview initial implementation --- .../headless_in_app_webview.dart | 22 +-- .../lib/src/inappwebview_platform.dart | 12 ++ .../windows/CMakeLists.txt | 8 ++ .../flutter_inappwebview_windows_plugin.cpp | 3 +- .../flutter_inappwebview_windows_plugin.h | 2 + .../headless_in_app_webview.cpp | 59 ++++++++ .../headless_in_app_webview.h | 35 +++++ .../headless_in_app_webview_manager.cpp | 136 ++++++++++++++++++ .../headless_in_app_webview_manager.h | 36 +++++ .../headless_webview_channel_delegate.cpp | 56 ++++++++ .../headless_webview_channel_delegate.h | 27 ++++ .../windows/in_app_webview/in_app_webview.cpp | 25 ++-- .../webview_channel_delegate.cpp | 2 +- .../windows/types/size_2d.cpp | 21 +++ .../windows/types/size_2d.h | 25 ++++ 15 files changed, 446 insertions(+), 23 deletions(-) create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.cpp create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.h create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.cpp create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.h create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.cpp create mode 100644 flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.h create mode 100644 flutter_inappwebview_windows/windows/types/size_2d.cpp create mode 100644 flutter_inappwebview_windows/windows/types/size_2d.h diff --git a/flutter_inappwebview_windows/lib/src/in_app_webview/headless_in_app_webview.dart b/flutter_inappwebview_windows/lib/src/in_app_webview/headless_in_app_webview.dart index 7354b20b..843b144a 100644 --- a/flutter_inappwebview_windows/lib/src/in_app_webview/headless_in_app_webview.dart +++ b/flutter_inappwebview_windows/lib/src/in_app_webview/headless_in_app_webview.dart @@ -274,7 +274,7 @@ class WindowsHeadlessInAppWebView extends PlatformHeadlessInAppWebView dynamic _controllerFromPlatform; - WindowsHeadlessInAppWebViewCreationParams get _macosParams => + WindowsHeadlessInAppWebViewCreationParams get _windowsParams => params as WindowsHeadlessInAppWebViewCreationParams; _init() { @@ -284,7 +284,7 @@ class WindowsHeadlessInAppWebView extends PlatformHeadlessInAppWebView _controllerFromPlatform = params.controllerFromPlatform?.call(_webViewController!) ?? _webViewController!; - _macosParams.findInteractionController?.init(id); + _windowsParams.findInteractionController?.init(id); channel = MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview_$id'); handler = _handleMethod; @@ -320,8 +320,8 @@ class WindowsHeadlessInAppWebView extends PlatformHeadlessInAppWebView initialSettings.toMap(); Map pullToRefreshSettings = - _macosParams.pullToRefreshController?.params.settings.toMap() ?? - _macosParams.pullToRefreshController?.params.options.toMap() ?? + _windowsParams.pullToRefreshController?.params.settings.toMap() ?? + _windowsParams.pullToRefreshController?.params.options.toMap() ?? PullToRefreshSettings(enabled: false).toMap(); Map args = {}; @@ -341,8 +341,14 @@ class WindowsHeadlessInAppWebView extends PlatformHeadlessInAppWebView 'pullToRefreshSettings': pullToRefreshSettings, 'initialSize': params.initialSize.toMap() }); - await _sharedChannel.invokeMethod('run', args); - _running = true; + try { + await _sharedChannel.invokeMethod('run', args); + _running = true; + } catch (e) { + _running = false; + _started = false; + throw e; + } } void _inferInitialSettings(InAppWebViewSettings settings) { @@ -420,8 +426,8 @@ class WindowsHeadlessInAppWebView extends PlatformHeadlessInAppWebView _webViewController?.dispose(); _webViewController = null; _controllerFromPlatform = null; - _macosParams.pullToRefreshController?.dispose(); - _macosParams.findInteractionController?.dispose(); + _windowsParams.pullToRefreshController?.dispose(); + _windowsParams.findInteractionController?.dispose(); } } diff --git a/flutter_inappwebview_windows/lib/src/inappwebview_platform.dart b/flutter_inappwebview_windows/lib/src/inappwebview_platform.dart index a91ade71..3cbfaa80 100644 --- a/flutter_inappwebview_windows/lib/src/inappwebview_platform.dart +++ b/flutter_inappwebview_windows/lib/src/inappwebview_platform.dart @@ -3,6 +3,7 @@ import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_pla import 'in_app_browser/in_app_browser.dart'; import 'in_app_webview/in_app_webview.dart'; import 'in_app_webview/in_app_webview_controller.dart'; +import 'in_app_webview/headless_in_app_webview.dart'; /// Implementation of [InAppWebViewPlatform] using the WebKit API. class WindowsInAppWebViewPlatform extends InAppWebViewPlatform { @@ -61,4 +62,15 @@ class WindowsInAppWebViewPlatform extends InAppWebViewPlatform { WindowsInAppBrowser createPlatformInAppBrowserStatic() { return WindowsInAppBrowser.static(); } + + /// Creates a new [WindowsHeadlessInAppWebView]. + /// + /// This function should only be called by the app-facing package. + /// Look at using [HeadlessInAppWebView] in `flutter_inappwebview` instead. + @override + WindowsHeadlessInAppWebView createPlatformHeadlessInAppWebView( + PlatformHeadlessInAppWebViewCreationParams params, + ) { + return WindowsHeadlessInAppWebView(params); + } } diff --git a/flutter_inappwebview_windows/windows/CMakeLists.txt b/flutter_inappwebview_windows/windows/CMakeLists.txt index 908110bb..2d8801db 100644 --- a/flutter_inappwebview_windows/windows/CMakeLists.txt +++ b/flutter_inappwebview_windows/windows/CMakeLists.txt @@ -70,6 +70,8 @@ list(APPEND PLUGIN_SOURCES "types/user_script.h" "types/plugin_script.cpp" "types/plugin_script.h" + "types/size_2d.cpp" + "types/size_2d.h" "custom_platform_view/custom_platform_view.cc" "custom_platform_view/custom_platform_view.h" "custom_platform_view/texture_bridge.cc" @@ -96,6 +98,12 @@ list(APPEND PLUGIN_SOURCES "in_app_webview/in_app_webview_manager.h" "in_app_webview/webview_channel_delegate.cpp" "in_app_webview/webview_channel_delegate.h" + "headless_in_app_webview/headless_in_app_webview.cpp" + "headless_in_app_webview/headless_in_app_webview.h" + "headless_in_app_webview/headless_in_app_webview_manager.cpp" + "headless_in_app_webview/headless_in_app_webview_manager.h" + "headless_in_app_webview/headless_webview_channel_delegate.cpp" + "headless_in_app_webview/headless_webview_channel_delegate.h" "in_app_browser/in_app_browser_settings.cpp" "in_app_browser/in_app_browser_settings.h" "in_app_browser/in_app_browser_manager.cpp" diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp index dfbb46e1..57355649 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp @@ -1,8 +1,8 @@ #include "flutter_inappwebview_windows_plugin.h" -#include #include +#include "headless_in_app_webview/headless_in_app_webview_manager.h" #include "in_app_browser/in_app_browser_manager.h" #include "in_app_webview/in_app_webview_manager.h" @@ -25,6 +25,7 @@ namespace flutter_inappwebview_plugin { inAppWebViewManager = std::make_unique(this); inAppBrowserManager = std::make_unique(this); + headlessInAppWebViewManager = std::make_unique(this); } FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin() diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h index 9e882ea7..64566fa0 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h @@ -8,12 +8,14 @@ namespace flutter_inappwebview_plugin { class InAppWebViewManager; class InAppBrowserManager; + class HeadlessInAppWebViewManager; class FlutterInappwebviewWindowsPlugin : public flutter::Plugin { public: flutter::PluginRegistrarWindows* registrar; std::unique_ptr inAppWebViewManager; std::unique_ptr inAppBrowserManager; + std::unique_ptr headlessInAppWebViewManager; static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.cpp b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.cpp new file mode 100644 index 00000000..bf1db080 --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.cpp @@ -0,0 +1,59 @@ +#include "../utils/log.h" +#include "headless_in_app_webview.h" + +namespace flutter_inappwebview_plugin +{ + using namespace Microsoft::WRL; + + HeadlessInAppWebView::HeadlessInAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const HeadlessInAppWebViewCreationParams& params, const HWND parentWindow, std::unique_ptr webView) + : plugin(plugin), id(params.id), + webView(std::move(webView)), + channelDelegate(std::make_unique(this, plugin->registrar->messenger())) + { + prepare(params); + ShowWindow(parentWindow, SW_HIDE); + } + + void HeadlessInAppWebView::prepare(const HeadlessInAppWebViewCreationParams& params) + { + if (!webView) { + return; + } + webView->webViewController->put_IsVisible(false); + } + + void HeadlessInAppWebView::setSize(const std::shared_ptr size) const + { + if (!webView) { + return; + } + RECT rect = { + 0, 0, (LONG)size->width, (LONG)size->height + }; + webView->webViewController->put_Bounds(rect); + } + + std::shared_ptr HeadlessInAppWebView::getSize() const + { + if (!webView) { + return std::make_shared(-1.0, -1.0); + } + RECT rect; + webView->webViewController->get_Bounds(&rect); + auto width = rect.right - rect.left; + auto height = rect.bottom - rect.top; + return std::make_shared((double)width, (double)height); + } + + HeadlessInAppWebView::~HeadlessInAppWebView() + { + debugLog("dealloc HeadlessInAppWebView"); + if (webView && webView->webViewController) { + HWND parentWindow; + if (succeededOrLog(webView->webViewController->get_ParentWindow(&parentWindow))) { + DestroyWindow(parentWindow); + } + } + webView = nullptr; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.h b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.h new file mode 100644 index 00000000..0e419602 --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview.h @@ -0,0 +1,35 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_H_ + +#include "../flutter_inappwebview_windows_plugin.h" +#include "../in_app_webview/in_app_webview.h" +#include "../types/size_2d.h" +#include "headless_webview_channel_delegate.h" + +namespace flutter_inappwebview_plugin +{ + struct HeadlessInAppWebViewCreationParams { + const std::string id; + const std::shared_ptr initialSize; + }; + + class HeadlessInAppWebView + { + public: + static inline const wchar_t* CLASS_NAME = L"HeadlessInAppWebView"; + static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_headless_inappwebview_"; + + const FlutterInappwebviewWindowsPlugin* plugin; + std::string id; + std::unique_ptr webView; + std::unique_ptr channelDelegate; + + HeadlessInAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const HeadlessInAppWebViewCreationParams& params, const HWND parentWindow, std::unique_ptr webView); + ~HeadlessInAppWebView(); + + void prepare(const HeadlessInAppWebViewCreationParams& params); + void setSize(const std::shared_ptr size) const; + std::shared_ptr getSize() const; + }; +} +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.cpp b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.cpp new file mode 100644 index 00000000..a8803bae --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include + +#include "../in_app_webview/in_app_webview_settings.h" +#include "../types/size_2d.h" +#include "../types/url_request.h" +#include "../types/user_script.h" +#include "../utils/flutter.h" +#include "../utils/log.h" +#include "../utils/string.h" +#include "../utils/vector.h" +#include "headless_in_app_webview_manager.h" + +namespace flutter_inappwebview_plugin +{ + HeadlessInAppWebViewManager::HeadlessInAppWebViewManager(const FlutterInappwebviewWindowsPlugin* plugin) + : plugin(plugin), + ChannelDelegate(plugin->registrar->messenger(), HeadlessInAppWebViewManager::METHOD_CHANNEL_NAME) + { + windowClass_.lpszClassName = HeadlessInAppWebView::CLASS_NAME; + windowClass_.lpfnWndProc = &DefWindowProc; + + RegisterClass(&windowClass_); + } + + void HeadlessInAppWebViewManager::HandleMethodCall(const flutter::MethodCall& method_call, + std::unique_ptr> result) + { + auto* arguments = std::get_if(method_call.arguments()); + auto& methodName = method_call.method_name(); + + if (string_equals(methodName, "run")) { + run(arguments, std::move(result)); + } + else { + result->NotImplemented(); + } + } + + void HeadlessInAppWebViewManager::run(const flutter::EncodableMap* arguments, std::unique_ptr> result) + { + auto result_ = std::shared_ptr>(std::move(result)); + + auto id = get_fl_map_value(*arguments, "id"); + auto params = get_fl_map_value(*arguments, "params"); + + auto initialSize = std::make_shared(get_fl_map_value(params, "initialSize")); + + auto settingsMap = get_fl_map_value(params, "initialSettings"); + auto urlRequestMap = get_optional_fl_map_value(params, "initialUrlRequest"); + auto initialFile = get_optional_fl_map_value(params, "initialFile"); + auto initialDataMap = get_optional_fl_map_value(params, "initialData"); + auto initialUserScriptList = get_optional_fl_map_value(params, "initialUserScripts"); + + RECT bounds; + GetClientRect(plugin->registrar->GetView()->GetNativeWindow(), &bounds); + + auto initialWidth = initialSize->width >= 0 ? initialSize->width : bounds.right - bounds.left; + auto initialHeight = initialSize->height >= 0 ? initialSize->height : bounds.bottom - bounds.top; + + auto hwnd = CreateWindowEx(0, windowClass_.lpszClassName, L"", 0, 0, + 0, (int)initialWidth, (int)initialHeight, + plugin->registrar->GetView()->GetNativeWindow(), + nullptr, + windowClass_.hInstance, nullptr); + + InAppWebView::createInAppWebViewEnv(hwnd, false, + [=](wil::com_ptr webViewEnv, + wil::com_ptr webViewController, + wil::com_ptr webViewCompositionController) + { + if (webViewEnv && webViewController) { + auto initialSettings = std::make_unique(settingsMap); + std::optional>> initialUserScripts = initialUserScriptList.has_value() ? + functional_map(initialUserScriptList.value(), [](const flutter::EncodableValue& map) { return std::make_shared(std::get(map)); }) : + std::optional>>{}; + + InAppWebViewCreationParams params = { + id, + std::move(initialSettings), + initialUserScripts + }; + + auto inAppWebView = std::make_unique(plugin, params, hwnd, + std::move(webViewEnv), std::move(webViewController), nullptr + ); + + HeadlessInAppWebViewCreationParams headlessParams = { + id, + std::move(initialSize) + }; + + auto headlessInAppWebView = std::make_unique(plugin, + headlessParams, + hwnd, + std::move(inAppWebView)); + + headlessInAppWebView->webView->initChannel(std::nullopt, std::nullopt); + + if (headlessInAppWebView->channelDelegate) { + headlessInAppWebView->channelDelegate->onWebViewCreated(); + } + + std::optional> urlRequest = urlRequestMap.has_value() ? std::make_shared(urlRequestMap.value()) : std::optional>{}; + if (urlRequest.has_value()) { + headlessInAppWebView->webView->loadUrl(urlRequest.value()); + } + else if (initialFile.has_value()) { + headlessInAppWebView->webView->loadFile(initialFile.value()); + } + else if (initialDataMap.has_value()) { + headlessInAppWebView->webView->loadData(get_fl_map_value(initialDataMap.value(), "data")); + } + + webViews.insert({ id, std::move(headlessInAppWebView) }); + + result_->Success(true); + } + else { + result_->Error("0", "Cannot create the HeadlessInAppWebView instance!"); + } + } + ); + } + + HeadlessInAppWebViewManager::~HeadlessInAppWebViewManager() + { + debugLog("dealloc HeadlessInAppWebViewManager"); + webViews.clear(); + UnregisterClass(windowClass_.lpszClassName, nullptr); + plugin = nullptr; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.h b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.h new file mode 100644 index 00000000..1e52c51f --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_in_app_webview_manager.h @@ -0,0 +1,36 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_MANAGER_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_MANAGER_H_ + +#include +#include +#include +#include +#include + +#include "../flutter_inappwebview_windows_plugin.h" +#include "../types/channel_delegate.h" +#include "headless_in_app_webview.h" + +namespace flutter_inappwebview_plugin +{ + class HeadlessInAppWebViewManager : public ChannelDelegate + { + public: + static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_headless_inappwebview"; + + const FlutterInappwebviewWindowsPlugin* plugin; + std::map> webViews; + + HeadlessInAppWebViewManager(const FlutterInappwebviewWindowsPlugin* plugin); + ~HeadlessInAppWebViewManager(); + + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + + void run(const flutter::EncodableMap* arguments, std::unique_ptr> result); + private: + WNDCLASS windowClass_ = {}; + }; +} +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_IN_APP_WEBVIEW_MANAGER_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.cpp b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.cpp new file mode 100644 index 00000000..5aadab56 --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.cpp @@ -0,0 +1,56 @@ +#include "../utils/flutter.h" +#include "../utils/log.h" +#include "../utils/strconv.h" +#include "../utils/string.h" +#include "headless_in_app_webview.h" +#include "headless_webview_channel_delegate.h" + +#include "headless_in_app_webview_manager.h" + +namespace flutter_inappwebview_plugin +{ + HeadlessWebViewChannelDelegate::HeadlessWebViewChannelDelegate(HeadlessInAppWebView* webView, flutter::BinaryMessenger* messenger) + : webView(webView), ChannelDelegate(messenger, HeadlessInAppWebView::METHOD_CHANNEL_NAME_PREFIX + variant_to_string(webView->id)) + {} + + void HeadlessWebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall& method_call, + std::unique_ptr> result) + { + if (!webView) { + result->Success(); + return; + } + + // auto& arguments = std::get(*method_call.arguments()); + auto& methodName = method_call.method_name(); + + if (string_equals(methodName, "dispose")) { + if (webView->plugin && webView->plugin->headlessInAppWebViewManager) { + std::map>& webViews = webView->plugin->headlessInAppWebViewManager->webViews; + auto& id = webView->id; + if (map_contains(webViews, id)) { + webViews.erase(id); + } + } + result->Success(); + } + else { + result->NotImplemented(); + } + } + + void HeadlessWebViewChannelDelegate::onWebViewCreated() const + { + if (!channel) { + return; + } + + channel->InvokeMethod("onWebViewCreated", nullptr); + } + + HeadlessWebViewChannelDelegate::~HeadlessWebViewChannelDelegate() + { + debugLog("dealloc HeadlessWebViewChannelDelegate"); + webView = nullptr; + } +} diff --git a/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.h b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.h new file mode 100644 index 00000000..15d3a8ed --- /dev/null +++ b/flutter_inappwebview_windows/windows/headless_in_app_webview/headless_webview_channel_delegate.h @@ -0,0 +1,27 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_WEBVIEW_CHANNEL_DELEGATE_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_WEBVIEW_CHANNEL_DELEGATE_H_ + +#include "../types/channel_delegate.h" +#include + +namespace flutter_inappwebview_plugin +{ + class HeadlessInAppWebView; + + class HeadlessWebViewChannelDelegate : public ChannelDelegate + { + public: + HeadlessInAppWebView* webView; + + HeadlessWebViewChannelDelegate(HeadlessInAppWebView* webView, flutter::BinaryMessenger* messenger); + ~HeadlessWebViewChannelDelegate(); + + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + + void onWebViewCreated() const; + }; +} + +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_HEADLESS_WEBVIEW_CHANNEL_DELEGATE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp index e2edd175..8f1f9658 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp @@ -274,7 +274,7 @@ namespace flutter_inappwebview_plugin navigationActions_.insert({ navigationId, navigationAction }); } - if (callShouldOverrideUrlLoading_ && requestMethod == nullptr) { + if (settings->useShouldOverrideUrlLoading && callShouldOverrideUrlLoading_ && requestMethod == nullptr) { // for some reason, we can't cancel and load an URL with other HTTP methods than GET, // so ignore the shouldOverrideUrlLoading event. @@ -1187,21 +1187,20 @@ namespace flutter_inappwebview_plugin InAppWebView::~InAppWebView() { debugLog("dealloc InAppWebView"); - HWND parentWindow; - webViewController->get_ParentWindow(&parentWindow); - if (webView) { - webView->Stop(); - } - if (webViewController) { - webViewController->Close(); - } - navigationActions_.clear(); - inAppBrowser = nullptr; - plugin = nullptr; - if (webViewCompositionController) { + HWND parentWindow = nullptr; + if (webViewCompositionController && succeededOrLog(webViewController->get_ParentWindow(&parentWindow))) { // if it's an InAppWebView, // then destroy the Window created with it DestroyWindow(parentWindow); } + if (webView) { + failedLog(webView->Stop()); + } + if (webViewController) { + failedLog(webViewController->Close()); + } + navigationActions_.clear(); + inAppBrowser = nullptr; + plugin = nullptr; } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp index db7e2875..a2648dc7 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp @@ -22,7 +22,7 @@ namespace flutter_inappwebview_plugin { decodeResult = [](const flutter::EncodableValue* value) { - if (value->IsNull()) { + if (!value || value->IsNull()) { return NavigationActionPolicy::cancel; } auto navigationPolicy = std::get(*value); diff --git a/flutter_inappwebview_windows/windows/types/size_2d.cpp b/flutter_inappwebview_windows/windows/types/size_2d.cpp new file mode 100644 index 00000000..e1239026 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/size_2d.cpp @@ -0,0 +1,21 @@ +#include "size_2d.h" + +namespace flutter_inappwebview_plugin +{ + Size2D::Size2D(const double& width, const double& height) + : width(width), height(height) + {} + + Size2D::Size2D(const flutter::EncodableMap& map) + : width(get_fl_map_value(map, "width")), + height(get_fl_map_value(map, "height")) + {} + + flutter::EncodableMap Size2D::toEncodableMap() const + { + return flutter::EncodableMap{ + {"width", width}, + {"height", height} + }; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/size_2d.h b/flutter_inappwebview_windows/windows/types/size_2d.h new file mode 100644 index 00000000..01162a95 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/size_2d.h @@ -0,0 +1,25 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_SIZE_2D_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_SIZE_2D_H_ + +#include +#include + +#include "../utils/flutter.h" + +namespace flutter_inappwebview_plugin +{ + class Size2D + { + public: + const double width; + const double height; + + Size2D(const double& width, const double& height); + Size2D(const flutter::EncodableMap& map); + ~Size2D() = default; + + flutter::EncodableMap toEncodableMap() const; + }; +} + +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_SIZE_2D_H_ \ No newline at end of file