gpui_web: Let applications provide fonts (#63493)

`gpui_web` currently embeds IBM Plex Sans and Lilex into every browser
application during platform construction. Applications such as Delta
already provide their own fonts, so those binaries contain overlapping
font bundles and register the same faces twice.

This change starts the web platform with an empty font database,
matching the ownership boundary used by native applications: the
application selects and registers its fonts before opening a window.
Delta already follows that sequence. GPUI's browser-capable examples now
load the former eight-face bundle explicitly through shared example
support, while the standalone `hello_web` example demonstrates
registering a minimal application font directly.

Testing performed:

- `cargo check -p gpui --examples --target wasm32-unknown-unknown`
- `cargo check -p gpui --examples`
- `cargo check -p gpui_web --target wasm32-unknown-unknown`
- `cargo check --manifest-path
crates/gpui_web/examples/hello_web/Cargo.toml --target
wasm32-unknown-unknown`
- `./script/clippy -p gpui_web --target wasm32-unknown-unknown`
- `cargo fmt -p gpui -p gpui_web --check`

Release Notes:

- N/A
This commit is contained in:
Lukas Wirth authored and GitHub committed 2026-08-31 13:07:22 +00:00
1 parent adc72a5a49
commit ef075910c9
47 files changed
+312 -20

No files matched your search

Generated
+1
View File
@@ -7573,6 +7573,7 @@ dependencies = [
"uuid",
"waker-fn",
"wasm-bindgen",
"web-sys",
"web-time",
"windows 0.61.3",
"zed-font-kit",
+1
View File
@@ -149,6 +149,7 @@ reqwest_client = { workspace = true, features = ["test-support"] }
[target.'cfg(target_family = "wasm")'.dev-dependencies]
wasm-bindgen = { workspace = true }
web-sys = { version = "0.3", features = ["console"] }
[build-dependencies]
embed-resource = { version = "3.0", optional = true }
+6
View File
@@ -30,6 +30,9 @@
//! - "2. Run tests"
//! - "3. Ship it"
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
AccessibleAction, App, Bounds, Context, FocusHandle, KeyBinding, Role, SharedString, Toggled,
Window, WindowBounds, WindowOptions, actions, div, prelude::*, px, rgb, size, text,
@@ -226,6 +229,9 @@ impl Render for A11yDemo {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.bind_keys([
KeyBinding::new("tab", Tab, None),
KeyBinding::new("shift-tab", TabPrev, None),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
Anchor, AnchoredPositionMode, App, Axis, Bounds, Context, Half as _, InteractiveElement,
ParentElement, Pixels, Point, Render, SharedString, Size, Window, WindowBounds, WindowOptions,
@@ -168,6 +171,9 @@ impl Render for AnchorDemo {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::time::Duration;
use anyhow::Result;
@@ -306,6 +309,9 @@ impl Render for AnimationExample {
fn run_example() {
application().with_assets(Assets {}).run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let options = WindowOptions {
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
None,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::{ops::Range, rc::Rc, time::Duration};
use gpui::{
@@ -451,6 +454,9 @@ impl Render for DataTable {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(
WindowOptions {
focus: true,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Half, Hsla, Pixels, Point, Window, WindowBounds, WindowOptions, div,
prelude::*, px, rgb, size,
@@ -125,6 +128,9 @@ impl Render for DragDrop {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(800.), px(600.0)), cx);
cx.open_window(
WindowOptions {
@@ -0,0 +1,44 @@
#[cfg(target_family = "wasm")]
use std::borrow::Cow;
use gpui::App;
#[cfg(target_family = "wasm")]
pub fn load_fonts(cx: &App) -> bool {
let fonts = [
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Regular.ttf")
.as_slice(),
),
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Italic.ttf")
.as_slice(),
),
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/ibm-plex-sans/IBMPlexSans-SemiBold.ttf")
.as_slice(),
),
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/ibm-plex-sans/IBMPlexSans-SemiBoldItalic.ttf")
.as_slice(),
),
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/lilex/Lilex-Regular.ttf").as_slice(),
),
Cow::Borrowed(include_bytes!("../../../../assets/fonts/lilex/Lilex-Bold.ttf").as_slice()),
Cow::Borrowed(include_bytes!("../../../../assets/fonts/lilex/Lilex-Italic.ttf").as_slice()),
Cow::Borrowed(
include_bytes!("../../../../assets/fonts/lilex/Lilex-BoldItalic.ttf").as_slice(),
),
];
if let Err(error) = cx.text_system().add_fonts(fonts.into()) {
web_sys::console::error_1(&format!("failed to load application fonts: {error:#}").into());
return false;
}
true
}
#[cfg(not(target_family = "wasm"))]
pub fn load_fonts(_cx: &App) -> bool {
true
}
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Div, ElementId, FocusHandle, KeyBinding, SharedString, Stateful, Window,
WindowBounds, WindowOptions, actions, div, prelude::*, px, size,
@@ -196,6 +199,9 @@ impl Render for Example {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.bind_keys([
KeyBinding::new("tab", Tab, None),
KeyBinding::new("shift-tab", TabPrev, None),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{App, Context, Render, Window, WindowOptions, div, img, prelude::*};
use gpui_platform::application;
use std::path::PathBuf;
@@ -27,6 +30,9 @@ impl Render for GifViewer {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let gif_path =
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples/image/black-cat-typing.gif");
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, ColorSpace, Context, Half, Render, Window, WindowOptions, canvas, div,
linear_color_stop, linear_gradient, point, prelude::*, px, size,
@@ -247,6 +250,9 @@ impl Render for GradientViewer {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(
WindowOptions {
focus: true,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Hsla, Window, WindowBounds, WindowOptions, container_query, div,
prelude::*, px, rgb, size,
@@ -63,6 +66,9 @@ impl Render for HolyGrailExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions, div, prelude::*, px,
rgb, size,
@@ -91,6 +94,9 @@ impl Render for HelloWorld {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "../example_support/fonts.rs"]
mod example_support;
use std::fs;
use std::path::PathBuf;
use std::sync::Arc;
@@ -159,6 +162,9 @@ fn run_example() {
base: manifest_dir.join("examples"),
})
.run(move |cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
#[cfg(not(target_family = "wasm"))]
{
let http_client = ReqwestClient::user_agent("gpui example").unwrap();
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use futures::FutureExt;
use gpui::{
App, AppContext, Asset as _, AssetLogger, Bounds, ClickEvent, Context, ElementId, Entity,
@@ -254,6 +257,9 @@ fn run_example() {
let app = gpui_platform::single_threaded_web();
app.run(move |cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
#[cfg(not(target_family = "wasm"))]
{
let http_client = ReqwestClient::user_agent("gpui example").unwrap();
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::{path::Path, sync::Arc, time::Duration};
use gpui::{
@@ -196,6 +199,9 @@ impl Render for ImageLoadingExample {
fn run_example() {
application().with_assets(Assets {}).run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let options = WindowOptions {
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
None,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::ops::Range;
use gpui::{
@@ -696,6 +699,9 @@ impl Render for InputExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(300.0), px(300.0)), cx);
cx.bind_keys([
KeyBinding::new("backspace", Backspace, None),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, ListAlignment, ListState, Render, Window, WindowBounds, WindowOptions,
div, list, prelude::*, px, rgb, size,
@@ -143,6 +146,9 @@ impl Render for BottomListDemo {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(400.), px(500.)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, MousePressureEvent, PressureStage, Window, WindowBounds, WindowOptions,
div, prelude::*, px, rgb, size,
@@ -48,6 +51,9 @@ impl MousePressureExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
cx.open_window(
@@ -8,6 +8,9 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::time::Duration;
use gpui::{
@@ -128,6 +131,9 @@ impl Render for HelloWorld {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
cx.open_window(
WindowOptions {
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, FocusHandle, KeyBinding, Window, WindowBounds, WindowOptions, actions,
div, prelude::*, px, rgb, size,
@@ -39,6 +42,9 @@ impl Render for ExampleWindow {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let mut bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
cx.bind_keys([KeyBinding::new("cmd-w", CloseWindow, None)]);
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::{fs, path::PathBuf};
use anyhow::Result;
@@ -163,6 +166,9 @@ fn run_example() {
base: PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples"),
})
.run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{App, Context, Entity, EventEmitter, prelude::*};
use gpui_platform::application;
@@ -15,6 +18,9 @@ impl EventEmitter<Change> for Counter {}
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let counter: Entity<Counter> = cx.new(|_cx| Counter { count: 0 });
let subscriber = cx.new(|cx: &mut Context<Counter>| {
cx.subscribe(&counter, |subscriber, _emitter, event, _cx| {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
Background, Bounds, ColorSpace, Context, MouseDownEvent, Path, PathBuilder, PathStyle, Pixels,
Point, Render, StrokeOptions, Window, WindowOptions, canvas, div, linear_color_stop,
@@ -443,6 +446,9 @@ impl Render for PaintingViewer {
fn run_example() {
application().run(|cx| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(
WindowOptions {
focus: true,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
Background, Bounds, ColorSpace, Context, Path, PathBuilder, Pixels, Render, TitlebarOptions,
Window, WindowBounds, WindowOptions, canvas, div, linear_color_stop, linear_gradient, point,
@@ -73,6 +76,9 @@ impl Render for PaintingViewer {
fn run_example() {
application().run(|cx| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(
WindowOptions {
titlebar: Some(TitlebarOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, AppContext, Bounds, Context, Window, WindowBounds, WindowOptions, div, linear_color_stop,
linear_gradient, pattern_slash, prelude::*, px, rgb, size,
@@ -103,6 +106,9 @@ impl Render for PatternExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(600.0), px(600.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
Anchor, App, Context, Div, Hsla, Stateful, Window, WindowOptions, anchored, deferred, div,
prelude::*, px,
@@ -167,6 +170,9 @@ impl Render for HelloWorld {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.open_window(WindowOptions::default(), |_, cx| {
cx.new(|_| HelloWorld {
open: false,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{App, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px, size};
use gpui_platform::application;
@@ -46,6 +49,9 @@ impl Render for Scrollable {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Context, Global, Menu, MenuItem, SharedString, SystemMenuType, Window, WindowOptions,
actions, div, prelude::*,
@@ -24,6 +27,9 @@ impl Render for SetMenus {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.set_global(AppState::new());
// Bring the menu bar to the foreground (so you can see the menu bar)
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, BoxShadow, Context, Div, SharedString, Window, WindowBounds, WindowOptions, div,
hsla, prelude::*, px, relative, rgb, size,
@@ -589,6 +592,9 @@ impl Render for Shadow {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(1000.0), px(800.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "../example_support/fonts.rs"]
mod example_support;
use std::fs;
use std::path::PathBuf;
@@ -76,6 +79,9 @@ fn run_example() {
base: PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples"),
})
.run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(300.0), px(300.0)), cx);
cx.open_window(
WindowOptions {
@@ -2,6 +2,9 @@
//! Demonstrates posting, replacing, dismissing, and responding to system notifications.
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Div, SharedString, Stateful, SystemNotification,
SystemNotificationAction, SystemNotificationResponse, Window, WindowBounds, WindowOptions, div,
@@ -97,6 +100,9 @@ fn button(id: &'static str, label: &'static str) -> Stateful<Div> {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.set_app_identity("dev.zed.gpui.system-notifications", "GPUI Notifications");
let view = cx.new(|_| SystemNotificationExample {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Div, ElementId, FocusHandle, KeyBinding, SharedString, Stateful, Window,
WindowBounds, WindowOptions, actions, div, prelude::*, px, size,
@@ -182,6 +185,9 @@ impl Render for Example {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.bind_keys([
KeyBinding::new("tab", Tab, None),
KeyBinding::new("shift-tab", TabPrev, None),
+7
View File
@@ -1,4 +1,5 @@
#![cfg_attr(target_family = "wasm", no_main)]
//! Example demonstrating GPUI's testing infrastructure.
//!
//! When run normally, this displays an interactive counter window.
@@ -7,6 +8,9 @@
//! Run the app: cargo run -p gpui --example testing
//! Run tests: cargo test -p gpui --example testing --features test-support
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, FocusHandle, Focusable, Render, Task, Window, WindowBounds,
WindowOptions, actions, div, prelude::*, px, rgb, size,
@@ -179,6 +183,9 @@ impl Render for Counter {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.bind_keys([
gpui::KeyBinding::new("up", Increment, Some("Counter")),
gpui::KeyBinding::new("down", Decrement, Some("Counter")),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use std::{
borrow::Cow,
ops::{Deref, DerefMut},
@@ -348,6 +351,9 @@ impl Render for TextExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
cx.set_menus(vec![Menu {
name: "GPUI Typography".into(),
disabled: false,
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, FontStyle, FontWeight, StyledText, Window, WindowBounds, WindowOptions,
div, prelude::*, px, size,
@@ -85,6 +88,9 @@ impl Render for HelloWorld {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, TextOverflow, Window, WindowBounds, WindowOptions, div, prelude::*, px,
size,
@@ -112,6 +115,9 @@ impl Render for HelloWorld {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
cx.open_window(
WindowOptions {
+7
View File
@@ -1,6 +1,10 @@
#![cfg_attr(target_family = "wasm", no_main)]
//! Renders a div with deep children hierarchy. This example is useful to exemplify that Zed can
//! handle deep hierarchies (even though it cannot just yet!).
#[path = "example_support/fonts.rs"]
mod example_support;
use std::sync::LazyLock;
use gpui::{App, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px, size};
@@ -32,6 +36,9 @@ impl Render for Tree {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(300.0), px(300.0)), cx);
cx.open_window(
WindowOptions {
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px, rgb, size,
uniform_list,
@@ -40,6 +43,9 @@ impl Render for UniformListExample {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(300.0), px(300.0)), cx);
cx.open_window(
WindowOptions {
@@ -13,6 +13,9 @@
//!
//! Run: `cargo run -p gpui --example view_example`
#[path = "../example_support/fonts.rs"]
mod example_support;
mod example_editor;
mod example_input;
mod example_text_area;
@@ -134,6 +137,9 @@ fn section(title: &str) -> Div {
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(560.0), px(480.0)), cx);
cx.bind_keys([
KeyBinding::new("backspace", Backspace, None),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, KeyBinding, PromptButton, PromptLevel, Window, WindowBounds, WindowKind,
WindowOptions, actions, div, prelude::*, px, rgb, size,
@@ -310,6 +313,9 @@ actions!(window, [Quit]);
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(800.0), px(600.0)), cx);
cx.open_window(
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, FocusHandle, Window, WindowBounds, WindowOptions, div, prelude::*, px,
rgb, size,
@@ -78,6 +81,9 @@ fn open_test_window(
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let window_size = size(px(420.), px(280.0));
let base = Bounds::centered(None, window_size, cx);
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, DisplayId, Hsla, Pixels, SharedString, Size, Window,
WindowBackgroundAppearance, WindowBounds, WindowKind, WindowOptions, div, point, prelude::*,
@@ -72,6 +75,9 @@ fn build_window_options(display_id: DisplayId, bounds: Bounds<Pixels>) -> Window
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
// Create several new windows, positioned in the top right corner of each screen
let size = Size {
width: px(350.),
+6
View File
@@ -1,5 +1,8 @@
#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, Context, CursorStyle, Decorations, HitboxBehavior, Hsla, MouseButton, Pixels,
Point, ResizeEdge, Size, Window, WindowBackgroundAppearance, WindowBounds, WindowDecorations,
@@ -211,6 +214,9 @@ fn resize_edge(pos: Point<Pixels>, shadow_size: Pixels, size: Size<Pixels>) -> O
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(600.0), px(600.0)), cx);
cx.open_window(
WindowOptions {
@@ -13,5 +13,5 @@ path = "main.rs"
[dependencies]
gpui = { path = "../../../gpui" }
gpui_platform = { path = "../../../gpui_platform" }
web-sys = { version = "0.3", features = ["Location", "Window"] }
web-sys = { version = "0.3", features = ["console", "Location", "Window"] }
web-time = "1"
@@ -1,3 +1,5 @@
use std::borrow::Cow;
use gpui::prelude::*;
use gpui::{
App, Bounds, Context, ElementId, SharedString, Task, Window, WindowBounds, WindowOptions, div,
@@ -429,6 +431,17 @@ fn requested_backend() -> gpui_platform::WebBackendPreference {
fn main() {
gpui_platform::web_init();
gpui_platform::application_with_web_backend(requested_backend()).run(|cx: &mut App| {
if let Err(error) = cx
.text_system()
.add_fonts(vec![Cow::Borrowed(include_bytes!(
"../../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Regular.ttf"
))])
{
web_sys::console::error_1(
&format!("failed to load application fonts: {error:#}").into(),
);
return;
}
let bounds = Bounds::centered(None, size(px(640.), px(560.)), cx);
cx.open_window(
WindowOptions {
+4 -19
View File
@@ -15,7 +15,6 @@ use gpui::{
};
use gpui_wgpu::{PreparedWebGraphics, WebBackendPreference, WgpuContext, wgpu};
use std::{
borrow::Cow,
cell::{Cell, RefCell},
path::{Path, PathBuf},
rc::Rc,
@@ -23,17 +22,10 @@ use std::{
};
use wasm_bindgen::prelude::*;
static BUNDLED_FONTS: &[&[u8]] = &[
include_bytes!("../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Regular.ttf"),
include_bytes!("../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Italic.ttf"),
include_bytes!("../../../assets/fonts/ibm-plex-sans/IBMPlexSans-SemiBold.ttf"),
include_bytes!("../../../assets/fonts/ibm-plex-sans/IBMPlexSans-SemiBoldItalic.ttf"),
include_bytes!("../../../assets/fonts/lilex/Lilex-Regular.ttf"),
include_bytes!("../../../assets/fonts/lilex/Lilex-Bold.ttf"),
include_bytes!("../../../assets/fonts/lilex/Lilex-Italic.ttf"),
include_bytes!("../../../assets/fonts/lilex/Lilex-BoldItalic.ttf"),
];
/// Provides the GPUI platform implementation for web browsers.
///
/// The platform starts with an empty font database. Applications must add fonts
/// through [`gpui::App::text_system`] before opening a window.
pub struct WebPlatform {
browser_window: web_sys::Window,
dispatcher: Arc<WebDispatcher>,
@@ -135,13 +127,6 @@ impl WebPlatform {
let text_system = Arc::new(gpui_wgpu::CosmicTextSystem::new_without_system_fonts(
"IBM Plex Sans",
));
let fonts = BUNDLED_FONTS
.iter()
.map(|bytes| Cow::Borrowed(*bytes))
.collect();
if let Err(error) = text_system.add_fonts(fonts) {
log::error!("failed to load bundled fonts: {error:#}");
}
let text_system: Arc<dyn PlatformTextSystem> = text_system;
let active_display: Rc<dyn PlatformDisplay> =
Rc::new(WebDisplay::new(browser_window.clone()));