Add wxEVT_WEBVIEW_CREATED for wxWebViewChromium async creation

wxWebViewChromium creation is asynchronous and the object can't be
really used until OnAfterCreated() is called, so expose this in the
public API via a new event sent when the object becomes actually usable.

As a side effect, add a convenient wxWebViewEvent ctor taking wxWebView
as argument and calling SetEventObject() itself, instead of forcing all
code creating wxWebViewEvents to do it.
This commit is contained in:
Vadim Zeitlin 2023-09-05 21:22:33 +02:00
parent f1734a29b6
commit 92f6f164b3
10 changed files with 58 additions and 3 deletions

View file

@ -333,6 +333,9 @@ protected:
void SendScriptResult(void* clientData, bool success,
const wxString& output) const;
// Send wxEVT_WEBVIEW_CREATED event. This function is MT-safe.
void NotifyWebViewCreated();
private:
static void InitFactoryMap();
static wxStringWebViewFactoryMap::iterator FindFactory(const wxString &backend);
@ -377,6 +380,12 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewEvent : public wxNotifyEvent
public:
wxWebViewEvent() = default;
wxWebViewEvent(wxWebView& webview, wxEventType type)
: wxNotifyEvent(type, webview.GetId())
{
SetEventObject(&webview);
}
wxWebViewEvent(wxEventType type, int id, const wxString& url,
const wxString target,
wxWebViewNavigationActionFlags flags = wxWEBVIEW_NAV_ACTION_NONE,
@ -405,6 +414,7 @@ private:
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN_DEF_COPY(wxWebViewEvent);
};
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_CREATED, wxWebViewEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NAVIGATING, wxWebViewEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NAVIGATED, wxWebViewEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_LOADED, wxWebViewEvent );
@ -423,6 +433,10 @@ typedef void (wxEvtHandler::*wxWebViewEventFunction)
#define wxWebViewEventHandler(func) \
wxEVENT_HANDLER_CAST(wxWebViewEventFunction, func)
#define EVT_WEBVIEW_CREATED(id, fn) \
wx__DECLARE_EVT1(wxEVT_WEBVIEW_CREATED, id, \
wxWebViewEventHandler(fn))
#define EVT_WEBVIEW_NAVIGATING(id, fn) \
wx__DECLARE_EVT1(wxEVT_WEBVIEW_NAVIGATING, id, \
wxWebViewEventHandler(fn))

View file

@ -904,6 +904,11 @@ public:
@c scheme:///C:/example/docs.zip;protocol=zip/main.htm
@beginEventEmissionTable{wxWebViewEvent}
@event{EVT_WEBVIEW_CREATED(id, func)}
Process a @c wxEVT_WEBVIEW_CREATED event, generated when the object is
fully initialized. For the backends using asynchronous initialization,
such as wxWebViewChromium, most of this class member functions can be
only used once this event is received.
@event{EVT_WEBVIEW_NAVIGATING(id, func)}
Process a @c wxEVT_WEBVIEW_NAVIGATING event, generated before trying
to get a resource. This event may be vetoed to prevent navigating to this
@ -967,6 +972,12 @@ public:
/**
Creation function for two-step creation.
Please note that the object creation may be asynchronous when using
some backends (currently this is the case only for wxWebViewChromium)
and the object is not really created until wxEVT_WEBVIEW_CREATED event
is received, so any non-trivial calls to its member functions should be
delayed until then.
*/
virtual bool Create(wxWindow* parent,
wxWindowID id,
@ -999,6 +1010,10 @@ public:
/**
Factory function to create a new wxWebView using a wxWebViewFactory.
Note that the returned object may not be immediately usable yet, see
Create() and wxEVT_WEBVIEW_CREATED.
@param parent Parent window for the control
@param id ID of this control
@param url Initial URL to load
@ -1785,6 +1800,11 @@ public:
wxWebView objects.
@beginEventEmissionTable{wxWebViewEvent}
@event{EVT_WEBVIEW_CREATED(id, func)}
Process a @c wxEVT_WEBVIEW_CREATED event, generated when the object is
fully initialized. For the backends using asynchronous initialization,
such as wxWebViewChromium, most of this class member functions can be
only used once this event is received.
@event{EVT_WEBVIEW_NAVIGATING(id, func)}
Process a @c wxEVT_WEBVIEW_NAVIGATING event, generated before trying
to get a resource. This event may be vetoed to prevent navigating to this
@ -1911,6 +1931,7 @@ public:
};
wxEventType wxEVT_WEBVIEW_CREATED;
wxEventType wxEVT_WEBVIEW_NAVIGATING;
wxEventType wxEVT_WEBVIEW_NAVIGATED;
wxEventType wxEVT_WEBVIEW_LOADED;

View file

@ -475,8 +475,8 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowFeatures* wi
// Chromium backend can't be used immediately after creation, so wait
// until the browser is created before calling GetUserAgent().
m_browser->Bind(wxEVT_CREATE, [this](wxWindowCreateEvent& event) {
wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
m_browser->Bind(wxEVT_WEBVIEW_CREATED, [this](wxWebViewEvent& event) {
wxLogMessage("Web view created, user agent is \"%s\"", m_browser->GetUserAgent());
event.Skip();
});
@ -1398,7 +1398,7 @@ void WebFrame::OnAddUserScript(wxCommandEvent & WXUNUSED(evt))
void WebFrame::OnSetCustomUserAgent(wxCommandEvent& WXUNUSED(evt))
{
wxString customUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1";
wxString customUserAgent = m_browser->GetUserAgent();
wxTextEntryDialog dialog
(
this,

View file

@ -45,6 +45,7 @@ extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendDefault[] = "wxWebVi
wxIMPLEMENT_ABSTRACT_CLASS(wxWebView, wxControl);
wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEvent, wxCommandEvent);
wxDEFINE_EVENT( wxEVT_WEBVIEW_CREATED, wxWebViewEvent );
wxDEFINE_EVENT( wxEVT_WEBVIEW_NAVIGATING, wxWebViewEvent );
wxDEFINE_EVENT( wxEVT_WEBVIEW_NAVIGATED, wxWebViewEvent );
wxDEFINE_EVENT( wxEVT_WEBVIEW_LOADED, wxWebViewEvent );
@ -446,6 +447,13 @@ wxWebView* wxWebView::New(wxWindow* parent, wxWindowID id, const wxString& url,
}
void wxWebView::NotifyWebViewCreated()
{
GetEventHandler()->QueueEvent(
new wxWebViewEvent{*this, wxEVT_WEBVIEW_CREATED}
);
}
// static
void wxWebView::RegisterFactory(const wxString& backend,
wxSharedPtr<wxWebViewFactory> factory)

View file

@ -1012,6 +1012,8 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
m_browserId = browser->GetIdentifier();
m_webview.PostSizeEvent();
m_webview.NotifyWebViewCreated();
}
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> WXUNUSED(browser))

View file

@ -508,6 +508,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
G_CALLBACK(wxgtk_webview_webkit_load_status),
this);
NotifyWebViewCreated();
return true;
}

View file

@ -907,6 +907,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
PostCreation(size);
NotifyWebViewCreated();
/* Open a webpage */
if (!isChildWebView)
webkit_web_view_load_uri(m_web_view, url.utf8_str());

View file

@ -1033,6 +1033,8 @@ bool wxWebViewEdge::Create(wxWindow* parent,
if (topLevelParent)
topLevelParent->Bind(wxEVT_ICONIZE, &wxWebViewEdge::OnTopLevelParentIconized, this);
NotifyWebViewCreated();
LoadURL(url);
return true;
}

View file

@ -109,6 +109,8 @@ bool wxWebViewIE::Create(wxWindow* parent,
// pages without any physical network connection.
SetOfflineMode(false);
NotifyWebViewCreated();
LoadURL(url);
return true;
}

View file

@ -321,6 +321,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
m_UIDelegate = uiDelegate;
NotifyWebViewCreated();
if (m_request)
[m_webView loadRequest:(NSURLRequest*)m_request];
else