Files
Ely-GPUI-Components/examples/gallery/pages/shell/system.rs
T
ZacharyZhang-NY 2cd2ca8bc1 T44d Web · What a browser cannot do says why; fonts resolve; the bundle builds
Demos that open a second window, take files, move the window, read the
clipboard or set native menus show a note on the web in the blocked style.
IBM Plex Sans Regular joins the assets, unmodified, where gpui's svg
renderer loads it: gpui_web answers .SystemUIFont with it. The gallery's
web entry registers a Hebrew cut of Noto Sans Hebrew. scripts/web.sh builds
the bundle with wasm-bindgen and wasm-opt -Oz, 20.0 MB, and fails past 25 MiB.
2026-09-29 19:16:41 -04:00

157 lines
5.6 KiB
Rust

use ely_gpui_component::{
buttons::{Button, ButtonVariant},
shell::{TrayIcon, TrayItem, dock_badge, set_dock_badge},
typography::Caption,
};
use gpui::{App, IntoElement, ParentElement, SharedString, Window};
use crate::{
probe::probe,
ui::{blocked, row, section, web_note},
};
const ITEMS: [&str; 3] = ["Open gallery", "Toggle theme", "Quit"];
pub fn tray(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let tray = window.use_keyed_state("tray", cx, |_, _| None::<TrayIcon>);
let last = window.use_keyed_state("tray-last", cx, |_, _| SharedString::from("nothing yet"));
let shown = tray.read(cx).is_some();
let note = last.read(cx).clone();
let (toggle, pick) = (tray.clone(), tray);
section(
"TrayIcon / TrayMenu",
"An SF Symbol in the menu bar with a menu. macOS only.",
cx,
)
.children(web_note(
"A browser page has no menu bar to hold an icon, so showing one fails and logs why.",
cx,
))
.child(
row()
.child(probe(
"tray-show",
Button::new(
"tray-show",
if shown {
"Remove tray icon"
} else {
"Show tray icon"
},
)
.variant(ButtonVariant::Outline)
.on_click(move |_, _, cx| {
let last = last.clone();
let next = match toggle.read(cx) {
Some(_) => None,
None => {
let items = vec![
TrayItem::Action(ITEMS[0].into()),
TrayItem::Action(ITEMS[1].into()),
TrayItem::Separator,
TrayItem::Action(ITEMS[2].into()),
];
let made = TrayIcon::new(
"circle.hexagongrid",
items,
move |index, cx| {
let label = match index {
0 => ITEMS[0],
1 => ITEMS[1],
3 => ITEMS[2],
other => panic!("tray has no action at {other}"),
};
last.update(cx, |last, cx| {
*last = label.into();
cx.notify();
})
},
cx,
);
match made {
Ok(icon) => Some(icon),
Err(error) => {
log::error!("gallery: tray failed: {error:#}");
None
}
}
}
};
toggle.update(cx, |tray, cx| {
*tray = next;
cx.notify();
})
}),
))
.child(probe(
"tray-pick",
Button::new("tray-pick", "Pick “Open gallery”")
.variant(ButtonVariant::Ghost)
.disabled(!shown)
.on_click(move |_, _, cx| {
if let Some(icon) = pick.read(cx) {
icon.pick(0);
}
}),
))
.child(Caption::new(format!("Last pick: {note}"))),
)
}
pub fn dock(cx: &mut App) -> impl IntoElement + use<> {
let reading = match dock_badge() {
Ok(Some(label)) => format!("The Dock shows “{label}”."),
Ok(None) => "The Dock shows no badge.".to_string(),
Err(error) => format!("{error:#}"),
};
let badge = |label: Option<&'static str>| {
move |_: &gpui::ClickEvent, window: &mut Window, _: &mut App| {
if let Err(error) = set_dock_badge(label) {
log::error!("gallery: badge failed: {error:#}");
}
window.refresh();
}
};
section(
"DockBadge",
"A count on the app's Dock icon. macOS only.",
cx,
)
.children(web_note(
"A browser page has no Dock icon to badge, so setting one fails and logs why.",
cx,
))
.child(
row()
.child(probe(
"badge-set",
Button::new("badge-set", "Badge 3")
.variant(ButtonVariant::Outline)
.on_click(badge(Some("3"))),
))
.child(probe(
"badge-clear",
Button::new("badge-clear", "Clear")
.variant(ButtonVariant::Ghost)
.on_click(badge(None)),
))
.child(Caption::new(reading)),
)
}
pub fn notification(cx: &App) -> impl IntoElement + use<> {
section(
"SystemNotification",
"Notices from the system's own center.",
cx,
)
.child(blocked(
if cfg!(target_family = "wasm") {
"Not shown: gpui on the web posts no system notification."
} else {
"Not yet shown: gpui posts a system notification only from an app bundle, and the gallery runs unbundled."
},
cx,
))
}