enum LavaApp
Swift
enum LavaApp
Reusable window/input/invalidation/render loop, so a second LavaUI
executable is a main.swift of a dozen lines instead of a copy of
HelloWorldApp's ~350.
Split into open + run because asset loading a specific app owns
(an app icon, a brand image) has to happen once, against an already-open
Editor, before the first makeRoot() — folding it into run's hot path
would either re-load it every rebuild or force every caller to thread a
cache through their own view. Two calls keeps that ordering explicit:
guard let editor = LavaApp.open(title: "My App") else { exit(1) }
let icon = ImageStore.loadAsset(
named: "icon.png", bundle: .module, into: editor)
LavaApp.run(editor: editor) { MyRootView(icon: icon) }
Sources/LavaUI/LavaApp.swift:20
Properties
static var currentWindow: WindowID { get }
The window whose frame is being built or whose handler is running.
Ambient rather than passed down, for the reason WindowScope gives at
length: a view genuinely does not know which window it is in, and every
view in a tree would have to thread the answer through to the one place
that wants it. Outside a frame this is the first window.
Sources/LavaUI/LavaApp.swift:318
static var mainLayoutHost: LayoutHost? { get }
The layout host of the window the app started with, once run has
brought it up. Nil before that, and after teardown.
For the app that has to know how big the tree it just laid out actually
is — agentFrame(sid:) on a committed layout answers it. A context
menu is the case this exists for: it has to tell the compositor its
size before the compositor will place it, and the only honest source
for that number is the layout pass, not a second pile of font
arithmetic that agrees with Yoga until a face changes.
Everything else about a window's geometry is told to the app. This is the one question that runs the other way.
Sources/LavaUI/LavaApp.swift:242
static var windowCount: Int { get }
Not documented.
Sources/LavaUI/LavaApp.swift:228
Methods
static func closeCurrentWindow()
Closes the window this handler is running in. What a "Close" button in a secondary window wants, without the window having to know its own id.
Sources/LavaUI/LavaApp.swift:322
static func closeWindow(_ id: WindowID)
Closes a window this app opened. Closing the window the app started
with ends run, the same as its titlebar X.
Takes effect at the end of the current frame, so it is safe from a handler running inside that window's own tree.
Sources/LavaUI/LavaApp.swift:299
static func isWindowOpen(_ id: WindowID) -> Bool
Whether id is still open.
Sources/LavaUI/LavaApp.swift:308
static func open(title: String, assetsRoot: String? = nil, width: Float = 1280, height: Float = 800) -> Editor?
Opens the window and does one-time framework setup: default font
bootstrap, clipboard bridge. Logs and returns nil if the window
failed to open — the caller should exit(1).
assetsRoot- Engine resource root (directory with
shaders/). Default is the SwiftPMCanvasResourcesbundle. Fonts always load from LavaUI's own resource bundle.
Sources/LavaUI/LavaApp.swift:28
@discardableResult static func openWindow<V>(title: String, width: Float = 800, height: Float = 600, onClose: (() -> Void)? = nil, makeRoot: @escaping () -> V) -> WindowID? where V : View
Opens a second window running its own view tree, sharing this process's GPU, font atlas, texture cache and frame loop.
Safe to call from a button handler: the window is created immediately but brought up at the end of the current frame, so it never draws against a half-updated tree, and the caller's own window still presents the frame the click belongs to.
The new window gets its own focus, invalidation and hover state (see
WindowScope) and the app-level onRawKey from run. It does not
get the menubar: a second menubar strip is a decision for the app, not
a default, and the DBus global menu is registered per process.
Returns nil if the engine could not open it, or if called before
run.
Sources/LavaUI/LavaApp.swift:260
static func resolveAssetsRoot(_ override: String? = nil) -> String
Back-compat alias — engine root only. App images should use
ImageStore.loadAsset(named:bundle:into:) with the app bundle.
Sources/LavaUI/LavaApp.swift:82
static func resolveEngineAssetsRoot(_ override: String? = nil) -> String
Engine assets root: override, else CANVAS_ASSETS_ROOT, else the
CanvasResources SwiftPM bundle (checked-in SPIR-V under shaders/).
Sources/LavaUI/LavaApp.swift:75
static func run<V>(editor: Editor, menu: (() -> MenuBar)? = nil, onRawKey: ((InputEvent) -> Bool)? = nil, makeRoot: @escaping () -> V) where V : View
Runs the full input/invalidation/render/agent-server loop until the window closes.
Drives every open window, not just this one: openWindow adds a
second tree to the same loop, and one GLFW wait serves all of them, so
N windows cost N draw arenas rather than N event loops. The app ends
when the window opened here closes; secondary windows come and go under
it. See LavaWindow for the per-window half and WindowScope for what
each window owns privately.
makeRoot: rebuilds the view tree from scratch. Called on the first frame and on any invalidation that can't be satisfied per-node (seeViewInvalidation.consumeDirtyBodyNodes) — keep it cheap, an app's own one-time setup belongs before this call, against theEditoropenalready returned.menu: optional application menubar. When a global-menu registrar is available (Vala Panel / Plasma appmenu / …), the tree is exported via DBusMenu and no in-window strip is drawn. OtherwiseMenuChromeRootdraws it with Vulkan. Override withLAVA_MENU=vulkanordbus. Rebuilt on every full body pass so labels/isEnabledstay in sync. Menu shortcuts are matched afteronRawKey(both backends).onRawKey: first look at every key event, ahead of focus/overlay/ content-scale handling. Returntrueto consume it.
Sources/LavaUI/LavaApp.swift:109