Many thanks to Marshall Greenblatt, the Chromium Embedded Framework founder, for writing and helping edit part of this blog post.
As frameworks usually go, CEF provides mainly a set of headers and a library. It is available on Windows, Mac OSX and Linux, though there is still work to do to have feature parity between platforms. C++ and C APIs are available as a part of the project, but there are projects out there which maintain wrappers for other environments like .NET, Java and Python.
Relationship with Chromium
CEF comes in two versions – CEF1 and CEF3, both of which are actively maintained. These two projects expose almost the same API to embedding clients, whie rendering HTML using the Chromium flavor of WebKit (now Blink). Where they differ is in how they hook into the HTML engine underneath, but to better understand that, it is useful to have a general overview of the Chromium architecture.
The Blink and Content APIs are not stable and many features have additional implementation requirements. CEF provides these implementations along with a stable API that hides most of the underlying Chromium and Blink complexity. CEF1 uses the Blink API directly and as a result shares the single-process architecture. CEF3 uses the Content API and benefits from the multi-process architecture and many of the advanced features that are implemented in the Content API. As an added benefit for CEF3 the Components changes will make it easier to selectively enable and share feature implementations that at this time cannot be shared due to tight coupling with the Chrome layer.
CEF3 implements some of the interfaces and delegates that the Content API provides, much in the same way that Chrome does. While a developer can embed Chromium starting directly from the Content API, this would involve a rather significant amount of work, which is already done in CEF3. This includes implementing the Content API interfaces and delegates that the application wants to manipulate, and while doing so, also writing the platform code for the platforms the application needs to run on (Windows/Mac/Linux). Using CEF, on the other hand, is as simple as writing a few lines of code before firing up a modern, up-to-date HTML5 view right inside the application.
Both CEF1 and CEF3 include parts Chromium into the resulting library, and as such, have a build dependency on the Chromium code. The project maintains compatibility with a specific revision of the Chromium code underneath, which is updated pretty regularly. From that point of view, embedders don’t have to worry that updating Chromium will break their application.
From here on, the term CEF will refer to CEF3, unless specified otherwise.
Probably the simplest way to start using CEF is to download one of the binary releases. CEF maintains branches that are compatible with the Chromium stabilisation branches used for releases. The periodic binary releases are usually built from one such stable branch.
The distributable package contains the headers, the library, some required resources, and also a test application called cefclient. This is where you should be looking. It is the perfect showcase of how to use CEF, from starting up the framework to implementing the HTML content callbacks exposed through the API. You can test things out by hacking at the application code, quickly rebuilding, and so on.
Note that you can also pass Chromium command line switches to cefclient, and they will have the same effect they would have in the browser (if they apply).
If you want to contribute, or use a feature that is not currently in one of the binary releases, you will have to build the CEF library from source. Although CEF is itself pretty lightweight, this also involves building Chromium, which makes the job a bit more complicated. I will not go into details in this post, but if you’re looking for a place to start, have a look at the CEF automate folder. The python script inside checks out both the CEF and Chromium source code and proceeds to build the final CEF package. The README file in the same folder describes the process in more detail, and also contains some required steps to be performed before running the script.
Our more considerable contributions to CEF, aside from various bug fixes are listed below.
IME on Mac [CEF1]
The first considerable contribution we made to CEF was implementing the missing platform code for the Mac OS X Input Method Editor (IME). In CEF1, this code was upright missing. In CEF3, it is already available underneath the Content API umbrella.
Tracing API [CEF3]
The tracing mechanism is a Chromium development tool which can be used to profile the Chromium code across threads and processes. Just type chrome://tracing in the Chrome URL bar if you’re wondering what this is, and start tracing. Our contribution was to expose the internal tracing API as a part of the CEF API. Embedders can use these methods to profile calls inside their own client application in the same view as the whole CEF – Chromium – Blink stack.
Offscreen Rendering on Windows and Mac [CEF3]
This feature allows embedders to receive paint notifications from CEF instead of having CEF render directly to a native window. The embedder can then handle the rendering themselves using technologies like OpenGL or Direct3D. As a part of this feature, UI events can also be forwarded to the HTML page. It is particularly useful when an embedder wants to draw something else on top of the HTML view or integrate with an existing application framework that performs its own rendering. Using offscreen rendering provides a simple solution for synchronized drawing between two overlapping views, even two HTML views. This would be a real hassle when dealing with two overlapped, transparent native views.
Another use case is to break the boundary between 64 and 32 bit processes. Since Chromium does not support 64 bit builds at the moment, CEF binaries will also be 32 bit bound. Hence, a 64 bit application will not be able to link directly with CEF. The HTML rendering could, however, be isolated in a 32 bit process without any UI, thanks to offscreen rendering. The rendered HTML results could then be passed through a bridge back to the 64 bit application, and drawn inside UI objects belonging to it.
We plan on contributing the IME functionality for offscreen rendering on Mac. Since implementing offscreen rendering overrides some of the internal Content API implementations, IME needs to be fitted to work without the native window it was bound to.
We are also working on setting up an automated build infrastructure for CEF. This will build CEF regularly, run the unit tests, and post the builds at a public location. We are still ironing out the details on this project (nightly builds vs change by change builds, branches vs trunk etc.).
To Sum Up
If you need a simple, cross-platform way to display HTML content in your desktop application, CEF may be exactly what you’re looking for. It is open and has a healthy community behind it, as also shown by all the applications that are using it.