Skip to content

Application and root services API

Declared by <huxerui/app.h> and <huxerui/root.h>. The host implementation interface is isolated in <huxerui/platform_adapter.h>.

  • RootFactory is View (*)().
  • Application(root_factory, AppOptions = {}) stores an immutable root and options.
  • AppOptions contains WindowOptions window, ViewportBreakpoints, debug-overlay default, and std::vector<RootHook> root_hooks.
  • RunApplication() launches the application declaration supplied by the generated platform entry.
  • LaunchActivation, UrlActivation{Uri url}, FileActivation{files}, and NotificationActivation{identifier, data} form ApplicationActivation.
  • ApplicationLifecycleState: Active, Inactive, Background.
  • UseApplication() -> ApplicationHandle.
  • StartupActivation() returns the runtime’s initial activation.
  • LifecycleState() reads observable current state.
  • OnLifecycleChange(handler, dependencies...) and OnActivation(handler, dependencies...) register scoped listeners.

RootHook receives RootContext&. RootContext::Provide(shared_ptr<Service>) installs exactly one service per type; Layers() exposes LayerController; RegisterPlatformModule and RegisterPlatformView install typed platform factories. UseService<Service>() resolves an installed root service.

Resolve FilePicker and HttpClient with UseService<T>(). Access clipboard and directories directly through ApplicationHandle; they are not application-resolved root services.

PlatformAdapter is the platform implementation interface for frame scheduling, time, text layout, rendering, input services, resources, activation, lifecycle, files, HTTP, process metrics, system UI, and platform integration. Applications do not subclass it.

Runtime owns composition, reconciliation, layout, interaction, semantics, animation, layers, and RenderScene generation for one adapter. Its public methods support platform hosts and focused framework extensions. ProcessMetrics carries cumulative CPU time, memory footprint, and processor count.

Surface Intended caller Lifetime and constraints
Application, AppOptions, UseApplication Application code One immutable application declaration; captured handles remain safe after Runtime destruction; each operation defines its disconnected behavior.
RootHook, RootContext, UseService<T> Application extensions Hooks run before root composition. UseService<T>() returns the installed std::shared_ptr<T> or throws std::logic_error.
PlatformAdapter, Runtime, FrameCommit Repository or custom platform hosts UI-thread adapter boundary, not an ordinary component API. One Runtime belongs to one adapter and host view.
RunApplication Generated native entry Uses the application declaration supplied by the platform shell.

Empty lifecycle/activation handlers and duplicate or empty service installation are rejected with std::invalid_argument or std::logic_error. Application code should not instantiate Runtime, subclass PlatformAdapter, or depend on huxerui::detail.

Permission currently covers Camera and Microphone. ApplicationHandle::CheckPermissionAsync reads current authorization; RequestPermissionAsync requests it from a user-driven workflow. Both return Task<PermissionStatus>.

Statuses are NotDetermined, Granted, Denied, PermanentlyDenied, Restricted, Unavailable, and Provisional. Provisional is reported only by capabilities with explicit provisional authorization, such as notifications. Do not equate Denied with “can ask again”: some hosts cannot reliably distinguish that. Platform manifests/usage descriptions remain mandatory; the API cannot add them at runtime.

#include <huxerui/huxerui.h>
using namespace huxerui;
[[huxerui::composable]]
View EnableCamera() {
auto application = UseApplication();
auto tasks = UseTaskScope();
auto status = UseState(PermissionStatus::NotDetermined);
const PermissionStatus authorization = status;
return Column {
Text(authorization == PermissionStatus::Granted ? "Camera allowed" : "Camera not enabled"),
Button("Enable camera").OnClick([application, tasks, status] {
tasks.Launch([application, status]() -> Task<void> {
status = co_await application.RequestPermissionAsync(Permission::Camera);
});
}),
};
}

Request only when the user starts the feature. OpenPermissionSettingsAsync(permission) returns whether the settings launch was accepted, not whether permission became granted; check again on return. Unsupported hosts or missing app declarations can report Unavailable.

Clipboard() noexcept returns the same non-null std::shared_ptr<huxerui::Clipboard> on every call. Check IsAvailable() and the result of each read/write; operations are synchronous on the owning UI thread. A retained clipboard reports unavailable after Runtime destruction. The accessor itself does not need active composition.

Directories() returns const AppDirectories& without I/O. It is valid while the handle or Runtime retains its service; copy paths for independent ownership. It throws std::logic_error when directories are unavailable. CurrentDirectory() queries the process working directory, not a cached application location, and throws std::runtime_error if that query fails. Both accessors work outside composition; captured directory values remain available after Runtime destruction.

#include <huxerui/huxerui.h>
using namespace huxerui;
[[huxerui::composable]]
View CopyTitle(std::string title) {
auto clipboard = UseApplication().Clipboard();
auto status = UseState(std::string{});
return Column {
Button("Copy title").With(Enabled(clipboard->IsAvailable())).OnClick([clipboard, title, status] {
status = clipboard->WriteText(title) ? "Copied" : "Clipboard unavailable";
}),
Text(status),
};
}

LocalNotifications() captures the current composition Environment and returns a LocalNotificationHandle. Use it for system-delivered notifications rather than in-window feedback. See Local notifications for authorization, scheduling, activation, and required platform configuration; System API lists the contracts.

ApplicationHandle::SystemTray() returns a composition-owned SystemTrayHandle. IsAvailable() is observable; Show(icon, SystemTrayOptions) supplies a tooltip and platform menu. The image must resolve to an ImageAsset. There is at most one active tray presentation per Runtime.

Use Lifecycle to show/hide and OnActivate(handler, dependencies...) for primary activation. Hiding only affects the owning handle’s presentation. Keep commands in ordinary application policy; closing a window is not necessarily the same operation as ApplicationHandle::Quit().

A tray is a platform capability, not a portable substitute for mobile background execution. See window and system UI for a lifecycle example.