Skip to main content

fenestra_shell/
lib.rs

1//! OS glue for fenestra: the winit + wgpu windowed runner and the headless
2//! renderer. Everything that touches a display server lives here;
3//! `fenestra-core` and `fenestra-kit` stay windowless.
4
5use std::fmt;
6
7// Headless rendering, GPU readback, the OS clipboard, and the AccessKit
8// adapter are native-only; on the web only the windowed (canvas) runner
9// exists. `fenestra-core` and `fenestra-kit` compile everywhere.
10#[cfg(not(target_arch = "wasm32"))]
11mod access;
12#[cfg(not(target_arch = "wasm32"))]
13mod blur;
14#[cfg(not(target_arch = "wasm32"))]
15mod element_render;
16#[cfg(not(target_arch = "wasm32"))]
17mod embed;
18#[cfg(not(target_arch = "wasm32"))]
19mod harness;
20#[cfg(not(target_arch = "wasm32"))]
21mod headless;
22#[cfg(not(target_arch = "wasm32"))]
23mod multi_pass;
24#[cfg(not(target_arch = "wasm32"))]
25mod os_clipboard;
26#[cfg(not(target_arch = "wasm32"))]
27mod reduce_motion;
28#[cfg(not(target_arch = "wasm32"))]
29mod scenario;
30#[cfg(not(target_arch = "wasm32"))]
31mod synthetic;
32#[cfg(not(target_arch = "wasm32"))]
33pub mod testing;
34mod window;
35
36#[cfg(not(target_arch = "wasm32"))]
37pub use blur::{apply_element_filter, box_blur_rgba8};
38#[cfg(not(target_arch = "wasm32"))]
39pub use element_render::{
40    render_element, render_element_over, render_element_with, render_element_with_state,
41    with_fonts, with_headless,
42};
43#[cfg(not(target_arch = "wasm32"))]
44pub use embed::{Embedded, EventResponse};
45#[cfg(not(target_arch = "wasm32"))]
46pub use harness::{Harness, MAX_FILM_FRAMES, MAX_FILM_INTERVAL_MS};
47#[cfg(not(target_arch = "wasm32"))]
48pub use headless::Headless;
49#[cfg(not(target_arch = "wasm32"))]
50pub use multi_pass::process_specs;
51#[cfg(not(target_arch = "wasm32"))]
52pub use os_clipboard::OsClipboard;
53#[cfg(not(target_arch = "wasm32"))]
54pub use scenario::{ScenarioError, ScenarioReport, run_scenario};
55#[cfg(not(target_arch = "wasm32"))]
56pub use synthetic::{SyntheticEvent, render_app};
57pub use window::{WindowOptions, run_app};
58
59// Re-exports for embedders: integration code must use the same wgpu and
60// winit versions fenestra was built with (the egui-wgpu convention).
61pub use vello;
62pub use vello::wgpu;
63#[cfg(not(target_arch = "wasm32"))]
64pub use window::{run_scene, run_static};
65pub use winit;
66
67/// Errors from the windowed or headless runners.
68#[derive(Debug)]
69pub enum ShellError {
70    /// No compute-capable wgpu adapter was found.
71    NoDevice,
72    /// The vello renderer failed to build or render.
73    Vello(vello::Error),
74    /// The winit event loop failed.
75    EventLoop(winit::error::EventLoopError),
76    /// GPU readback of the rendered image failed.
77    Readback,
78}
79
80impl fmt::Display for ShellError {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        match self {
83            Self::NoDevice => write!(f, "no compute-capable wgpu adapter found"),
84            Self::Vello(e) => write!(f, "vello renderer error: {e}"),
85            Self::EventLoop(e) => write!(f, "winit event loop error: {e}"),
86            Self::Readback => write!(f, "GPU readback failed"),
87        }
88    }
89}
90
91impl std::error::Error for ShellError {}