Expand description
DevTools — Safari’s Web Inspector, for a gpui app.
The Web Inspector’s layout is doing real work: a tab bar of tools rather than a stack of panels, a tree beside a details sidebar, a console that drops down over whatever else you were looking at. This module reproduces that — Elements, Network, Sources, Timelines, Storage, Layers, Logs and Audit — against a native app instead of a page.
Where the data comes from differs by panel, and that difference is the whole design:
-
Elements, Layers and the Styles sidebar are real introspection. Components tag their root with
Probed::probe, so the tree, the bounds, and the style declarations are read back out of what actually rendered this frame. -
Logs, Network, Storage and Timelines are reported.
guisenever opens a socket, so the host callslog,network_begin,storage_setand friends, exactly ascrate::aidisplays a conversation it does not conduct.Safari’s equivalent tab is the Console, and it is called Logs here for a reason: half of that tab is a JavaScript evaluator, and a compiled binary has nothing to evaluate. A prompt that cannot run anything is worse than no prompt, so the panel is named for the half that does transfer.
-
Audit is computed here, from the tree, against the library’s own conventions.
// once at startup
DevToolsState::new().init(cx);
// wherever the inspector should live — a pane, a drawer, its own window
let devtools = cx.new(|cx| DevTools::new(cx));
// and from anywhere in the app
guise::devtools::log(cx, LogLevel::Warning, "cache miss");Nothing here is compiled out of release builds, because dead-code
elimination already handles that: an app that never constructs DevTools
links none of it. What an app does pay for is the Probed::probe calls
left in components, and those are a single boolean check while the
inspector is closed.
Structs§
- BoxModel
- The four nested boxes of the Computed sidebar’s diagram. Every value is in pixels, already resolved against the rem size, so the diagram can label itself with numbers rather than units.
- Declaration
- One
property: valueline in the Styles sidebar. - DevTools
- The inspector. Create with
cx.new(|cx| DevTools::new(cx)). - DevTools
State - Everything the inspector displays, and the only mutable state it owns.
- Limits
- How many records each store keeps before evicting the oldest.
- LogRecord
- One log line.
countis the repeat tally: Safari collapses identical consecutive messages into a single row with a counter rather than scrolling the useful history away, and so do we. - Network
Record - One network request.
- Probe
- A component’s root element, tagged for the Elements panel. Built by
Probed::probe. - Probe
Node - One recorded element: a row in the Elements tree.
- Probe
Tree - A recorded tree: a flat arena plus its roots, in the order they prepainted.
- Source
Ref - Where a record came from in the source. Built from a gpui element’s
#[track_caller]location, or supplied by the host for its own records. - Storage
Domain - A named collection of storage rows, listed in the Storage panel’s sidebar.
- Storage
Entry - One row in a storage domain.
- Timeline
Event - One span on a timeline band.
- Timings
- The phase breakdown behind the waterfall bar. Each field is the time spent in that phase, not a timestamp, so a partially-complete request is just one with later phases still zero.
Enums§
- DevTools
Event - What the inspector asks the host to do. Everything it can do alone, it does alone; these are the things that need the host.
- DevTools
Tab - The tools along the top, in Safari’s order.
- Dock
- Where the host has put the inspector.
guisecannot move a panel it does not own, so this only sets which dock button reads as pressed — the host acts onDevToolsEvent::Dock. - Elements
Sidebar - The sidebar tabs, in Safari’s order.
- LogLevel
- Log severity. Mirrors the levels Safari’s console filters by.
- Request
State - How far along a request is. A record starts
Pendingand the host settles it later by id — the inspector shows the row the whole time, as Safari does. - Resource
Kind - What kind of resource a request fetched. Drives the Network panel’s type filter and the waterfall color, exactly as in Safari.
- Storage
Kind - What a storage domain holds. Only affects the icon and the sidebar grouping.
- Timeline
Kind - A band on the Timelines panel.
Traits§
- Probed
- Tag any element as a component for the Elements panel.
- Probed
Any - The same, for an element that has no style of its own.
Functions§
- begin_
frame - Promote the tree the last frame recorded and start a fresh one, claiming
this frame for
window. Called from the inspector’srender, which runs before any of this frame’s prepaints, so elements in every other window this thread draws are skipped for the rest of the frame. - box_
model - Resolve the box model for an element, given the bounds it was laid out at.
- clear
- Drop every record.
- declarations
- Every declaration the refinement actually sets, in CSS authoring order: layout, then box, then flex, then visual, then text.
- format_
bytes - Format a byte count the way Safari’s size columns do.
- format_
duration - Format a duration the way Safari’s timing columns do: sub-millisecond work still reads as a number, and anything past a second switches unit.
- format_
timestamp - Elapsed time as the log’s timestamp column shows it.
- hex
#rrggbb, or#rrggbbaawhen the color is not fully opaque — the notation Safari’s color swatches label themselves with.- is_
recording - Whether the element recorder is running, for a host that wants to skip its own instrumentation while the inspector is closed.
- log
- Append a log line, stamped with the source location it was called from.
- log_
record - Append a fully-built log record — the form to use when the line has expandable detail rows.
- measure
- Time
fand record it as a Script span. The return value is passed through, so this wraps an existing call without restructuring it. - network_
begin - Record a request that has just started. The returned id settles it later;
Nonemeans the inspector is not installed and nothing was recorded. - network_
update - Amend a request in flight.
- set_
enabled - Turn recording on or off outright, ignoring how many inspectors are alive.
For a host driving the recorder by hand, and for tests; an inspector uses
retainandreleaseinstead. - storage_
remove - Remove a storage domain.
- storage_
set - Publish a storage domain, replacing any previous snapshot of it.
- timeline_
event - Record a span on a timeline band.
- tree
- The most recently completed tree.
- with_
tree - Run
fagainst the current tree without cloning it — for a host that wants to inspect the tree without paying for a copy of it.