Allow specifying a custom CefClient to use with wxWebViewChromium

This opens many customization possibilities beyond those provided by
wxWebView API and also allows to process CEF IPC messages much more
efficiently than what is possible using wxEvents.

Closes #24336.
This commit is contained in:
Vadim Zeitlin 2024-02-17 18:34:15 +01:00
parent a766ed9f21
commit 5ca49dc56c
11 changed files with 249 additions and 3 deletions

View file

@ -18,6 +18,8 @@ class WXDLLIMPEXP_FWD_BASE wxFileName;
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendChromium[];
class CefClient;
// Private namespace containing classes used only in the implementation.
namespace wxCEF
{
@ -170,6 +172,10 @@ private:
friend class wxCEF::ClientHandler;
wxCEF::ClientHandler* m_clientHandler = nullptr;
// Actual client used by CEF: this can be either m_clientHandler itself or
// a custom client provided by the application.
CefClient* m_actualClient = nullptr;
friend class wxWebViewChromiumModule;
static bool ms_cefInitialized;
@ -198,6 +204,19 @@ public:
// Logging level must be one of cef_log_severity_t values (0 means default).
int m_logLevel = 0;
// Function to create the custom CefClient to use if non-null.
//
// The CefClient subclass must delegate all not otherwise implemented
// functions to the provided client (and should always delegate the
// lifetime-related callbacks).
//
// It is recommended, although not required, to derive the custom client
// from wxDelegatingCefClient defined in wx/webview_chromium_impl.h.
CefClient* (*m_clientCreate)(CefClient* client, void* data) = nullptr;
// Data to pass to m_clientCreate if it is used.
void* m_clientCreateData = nullptr;
};

View file

@ -0,0 +1,97 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/webview_chromium_impl.h
// Purpose: Helpers for implementing custom CefClient for wxWebViewChromium
// Author: Vadim Zeitlin
// Created: 2024-02-17
// Copyright: (c) 2024 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_WEBVIEW_CHROMIUM_IMPL_H_
#define _WX_WEBVIEW_CHROMIUM_IMPL_H_
// Note that this header includes CEF headers and so the appropriate include
// path should be set up when using it.
#ifdef __VISUALC__
#pragma warning(push)
#pragma warning(disable:4100)
#endif
wxGCC_WARNING_SUPPRESS(unused-parameter)
#include "include/cef_client.h"
wxGCC_WARNING_RESTORE(unused-parameter)
#ifdef __VISUALC__
#pragma warning(pop)
#endif
// ----------------------------------------------------------------------------
// Convenient base class for custom CefClient implementations.
// ----------------------------------------------------------------------------
class wxDelegatingCefClient : public CefClient
{
public:
// Forward all CefClient methods to the original client.
virtual CefRefPtr<CefAudioHandler> GetAudioHandler() override
{ return m_clientOrig->GetAudioHandler(); }
virtual CefRefPtr<CefCommandHandler> GetCommandHandler() override
{ return m_clientOrig->GetCommandHandler(); }
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override
{ return m_clientOrig->GetContextMenuHandler(); }
virtual CefRefPtr<CefDialogHandler> GetDialogHandler() override
{ return m_clientOrig->GetDialogHandler(); }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override
{ return m_clientOrig->GetDisplayHandler(); }
virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() override
{ return m_clientOrig->GetDownloadHandler(); }
virtual CefRefPtr<CefDragHandler> GetDragHandler() override
{ return m_clientOrig->GetDragHandler(); }
virtual CefRefPtr<CefFindHandler> GetFindHandler() override
{ return m_clientOrig->GetFindHandler(); }
virtual CefRefPtr<CefFocusHandler> GetFocusHandler() override
{ return m_clientOrig->GetFocusHandler(); }
virtual CefRefPtr<CefFrameHandler> GetFrameHandler() override
{ return m_clientOrig->GetFrameHandler(); }
virtual CefRefPtr<CefPermissionHandler> GetPermissionHandler() override
{ return m_clientOrig->GetPermissionHandler(); }
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override
{ return m_clientOrig->GetJSDialogHandler(); }
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() override
{ return m_clientOrig->GetKeyboardHandler(); }
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override
{ return m_clientOrig->GetLifeSpanHandler(); }
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override
{ return m_clientOrig->GetLoadHandler(); }
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() override
{ return m_clientOrig->GetPrintHandler(); }
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override
{ return m_clientOrig->GetRenderHandler(); }
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override
{ return m_clientOrig->GetRequestHandler(); }
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) override
{
return m_clientOrig->OnProcessMessageReceived(browser, frame,
source_process, message);
}
protected:
// Objects of this class shouldn't be created, only derived classes should
// be used, hence the constructor is protected.
explicit wxDelegatingCefClient(CefClient* clientOrig)
: m_clientOrig{clientOrig}
{
}
CefRefPtr<CefClient> const m_clientOrig;
IMPLEMENT_REFCOUNTING(wxDelegatingCefClient);
};
#endif // _WX_WEBVIEW_CHROMIUM_IMPL_H_