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:

  1. Sizing and Layout: Determining where it and its child views sit on the screen.
  2. Event Handling: Responding to mouse clicks, touches, and keystrokes.
  3. 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 from Button, which inherits from View).
  • 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 Label view.
  • It generates "OK" and "Cancel" buttons using MdTextButton views (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:

  1. Window Creation: MenuRunner spawns a temporary, borderless popup Widget at the cursor's location.
  2. Menu Hierarchy: A SubmenuView is placed inside this popup window. It acts as a container for a vertical stack of MenuItemView objects.
  3. Custom Painting: Each MenuItemView calculates the space needed for its text label, keyboard shortcut text, and checkmark icon. It then paints these elements directly onto the popup's canvas.
  4. State Management: A singleton class called MenuController takes over mouse and keyboard capture. As you move your mouse down the menu, the MenuController tracks the coordinates, tells the previously hovered MenuItemView to repaint itself with a normal background, and tells the newly hovered MenuItemView to repaint itself with a highlighted background. If a submenu is triggered, it simply spawns another popup Widget next to the current one.