diff --git a/include/wx/msw/private/webview_edge.h b/include/wx/msw/private/webview_edge.h index e666f1f1c0..765127e9ed 100644 --- a/include/wx/msw/private/webview_edge.h +++ b/include/wx/msw/private/webview_edge.h @@ -36,6 +36,8 @@ public: bool m_initialized; bool m_isBusy; wxString m_pendingURL; + int m_pendingContextMenuEnabled; + int m_pendingAccessToDevToolsEnabled; // WebView Events tokens EventRegistrationToken m_navigationStartingToken = { }; @@ -63,7 +65,7 @@ public: ICoreWebView2Settings* GetSettings(); - static int ms_isAvailable; + static bool ms_isInitialized; static wxDynamicLibrary ms_loaderDll; static bool Initialize(); diff --git a/include/wx/msw/webview_edge.h b/include/wx/msw/webview_edge.h index f969566b33..dbdbfc5678 100644 --- a/include/wx/msw/webview_edge.h +++ b/include/wx/msw/webview_edge.h @@ -122,10 +122,6 @@ public: virtual void* GetNativeBackend() const wxOVERRIDE; - // ---- Edge-specific methods - - static bool IsAvailable(); - protected: virtual void DoSetPage(const wxString& html, const wxString& baseUrl) wxOVERRIDE; @@ -134,6 +130,8 @@ private: void OnSize(wxSizeEvent& event); + void OnShow(wxShowEvent& event); + bool RunScriptSync(const wxString& javascript, wxString* output = NULL); wxDECLARE_DYNAMIC_CLASS(wxWebViewEdge); @@ -153,6 +151,7 @@ public: { return new wxWebViewEdge(parent, id, url, pos, size, style, name); } + virtual bool IsAvailable() wxOVERRIDE; }; #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_EDGE && defined(__WXMSW__) diff --git a/include/wx/webview.h b/include/wx/webview.h index 53c78122c2..63ca8199a4 100644 --- a/include/wx/webview.h +++ b/include/wx/webview.h @@ -119,6 +119,7 @@ public: const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxASCII_STR(wxWebViewNameStr)) = 0; + virtual bool IsAvailable() { return true; } }; WX_DECLARE_STRING_HASH_MAP(wxSharedPtr, wxStringWebViewFactoryMap); diff --git a/interface/wx/webview.h b/interface/wx/webview.h index 9011577fbd..a1d1ce04e3 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -220,6 +220,17 @@ public: const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxWebViewNameStr) = 0; + /** + Function to check if the backend is available at runtime. The + wxWebView implementation can use this function to check all + runtime requirements without trying to create a wxWebView. + + @return returns @true if the backend can be used or @false if it is + not available during runtime. + + @since 3.1.5 + */ + virtual bool IsAvailable(); }; /** diff --git a/src/common/webview.cpp b/src/common/webview.cpp index ad44a43559..348a2ad75e 100644 --- a/src/common/webview.cpp +++ b/src/common/webview.cpp @@ -88,7 +88,10 @@ void wxWebView::RegisterFactory(const wxString& backend, bool wxWebView::IsBackendAvailable(const wxString& backend) { wxStringWebViewFactoryMap::iterator iter = FindFactory(backend); - return iter != m_factoryMap.end(); + if (iter != m_factoryMap.end()) + return iter->second->IsAvailable(); + else + return false; } // static @@ -111,8 +114,7 @@ void wxWebView::InitFactoryMap() #endif #if wxUSE_WEBVIEW_EDGE - if (wxWebViewEdge::IsAvailable() && - m_factoryMap.find(wxWebViewBackendEdge) == m_factoryMap.end()) + if (m_factoryMap.find(wxWebViewBackendEdge) == m_factoryMap.end()) RegisterFactory(wxWebViewBackendEdge, wxSharedPtr (new wxWebViewFactoryEdge)); #endif diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 4da9765eae..2dba6fffb1 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -51,7 +51,7 @@ typedef HRESULT(__stdcall *GetAvailableCoreWebView2BrowserVersionString_t)( CreateCoreWebView2EnvironmentWithOptions_t wxCreateCoreWebView2EnvironmentWithOptions = NULL; GetAvailableCoreWebView2BrowserVersionString_t wxGetAvailableCoreWebView2BrowserVersionString = NULL; -int wxWebViewEdgeImpl::ms_isAvailable = -1; +bool wxWebViewEdgeImpl::ms_isInitialized = false; wxDynamicLibrary wxWebViewEdgeImpl::ms_loaderDll; wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview): @@ -76,6 +76,8 @@ bool wxWebViewEdgeImpl::Create() { m_initialized = false; m_isBusy = false; + m_pendingContextMenuEnabled = -1; + m_pendingAccessToDevToolsEnabled = -1; m_historyLoadingFromList = false; m_historyEnabled = true; @@ -111,6 +113,9 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated( bool wxWebViewEdgeImpl::Initialize() { + if (ms_isInitialized) + return true; + if (!ms_loaderDll.Load("WebView2Loader.dll", wxDL_DEFAULT | wxDL_QUIET)) return false; @@ -124,7 +129,10 @@ bool wxWebViewEdgeImpl::Initialize() wxCoTaskMemPtr versionStr; HRESULT hr = wxGetAvailableCoreWebView2BrowserVersionString(NULL, &versionStr); if (SUCCEEDED(hr) && versionStr) + { + ms_isInitialized = true; return true; + } else wxLogApiError("GetCoreWebView2BrowserVersionInfo", hr); @@ -133,10 +141,10 @@ bool wxWebViewEdgeImpl::Initialize() void wxWebViewEdgeImpl::Uninitialize() { - if (ms_isAvailable == 1) + if (ms_isInitialized) { ms_loaderDll.Unload(); - ms_isAvailable = -1; + ms_isInitialized = false; } } @@ -310,6 +318,18 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control this, &wxWebViewEdgeImpl::OnContentLoading).Get(), &m_contentLoadingToken); + if (m_pendingContextMenuEnabled != -1) + { + m_ctrl->EnableContextMenu(m_pendingContextMenuEnabled == 1); + m_pendingContextMenuEnabled = -1; + } + + if (m_pendingAccessToDevToolsEnabled != -1) + { + m_ctrl->EnableAccessToDevTools(m_pendingAccessToDevToolsEnabled == 1); + m_pendingContextMenuEnabled = -1; + } + if (!m_pendingURL.empty()) { m_ctrl->LoadURL(m_pendingURL); @@ -335,21 +355,9 @@ ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings() return settings; } -bool wxWebViewEdge::IsAvailable() -{ - if (wxWebViewEdgeImpl::ms_isAvailable == -1) - { - if (!wxWebViewEdgeImpl::Initialize()) - wxWebViewEdgeImpl::ms_isAvailable = 0; - else - wxWebViewEdgeImpl::ms_isAvailable = 1; - } - - return wxWebViewEdgeImpl::ms_isAvailable == 1; -} - wxWebViewEdge::~wxWebViewEdge() { + Unbind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this); delete m_impl; } @@ -361,7 +369,7 @@ bool wxWebViewEdge::Create(wxWindow* parent, long style, const wxString& name) { - if (!IsAvailable()) + if (!wxWebViewEdgeImpl::Initialize()) return false; if (!wxControl::Create(parent, id, pos, size, style, @@ -374,6 +382,7 @@ bool wxWebViewEdge::Create(wxWindow* parent, if (!m_impl->Create()) return false; Bind(wxEVT_SIZE, &wxWebViewEdge::OnSize, this); + Bind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this); LoadURL(url); return true; @@ -385,6 +394,13 @@ void wxWebViewEdge::OnSize(wxSizeEvent& event) event.Skip(); } +void wxWebViewEdge::OnShow(wxShowEvent& event) +{ + if (m_impl->m_webView) + m_impl->m_webViewController->put_IsVisible(event.IsShown()); + event.Skip(); +} + void wxWebViewEdge::LoadURL(const wxString& url) { if (!m_impl->m_webView) @@ -706,6 +722,8 @@ void wxWebViewEdge::EnableContextMenu(bool enable) wxCOMPtr settings(m_impl->GetSettings()); if (settings) settings->put_AreDefaultContextMenusEnabled(enable); + else + m_impl->m_pendingContextMenuEnabled = enable ? 1 : 0; } bool wxWebViewEdge::IsContextMenuEnabled() const @@ -727,6 +745,8 @@ void wxWebViewEdge::EnableAccessToDevTools(bool enable) wxCOMPtr settings(m_impl->GetSettings()); if (settings) settings->put_AreDevToolsEnabled(enable); + else + m_impl->m_pendingAccessToDevToolsEnabled = enable ? 1 : 0; } bool wxWebViewEdge::IsAccessToDevToolsEnabled() const @@ -842,6 +862,14 @@ void wxWebViewEdge::DoSetPage(const wxString& html, const wxString& WXUNUSED(bas m_impl->m_webView->NavigateToString(html.wc_str()); } +// wxWebViewFactoryEdge + +bool wxWebViewFactoryEdge::IsAvailable() +{ + return wxWebViewEdgeImpl::Initialize(); +} + + // ---------------------------------------------------------------------------- // Module ensuring all global/singleton objects are destroyed on shutdown. // ----------------------------------------------------------------------------