Chromium Developer Documentation

Google Chrome is built with open source code from Chromium.

Except as otherwise noted, the content of this page is licensed under a Creative Commons Attribution 2.5 license, and examples are licensed under the BSD License.

ChromeViews

Overview and background

Windows provides very primitive tools for building user interfaces. The system provides a few basic controls and native window containers, but building a custom user interface is difficult. Since we desired a differentiated aesthetic for Chromium, we have had to build a framework on Windows to accelerate our development of custom UI. This system is called ChromeViews. 

ChromeViews is a rendering system not unlike that used in WebKit or Gecko to render web pages. The user interface is constructed of a tree of components called Views. These Views are responsible for rendering, layout, and event handling. Each View in the tree represents a different component of the UI. An analog is the hierarchical structure of an HTML document.

At the root of a View hierarchy is a Container, which is a native window. The native window receives messages from Windows, converts them into something the View hierarchy can understand, and then passes them to the RootView. The RootView then begins propagation of the event into the View hierarchy.

Painting and layout are done in a similar way. A View in the View tree has its own bounds (often imbued upon it by its containing View's Layout method), and so when it is asked to Paint, it paints into a canvas clipped to its bounds, with the origin of rendering translated to the View's top left. Rendering for the entire View tree is done into a single canvas set up and owned by the Container when it receives a Paint message. Rendering itself is done using a combination of Skia and GDI calls — GDI for text and Skia for everything else. For WebKit or Gecko developers, the analog of a View can be thought of as a RenderObject or nsFrame respectively, and a Container Widget or nsWidget respectively.

Chromium has several Container implementations for various purposes, but over time it would be ideal to standardize on just one, with specializations for different kinds of windows. (The most generic case is child control; the most specific case is when custom high-level pieces of UI need to respond to particular Windows messages to implement their desired functionality.) Since these objects are the View system's interface to the operating system, they are not especially portable.

Several UI controls in Chromium's UI are not rendered using Views, however. Rather, they are native Windows controls hosted within a special kind of View that knows how to display and size a native widget. These are used for buttons, tables, radio buttons, checkboxes, text fields, and other such controls. Since they use native controls, these Views are also not especially portable, except perhaps in API.

Barring platform-specific rendering code, code that sizes things based on system metrics, and so on, the rest of the View system is not especially unportable, since most rendering is done using the cross-platform Skia library. For historical reasons, many of View's functions take Windows or ATL types, but we have since augmented base/gfx with many platform independent types that we can eventually replace these with.

Code Location and Info

The base set of classes and interfaces provided by ChromeViews can be found in the src/chrome/views directory. All base ChromeViews classes are in the "views" namespace.

Containers you might encounter

  • ContainerWin: The base class for most Containers in ChromeViews. Provides a basic child window control implementation. Subclass this directly if you are not making a top-level window or dialog.
  • Window: A top-level window with a native (Windows-provided) non-client frame. A subclass of ContainerWin.
  • CustomFrameWindow: A subclass of Window that does custom non-client rendering, used on Windows XP. Note: Do not use this or Window directly, instead create a Window using Window::CreateChromeWindow. This will ensure you get the most appropriate frame for Windows XP or Vista.
  • OpaqueFrame and AeroGlassFrame: The contains used to represent the Browser Window.
  • Deprecated: XPFrame: Contains the contents of the main browser window on Windows XP and Windows Vista when DWM compositing is not enabled. Not a subclass of ContainerWin, though eventually this will be desirable (via CustomFrameWindow). The entire window is client area; non-client area is faked using a View.
  • Deprecated: VistaFrame: Contains the contents of the main browser window on Windows Vista when DWM compositing is enabled. Uses a native non-client frame to make use of Aero's glass capabilities. Also not a subclass of ContainerWin; again it will be desirable to make it one eventually, probably via Window.

Other approaches

At the start of the project, we began building the Chromium browser using native windows and the owner-draw approach used in many Windows applications. This proved to be unsatisfactory, since native windows don't support transparency natively, and handling events requires tedious window subclassing. Some early UI elements gravitated towards custom painting and event handling, but this was very ad-hoc based on the circumstance.

Existing UI toolkits for Windows are similarly unsatisfying, with limited widget sets, unnatural aesthetics, or awkward programming models.

Limitations/issues

By and large, ChromeViews makes it relatively easy to build complex custom UIs. However it has a few rough edges that can be improved over time:

  • The Event types currently are occasionally problematic - they crack the native windows message parameters and then discard them. Sometimes this information is useful.
  • Some ad-hoc message processing.
  • Mix of native controls that don't work properly until inserted into a View hierarchy attached to a Container with a valid HWND. Many of our native controls have API methods that require them to exist within a window hierarchy. This means that they cannot be fully initialized until they are inserted.
  • No common pattern for initialization following view insertion. It'd be good if the WindowDelegate, View or some other aspect of the framework would advocate for a clear path here.
  • The Container interface is a bit weak and frozen in time somewhat. It should be reviewed and improved.

  Sign in   Home   Sitemap   Terms   Report Abuse   Print  |  Powered by Google Sites