495 lines
19 KiB
Objective-C
495 lines
19 KiB
Objective-C
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: webview_chromium.h
|
|
// Purpose: interface of wxWebViewChromium
|
|
// Author: wxWidgets team
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
@class wxWebViewChromium
|
|
|
|
wxWebViewChromium is a Chromium-based backend for wxWebView using the
|
|
Chromium Embedded Framework (CEF).
|
|
|
|
This backend is only available for Windows, Linux and macOS and currently
|
|
requires CEF version 116 or later but earlier than 128, which has known
|
|
problems in wxGTK.
|
|
|
|
Using CEF also requires a compiler with at least C++14 support.
|
|
|
|
@section requirements Building CEF
|
|
|
|
If you are compiling your own copy of CEF then your compile flags must
|
|
match those you are using to compile wxWidgets. Specifically on Windows
|
|
it is likely you will need to adjust the following properties in the CEF
|
|
provided build files:
|
|
|
|
- C/C++ - Code Generation - Runtime Library - Multithreaded [Debug] DLL
|
|
- C/C++ - Code Generation - Enable C++ Exceptions - Yes
|
|
- C/C++ - Language - Enable Run-Time Type Information - Yes
|
|
|
|
@section instructions Build Instructions
|
|
|
|
__General__
|
|
|
|
When wxWebViewChromium backend is enabled, it is compiled as part of the
|
|
webview library which means that this library depends on CEF and all
|
|
applications using it must be linked with it.
|
|
|
|
Currently building wxWebViewChromium is possible only with configure-based
|
|
build system under Unix (including macOS) and using the provided MSVS
|
|
project files under MSW. Notably building it using CMake does not work.
|
|
|
|
Before enabling wxWebViewChromium you need to ensure that CEF is available:
|
|
|
|
1. Download the binaries for your platform from the CEF official site at
|
|
https://cef-builds.spotifycdn.com/index.html ("Minimal Distribution" is
|
|
sufficient)
|
|
2. Unpack the archive into `3rdparty/cef` directory under wxWidgets source
|
|
directory.
|
|
3. Build `libcef_dll_wrapper` using the instructions provided in the CEF
|
|
distribution, which basically means using `cmake` to do it. Please note:
|
|
* Under Windows you must use `-DCEF_RUNTIME_LIBRARY_FLAG=/MD` option
|
|
to match the default wxWidgets build configuration.
|
|
* Under Unix remember that if you use `-DCMAKE_BUILD_TYPE=Debug` when
|
|
building it, you need to pass `--enable-cef_debug` option to
|
|
wxWidgets configure to avoid mismatches between various definitions
|
|
in the wrapper itself and in wxWidgets.
|
|
* Under all platforms you may want to use `-DUSE_SANDBOX=OFF`
|
|
option to avoid linking with the sandbox library which is not
|
|
provided in the "Minimal Distribution" if you don't use this feature.
|
|
4. Copy the static library binary in the platform-dependent location:
|
|
- Under MSW, copy `libcefl_dll_wrapper.lib` file to either
|
|
`3rdparty/cef/Release` or `3rdparty/cef/Debug` depending on the build
|
|
configuration (it's recommended to build CEF wrapper in both
|
|
configurations and so copy the two files to both locations).
|
|
- Under Unix (including macOS), copy `libcef_dll_wrapper.a` file to
|
|
`3rdparty/cef/libcef_dll_wrapper` directory.
|
|
|
|
Then enable wxWebViewChromium support:
|
|
|
|
- Under MSW, set `wxUSE_WEBVIEW_CHROMIUM` to 1 in `wx/msw/setup.h`.
|
|
- Under Unix, add `--enable-webviewchromium` option to configure command
|
|
line.
|
|
|
|
Finally, build wxWidgets as usual: the resulting webview library will
|
|
include wxWebViewChromium.
|
|
|
|
It is recommended to build webview sample to check that everything is
|
|
working as expected. Under Unix, the required CEF files will be copied to
|
|
the sample directory as part of the build process, but under MSW you need
|
|
to copy them manually before running the sample: please copy
|
|
|
|
- All files from either `3rdparty/cef/Debug` or
|
|
`3rdparty/cef/Release` folder, depending on your build type
|
|
- The contents of the wx_root/3rdparty/cef/Resources folder.
|
|
|
|
to the directory containing `webview` executable.
|
|
|
|
Please see CEF `README.txt` for more details and also note that when
|
|
redistributing CEF you must abide by the terms of its `LICENSE.txt`.
|
|
|
|
Note that by default the webview sample uses the default platform-dependent
|
|
wxWebView backend and to use Chromium backend in it you need to set
|
|
`WX_WEBVIEW_BACKEND` environment variable to the value `wxWebViewChromium`.
|
|
|
|
|
|
__CEF Helper Process__
|
|
|
|
CEF uses multiple processes. The main process, using wxWidgets and creating
|
|
wxWebViewChromium, is known as the "browser process" but CEF also creates
|
|
additional helper processes for other tasks it needs to perform. Under
|
|
non-Mac platforms by default the main process itself is also used as the
|
|
helper process: if the main process detects the presence of the special
|
|
`--type=` command line option, it considers that it is executed as "CEF
|
|
helper" and just passes the command line to CEF instead of executing as
|
|
usual. This happens before executing any application-specific code and so
|
|
makes it impossible to use `--type` option for the application itself.
|
|
|
|
Under macOS main process cannot be used as the helper process and a
|
|
separate executable with the fixed name must be built to be used instead.
|
|
wxWidgets provides a trivial source of such helper process in
|
|
`samples/webview/cef_process_helper.cpp` file, which has to be compiled and
|
|
linked with CEF at least under macOS.
|
|
|
|
It may also be desirable to use a separate helper process under the other
|
|
platforms too and if an executable called `yourapp_cef_helper` (Unix) or
|
|
`yourapp_cef_helper.exe` (MSW), where `yourapp` is the name of the
|
|
application such as returned by wxApp::GetAppName(), is found in the same
|
|
directory as the main application executable itself, it will be used as the
|
|
CEF helper process.
|
|
|
|
|
|
__Microsoft Windows Platform__
|
|
|
|
Windows 10 or newer is required to run applications using wxWebViewChromium.
|
|
Such applications should also have an application manifest declaring compatibility
|
|
with supported Windows versions.
|
|
|
|
Microsoft Visual C++ 2022 must be used to build wxWebViewChromium.
|
|
|
|
When linking an application using it, both `libcef.lib` and
|
|
`libcef_dll_wrapper.lib` should be included in the libraries list.
|
|
|
|
__Linux with GTK__
|
|
|
|
wxWebviewChromium currently only supports X11 and not Wayland, i.e. you
|
|
need to either ensure that `GDK_BACKEND` environment variable is set to
|
|
"x11" before running your program using it or call
|
|
|
|
@code
|
|
gdk_set_allowed_backends("x11")
|
|
@endcode
|
|
|
|
in your application code, otherwise wxWebView::IsBackendAvailable() will
|
|
return @false when the application is running under Wayland and creating
|
|
wxWebviewChromium will fail in this case.
|
|
|
|
Moreover, the actual browser is only created once the window is shown, and
|
|
can't be used until then. You can bind an event handler for wxEVT_CREATE to
|
|
know when it is usable.
|
|
|
|
|
|
__macOS Platform__
|
|
|
|
macOS 10.13 or above is required.
|
|
|
|
Due to the application bundle structure on macOS, wxWebviewChromium is a
|
|
little more complicated than on Windows/Linux platforms as extra helper
|
|
applications for executing separate Chromium processes(renderer, plugin,
|
|
etc) are required.
|
|
|
|
For applications using wxWebviewChromium, below are the steps to make
|
|
it work, based off the webview sample bakefile.
|
|
|
|
1. Build the webview library with CEF support.
|
|
2. Compile/link/package the `YourApp helper` app:
|
|
- Require `cef_process_helper.cpp`
|
|
- Require link frameworks: Chromium Embedded Framework.framework,
|
|
AppKit.frameworks.
|
|
- Require app bundle configuration: Info.plist
|
|
- Use system tool `install_name_tool -change` to correct `Chromium
|
|
Embedded Framework.framework/Chromium Embedded Framework` location.
|
|
3. Compile/link/package `YourApp` itself as usual under macOS.
|
|
4. Create a `Contents/Frameworks` directory in `YourApp.app` bundle
|
|
and copy `Chromium Embedded Framework` and `YourApp helper.app` into it.
|
|
5. Create clones of `YourApp helper.app`, in the same directory, with the
|
|
names `YourApp helper (Alerts).app`, `YourApp helper (GUI).app` etc. It
|
|
is possible to use symbolic links to `YourApp helper` binary for the
|
|
executable files of these extra helpers.
|
|
|
|
Below is the wxWebviewChromium sample app bundle directory structure,
|
|
omitting some resource files
|
|
|
|
webview.app
|
|
|____Contents
|
|
|____MacOS
|
|
| |____webview
|
|
|____Resources
|
|
| |____wxmac.icns
|
|
|____Frameworks
|
|
| |____webview Helper.app
|
|
| | |____Contents
|
|
| | |____MacOS
|
|
| | | |____webview Helper
|
|
| | |____Resources
|
|
| | | |____wxmac.icns
|
|
| | |____Info.plist
|
|
| |____webview Helper (GPU).app
|
|
| | |____Contents
|
|
| | |____MacOS
|
|
| | | |____webview Helper (GPU)
|
|
| | |____Resources
|
|
| | | |____wxmac.icns
|
|
| | |____Info.plist
|
|
| |____webview Helper (Plugin).app
|
|
| | |____Contents
|
|
| | |____MacOS
|
|
| | | |____webview Helper (Plugin)
|
|
| | |____Resources
|
|
| | | |____wxmac.icns
|
|
| | |____Info.plist
|
|
| |____Chromium Embedded Framework.framework
|
|
| | |____Resources
|
|
| | | |____chrome_200_percent.pak
|
|
| | | |____chrome_100_percent.pak
|
|
| | | |____icudtl.dat
|
|
| | | |____snapshot_blob.bin
|
|
| | | |____v8_context_snapshot.arm64.bin
|
|
| | | |____resources.pak
|
|
| | | |____gpu_shader_cache.bin
|
|
| | | |____Info.plist
|
|
| | |____Libraries
|
|
| | | |____libEGL.dylib
|
|
| | | |____vk_swiftshader_icd.json
|
|
| | | |____libvk_swiftshader.dylib
|
|
| | | |____libGLESv2.dylib
|
|
| | |____Chromium Embedded Framework
|
|
| |____webview Helper (Renderer).app
|
|
| | |____Contents
|
|
| | |____MacOS
|
|
| | | |____webview Helper (Renderer)
|
|
| | |____Resources
|
|
| | | |____wxmac.icns
|
|
| | |____Info.plist
|
|
| |____webview Helper (Alerts).app
|
|
| |____Contents
|
|
| |____MacOS
|
|
| | |____webview Helper (Alerts)
|
|
| |____Resources
|
|
| | |____wxmac.icns
|
|
| |____Info.plist
|
|
|____Info.plist
|
|
|
|
|
|
|
|
@section differences API Differences
|
|
|
|
wxWebViewChromium aims to support the full wxWebView API, but there are
|
|
some features which are currently unsupported:
|
|
|
|
- GetSelectedSource/GetSelectedText: Always returns "".
|
|
- HasSelection: Always returns false.
|
|
- IsEditable: Always returns false.
|
|
- CanUndo/CanRedo/CanCut/CanCopy/CanPaste: Always returns true.
|
|
- Find: Always returns -1.
|
|
- RunScript: Retrieving the result of JavaScript execution is not supported and
|
|
if the @a output parameter is non-null, the function will always return false.
|
|
|
|
wxWebView also provides some functions not available in the base class:
|
|
|
|
- SetRoot() allows to use the given directory for all application files.
|
|
|
|
|
|
@section events Events
|
|
|
|
wxWebViewChromiumEvent is a specific event generated when a message from
|
|
the renderer process (in which any user-defined JavaScript functions are
|
|
executing) is received in the browser process (containing UI). Such
|
|
messages are sent using `CefFrame::SendProcessMessage(PID_BROWSER)` from
|
|
the renderer process, but describing Chromium IPC in details is out of
|
|
scope of this document, please see Chromium documentation for more
|
|
information.
|
|
|
|
@since 3.3.0
|
|
@library{wxwebview}
|
|
@category{webview}
|
|
|
|
**/
|
|
class wxWebViewChromium : public wxWebView
|
|
{
|
|
public:
|
|
/**
|
|
Default constructor.
|
|
|
|
Use Create() to actually create the web view object later.
|
|
*/
|
|
wxWebViewChromium();
|
|
|
|
/**
|
|
Constructor allowing to specify extra configuration parameters.
|
|
|
|
You must use Create() to really initialize the object created with this
|
|
constructor.
|
|
|
|
Chromium-specific configuration parameters can be specified by setting
|
|
wxWebViewConfigurationChromium fields before passing @a config to this
|
|
function, e.g.
|
|
|
|
@code
|
|
wxWebViewConfiguration config =
|
|
wxWebView::NewConfiguration(wxWebViewBackendChromium);
|
|
|
|
auto configChrome =
|
|
static_cast<wxWebViewConfigurationChromium*>(config.GetNativeConfiguration());
|
|
configChrome->m_logFile = "/my/custom/CEF/log/file/path.txt";
|
|
|
|
auto webview = new wxWebViewChromium(config);
|
|
webview->Create(this, wxID_ANY, url);
|
|
@endcode
|
|
*/
|
|
explicit wxWebViewChromium(const wxWebViewConfiguration& config);
|
|
|
|
/**
|
|
wxWebViewChromium constructor, arguments as per wxWebView::New.
|
|
*/
|
|
wxWebViewChromium(wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxString& url = wxWebViewDefaultURLStr,
|
|
const wxPoint& pos = wxDefaultPosition,
|
|
const wxSize& size = wxDefaultSize,
|
|
long style = 0,
|
|
const wxString& name = wxWebViewNameStr);
|
|
|
|
/**
|
|
Creation function for two-step creation.
|
|
*/
|
|
virtual bool Create(wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxString& url = wxWebViewDefaultURLStr,
|
|
const wxPoint& pos = wxDefaultPosition,
|
|
const wxSize& size = wxDefaultSize,
|
|
long style = 0,
|
|
const wxString& name = wxWebViewNameStr);
|
|
|
|
/**
|
|
Use the specified directory as root for the file:// URLs.
|
|
|
|
After calling this function, all file paths will be resolved relatively
|
|
to the given @a rootDir rather than to the actual file system root.
|
|
*/
|
|
void SetRoot(const wxFileName& rootDir);
|
|
};
|
|
|
|
|
|
/**
|
|
Chromium-specific configuration parameters.
|
|
|
|
This simple class contains parameters that can be passed to the function
|
|
initializing CEF when wxWebView is used for the first time.
|
|
|
|
To use this struct you need to cast the value returned from
|
|
wxWebViewConfiguration::GetNativeConfiguration() to this type:
|
|
@code
|
|
wxWebViewConfiguration config =
|
|
wxWebView::NewConfiguration(wxWebViewBackendChromium);
|
|
|
|
auto configChrome =
|
|
static_cast<wxWebViewConfigurationChromium*>(config.GetNativeConfiguration());
|
|
configChrome->m_logLevel = 99; // Disable all logging.
|
|
@endcode
|
|
|
|
@since 3.3.0
|
|
*/
|
|
class wxWebViewConfigurationChromium
|
|
{
|
|
public:
|
|
/**
|
|
Default constructor initializes the object to default parameters.
|
|
*/
|
|
wxWebViewConfigurationChromium();
|
|
|
|
/**
|
|
CEF log file location.
|
|
|
|
Should be an absolute path if specified.
|
|
|
|
If this variable is empty, `debug.log` under the data directory is
|
|
used.
|
|
*/
|
|
wxString m_logFile;
|
|
|
|
/**
|
|
Logging level to use for CEF.
|
|
|
|
This must be one of `cef_log_severity_t` values.
|
|
|
|
Default value 0 means to use default "INFO" log level.
|
|
*/
|
|
int m_logLevel = 0;
|
|
|
|
/**
|
|
Port for remote debugging if non-zero.
|
|
|
|
Settings this to non-zero value, e.g. 9223 which is commonly used,
|
|
enables Chrome remote debugging on the given port.
|
|
*/
|
|
int m_remoteDebuggingPort = 0;
|
|
|
|
/**
|
|
Function to create the custom CefClient to use if non-null.
|
|
|
|
CEF uses an object of CefClient class to customize handling of many
|
|
operations, by allowing to return custom objects from its callbacks,
|
|
and for processing IPC messages received from the other processes used
|
|
by CEF. By defining this function pointer, the application can use its
|
|
own CefClient subclass to customize many aspects of CEF behaviour
|
|
beyond what is possible using the standard wxWebView API.
|
|
|
|
Please note that the returned object must delegate all not otherwise
|
|
implemented functions to the provided @a client (and should always
|
|
delegate the lifetime-related callbacks). You can ensure that this is
|
|
the case by deriving your custom CefClient subclass from
|
|
wxDelegatingCefClient, but you still need to do it manually if not
|
|
using this class.
|
|
*/
|
|
CefClient* (*m_clientCreate)(CefClient* client, void* data) = nullptr;
|
|
|
|
/**
|
|
Data to pass to m_clientCreate if it is used.
|
|
|
|
This is just an arbitrary pointer, which is passed as argument to
|
|
m_clientCreate function if it is non-null.
|
|
|
|
This pointer itself may be null if it is not necessary to pass any
|
|
extra data to the client creation function.
|
|
*/
|
|
void* m_clientCreateData = nullptr;
|
|
};
|
|
|
|
/**
|
|
Event class for events generated exclusively by wxWebViewChromium.
|
|
|
|
See wxWebViewEvent for other events also generated by wxWebViewEvent.
|
|
|
|
Currently there is a single event type corresponding to this event:
|
|
`wxEVT_WEBVIEW_CHROMIUM_MESSAGE_RECEIVED`. To use it (this example assumes
|
|
that the required CEF headers are included):
|
|
|
|
@code
|
|
webview->Bind(
|
|
wxEVT_WEBVIEW_CHROMIUM_MESSAGE_RECEIVED,
|
|
[this](wxWebViewChromiumEvent& event) {
|
|
if ( event.GetMessageName() == "MyCustomRequest" ) {
|
|
CefRefPtr<CefListValue> arguments = event.GetMessage().GetArgumentList();
|
|
CefRefPtr<CefProcessMessage> response = CefProcessMessage::Create("MyCustomResponse");
|
|
|
|
// ... do whatever is needed to construct the response ...
|
|
|
|
event.GetFrame().SendProcessMessage(PID_RENDERER, response);
|
|
} else {
|
|
// Not our message.
|
|
event.Skip();
|
|
}
|
|
}
|
|
);
|
|
@endcode
|
|
|
|
@note Using wxEvent dispatching adds a significant overhead to handling of
|
|
CEF IPC messages, so if performance is important (i.e. many such messages
|
|
are expected), it is recommended to configure wxWebViewChromium to use a
|
|
custom `CefClient` as described in wxWebViewConfigurationChromium
|
|
documentation and handle the messages directly in the overridden
|
|
`OnProcessMessageReceived()` of the custom client class.
|
|
|
|
@since 3.3.0
|
|
@library{wxwebview}
|
|
@category{webview}
|
|
**/
|
|
class wxWebViewChromiumEvent : public wxCommandEvent
|
|
{
|
|
public:
|
|
/**
|
|
Get the associated browser frame.
|
|
|
|
This object can be used to call `SendProcessMessage(PID_RENDERER)` on
|
|
it to send the reply back to the renderer process.
|
|
*/
|
|
CefFrame& GetFrame() const;
|
|
|
|
/**
|
|
Get the actual message.
|
|
|
|
Message arguments can be used in the event handler to get information
|
|
associated with this message.
|
|
*/
|
|
CefProcessMessage& GetMessage() const;
|
|
|
|
/**
|
|
Get the message name.
|
|
|
|
This is just a convenient wrapper for `GetMessage().GetName()`.
|
|
*/
|
|
wxString GetMessageName() const;
|
|
};
|