Chromium Views: Building UI Without Native OS Controls
Chromium's Views framework bypasses native operating system controls to deliver a consistent, hardware-accelerated, and highly customizable user interface across platforms. This article provides a look into how the Views architecture leverages a single native window, the Skia graphics library, and a hierarchical tree of custom C++ objects to construct, layout, and render its own toolbars, dialogs, and menus entirely from scratch.
The Core Architecture: Widgets and Views
To avoid using native OS buttons, text boxes, or menus, Chromium
reduces its reliance on the host operating system to the bare minimum.
It requests only a blank, top-level rectangular window from the OS. In
the Views framework, this native window is wrapped by an object called a
Widget.
Inside the Widget, the entire user interface is
constructed using a tree of View objects. A
View is not a native OS control; it is a lightweight C++
class that represents a specific rectangular region within the
Widget. The View class is responsible for
three main tasks:
- Sizing and Layout: Determining where it and its child views sit on the screen.
- Event Handling: Responding to mouse clicks, touches, and keystrokes.
- Painting: Drawing its visual representation onto a canvas.
Rendering and Event Routing
Because the operating system has no awareness of the buttons or menus inside the blank window, Chromium must handle all rendering and input routing internally.
Rendering: When a View needs to appear
on screen, the framework calls its OnPaint() method.
Instead of asking the OS to draw a button, the View issues
drawing commands—such as drawing lines, shapes, and text—to a
gfx::Canvas. This canvas is powered by Skia, Chromium’s 2D
graphics engine, alongside Chromium's compositor. The UI is drawn
directly using the GPU, just like a webpage.
Input Routing: When a user clicks the mouse, the OS
only knows that the top-level window was clicked. The
Widget receives this raw OS event and passes it to the
RootView. The RootView then traverses the tree
of View objects, checking their coordinates to find which
specific View is directly under the cursor, and delivers
the click event to that object.
Constructing Toolbars
In Chromium, the main browser toolbar is built using a container
class called ToolbarView. Because there are no native OS
layout engines involved, ToolbarView uses a custom
LayoutManager (specifically, FlexLayout) to
automatically calculate the positions and sizes of its child elements
when the browser window is resized.
The children of the ToolbarView are simply other
specialized View subclasses:
- Buttons: The Back, Forward, and Reload buttons are
instances of
ToolbarButton(which inherits fromButton, which inherits fromView). - Icons: Instead of using bitmap images or OS icons, buttons render their icons using mathematical paths via Chromium's vector icon system.
- Animations: When you hover over or click a toolbar
button, the ink-drop ripple effect is calculated and drawn
frame-by-frame by a compositor animation layer attached to that specific
View.
Constructing Dialogs
When Chromium displays a prompt—such as the "Bookmark Added" bubble
or the "Clear Browsing Data" modal—it does not invoke native OS dialog
APIs. Instead, it uses DialogDelegateView or
BubbleDialogDelegateView.
To show a dialog, Views creates a new, secondary Widget
(a blank, frameless OS window) and positions it over the main browser
window. Inside this blank window, a DialogClientView is
inserted. This view automatically constructs the dialog's internal
anatomy using standard View components:
- It creates a title area using a custom
Labelview. - It generates "OK" and "Cancel" buttons using
MdTextButtonviews (Material Design text buttons). - It draws the dialog's rounded corners, borders, and drop shadows directly onto the transparent window canvas using Skia.
Constructing Menus
Native OS menus are notoriously difficult to style and animate
consistently across Windows, Linux, and ChromeOS. Chromium bypasses them
using a combination of MenuRunner,
MenuController, and MenuItemView.
When you right-click a webpage or click the three-dot browser menu, the following happens:
- Window Creation:
MenuRunnerspawns a temporary, borderless popupWidgetat the cursor's location. - Menu Hierarchy: A
SubmenuViewis placed inside this popup window. It acts as a container for a vertical stack ofMenuItemViewobjects. - Custom Painting: Each
MenuItemViewcalculates the space needed for its text label, keyboard shortcut text, and checkmark icon. It then paints these elements directly onto the popup's canvas. - State Management: A singleton class called
MenuControllertakes over mouse and keyboard capture. As you move your mouse down the menu, theMenuControllertracks the coordinates, tells the previously hoveredMenuItemViewto repaint itself with a normal background, and tells the newly hoveredMenuItemViewto repaint itself with a highlighted background. If a submenu is triggered, it simply spawns another popupWidgetnext to the current one.