Desktop field Plate 28 Route §28
Plate 28

The workspace

A home screen where you choose, and a workspace where you work. The two-scope shape, and the one that is worth understanding before you change anything.

AppState is provided by the root and lives for the whole process. WorkspaceState is provided by the workspace view and lives only while a project is open — its entries, its selection, its active tab.

The root drops the workspace entity when the route goes home. That is what stops a closed project's state leaking into the next one, and what stops an in-flight load landing in a view that has moved on. Settings stay at the root, because ⌘, has to work on the home screen too.

What you are carrying

model

The project, and what a project contains.

store

Projects on disk, one JSON document.

host

Owns the active-project cursor, not the UI.

app

Home ⇄ workspace routing, two state scopes.

Start it

scripts/new.sh Acme ~/Dev/acme --template workspace

What it looks like

crates/app/src/root.rsrust
match self.state.route.get(cx) {
    Route::Home => {
        // Dropping the entity here is what stops a closed project's signals
        // and in-flight loads from outliving it.
        self.workspace = None;
        div().size_full().child(self.home.clone())
    }
    Route::Workspace(id) => match self.state.host.active().filter(|p| p.id == id) {
        Some(project) => div().size_full().child(self.workspace_for(project, cx)),
        // The route says open and the host disagrees. An empty workspace
        // would strand the user, so fall back rather than render nothing.
        None => { self.state.route.set(cx, Route::Home); div().size_full().child(self.home.clone()) }
    },
}

Read next

Desktop architecture Scaffolding
Type to search guides and package references.