Skip to main content

Module devtools

Module devtools 

Source
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. guise never opens a socket, so the host calls log, network_begin, storage_set and friends, exactly as crate::ai displays 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: value line in the Styles sidebar.
DevTools
The inspector. Create with cx.new(|cx| DevTools::new(cx)).
DevToolsState
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. count is 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.
NetworkRecord
One network request.
Probe
A component’s root element, tagged for the Elements panel. Built by Probed::probe.
ProbeNode
One recorded element: a row in the Elements tree.
ProbeTree
A recorded tree: a flat arena plus its roots, in the order they prepainted.
SourceRef
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.
StorageDomain
A named collection of storage rows, listed in the Storage panel’s sidebar.
StorageEntry
One row in a storage domain.
TimelineEvent
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§

DevToolsEvent
What the inspector asks the host to do. Everything it can do alone, it does alone; these are the things that need the host.
DevToolsTab
The tools along the top, in Safari’s order.
Dock
Where the host has put the inspector. guise cannot move a panel it does not own, so this only sets which dock button reads as pressed — the host acts on DevToolsEvent::Dock.
ElementsSidebar
The sidebar tabs, in Safari’s order.
LogLevel
Log severity. Mirrors the levels Safari’s console filters by.
RequestState
How far along a request is. A record starts Pending and the host settles it later by id — the inspector shows the row the whole time, as Safari does.
ResourceKind
What kind of resource a request fetched. Drives the Network panel’s type filter and the waterfall color, exactly as in Safari.
StorageKind
What a storage domain holds. Only affects the icon and the sidebar grouping.
TimelineKind
A band on the Timelines panel.

Traits§

Probed
Tag any element as a component for the Elements panel.
ProbedAny
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’s render, 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 #rrggbbaa when 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 f and 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; None means 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 retain and release instead.
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 f against the current tree without cloning it — for a host that wants to inspect the tree without paying for a copy of it.