How to Seamlessly Integrate Chromium Embedded Framework (CEF) on Windows and macOS
This guide explains how to adapt the cross‑platform Chromium Embedded Framework for both Windows and macOS, covering required libraries, resource path configuration, main and renderer process initialization, message‑loop handling, window adaptation, and version differentiation to keep a single code base maintainable.
Background
CEF is a cross‑platform framework based on the Chromium engine that can display web‑related pages inside native applications. It was previously used only on Windows, and the author adapted it for macOS in the Dongdong workbench, documenting the files, paths, and initialization steps required on both platforms.
1. Libraries and Resource Files
include folder – header files exposed by CEF.
libcef_dll folder – wrapper library source files.
Resources folder – CEF’s .pak resource files.
libcef.dll / Chromium Embedded Framework.framework – core CEF library.
Other dll/dylib files (e.g., libEGL) – dynamic libraries CEF depends on.
Other bin files (e.g., natives_blob.bin) – binary files CEF depends on.
All these files must be packaged with the installer. The include and libcef_dll folders can be combined into a static library (typically libcef_dll_wrapper.lib) for linking.
2. File Path Lookup
Resource files must be located via absolute paths set in CefSettings. The relevant settings are:
resources_dir_path (Windows) / framework_dir_path/main_bundle_path (macOS) – path to the .pak files.
locales_dir_path – path to locale files (same on both platforms).
browser_subprocess_path – path to the subprocess executable (identical on both platforms).
These paths cannot be relative; they must be fully qualified so the application can locate resources after installation.
3. Main Process Initialization
The main process initialization consists of several steps:
Load the CEF dynamic library. On Windows, placing libcef.dll next to the executable allows automatic loading; otherwise, load it explicitly. On macOS, use
CefScopedLibraryLoader library_loader; library_loader.LoadInMain();.
Obtain startup arguments using CefMainArgs.
Windows example:
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); CefMainArgs main_args(hInstance); CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine(); command_line->InitFromString(::GetCommandLineW());macOS example:
CefMainArgs main_args(argc, argv); CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine(); command_line->InitFromArgv(argc, argv);Create a ClientAppBrowser instance that derives from CefApp.
Set additional parameters in CefSettings such as log_severity, log_file, user_agent, and remote_debugging_port.
Call CefInitialize(main_args, settings, app.get(), sandbox_info). A successful return means the main process can continue; failure aborts the startup.
4. Renderer Process Creation
The renderer can run in the same process as the main process or in a separate subprocess. Large or complex projects usually use separate subprocesses, possibly multiple for different pages. Subprocess naming on macOS must end with “Helper”. Initialization steps mirror the main process: load the helper library (using
CefScopedLibraryLoader library_loader; library_loader.LoadInHelper();if needed), then call: CefExecuteProcess(main_args, app, nullptr) The return value > 0 indicates the subprocess started successfully; < 0 means failure, which prevents rendering but does not affect the main process.
5. Message Loop
Different platforms use different message‑loop strategies:
Windows : Set multi_threaded_message_loop = true in CefSettings to enable a separate CEF message thread that runs alongside the application’s UI thread.
macOS : Two options exist.
Run the entire application loop inside CEF by calling CefRunMessageLoop().
If the host uses Qt (or another framework with its own loop), embed CEF’s loop into the host’s loop by periodically calling CefDoMessageLoopWork() (e.g., every 20 ms).
6. Window Adaptation
When displaying web pages, the window size often needs to be adjusted. Platform‑specific APIs are used:
Get window ID : (CefWindowHandle)this->winId() on both Windows and macOS.
Resize window : Windows –
::MoveWindow(hwnd, rect.x(), rect.y(), rect.width(), rect.height(), true); macOS –
[nsview setFrameSize:NSMakeSize(rect.width(), rect.height())].
Get window handle : browser->GetHost()->GetWindowHandle() (Windows); macOS also provides GetOpenerWindowHandle() for non‑popup windows.
During browser creation, SetAsChild is called with the obtained window handle. Resizing must use native OS calls because CEF does not provide a generic method.
7. Version Differentiation
Use Qt macros to distinguish operating systems: Q_OS_WIN for Windows. Q_OS_MAC for macOS.
CEF version checks rely on definitions such as:
#define CEF_VERSION_MAJOR 106
#define CEF_VERSION_MINOR 1
#define CEF_VERSION_PATCH 0
#define CEF_COMMIT_NUMBER 2678If multiple major versions are present, compare CEF_VERSION_MAJOR; minor versions are only needed when the major numbers match.
Conclusion
By using the same CEF files on Windows and macOS and guarding platform‑specific code with Qt macros, a single source tree can run on both platforms and across different CEF versions, greatly simplifying maintenance and upgrades. Future work can split functionality into independent modules to reduce the learning curve for new developers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
