mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 15:13:12 -04:00
eframe: gate web clipboard image copy behind web_clipboard_image feature
The wasm path of `set_clipboard_image` is the only consumer of the `image` crate inside eframe; `image`'s decoders / color-management code add ~600 KB compressed to a wasm bundle even when only `png` is requested (image-webp / moxcms / pxfm get pulled in regardless). Make the dep optional behind a new `web_clipboard_image` feature (default-on, so this is source-compatible for everyone except those who explicitly want the smaller bundle). Apps that opt out get a `log::warn!` if a CopyImage command ever fires.
This commit is contained in:
@@ -29,12 +29,18 @@ default = [
|
||||
"accesskit",
|
||||
"default_fonts",
|
||||
"wayland", # Required for Linux support (including CI!)
|
||||
"web_clipboard_image",
|
||||
"web_screen_reader",
|
||||
"wgpu",
|
||||
"winit/default",
|
||||
"x11",
|
||||
]
|
||||
|
||||
## Enable PNG-encoding `egui::ColorImage`s for the web clipboard via the
|
||||
## [`image`](https://docs.rs/image) crate. Disable on the web to drop the
|
||||
## image (and image-webp / moxcms / ...) crates from the wasm bundle.
|
||||
web_clipboard_image = ["dep:image"]
|
||||
|
||||
## Enable platform accessibility API implementations through [AccessKit](https://accesskit.dev/).
|
||||
accesskit = ["egui-winit/accesskit"]
|
||||
|
||||
@@ -195,7 +201,10 @@ windows-sys = { workspace = true, features = [
|
||||
# web:
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
bytemuck.workspace = true
|
||||
image = { workspace = true, features = ["png"] } # For copying images
|
||||
# `image` is only needed for the "copy image to clipboard" path on the web.
|
||||
# Behind `web_clipboard_image` (default-on) so apps that don't care can drop
|
||||
# the image crate (and ~600 KB of png/webp/moxcms compressed code with it).
|
||||
image = { workspace = true, features = ["png"], optional = true }
|
||||
js-sys.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
wasm-bindgen.workspace = true
|
||||
|
||||
@@ -385,7 +385,16 @@ impl AppRunner {
|
||||
super::set_clipboard_text(&text);
|
||||
}
|
||||
egui::OutputCommand::CopyImage(image) => {
|
||||
#[cfg(feature = "web_clipboard_image")]
|
||||
super::set_clipboard_image(&image);
|
||||
#[cfg(not(feature = "web_clipboard_image"))]
|
||||
{
|
||||
let _ = image;
|
||||
log::warn!(
|
||||
"CopyImage requested but eframe was built without the \
|
||||
`web_clipboard_image` feature; ignoring."
|
||||
);
|
||||
}
|
||||
}
|
||||
egui::OutputCommand::OpenUrl(open_url) => {
|
||||
super::open_url(&open_url.url, open_url.new_tab);
|
||||
|
||||
@@ -207,6 +207,7 @@ fn set_clipboard_text(s: &str) {
|
||||
}
|
||||
|
||||
/// Set the clipboard image.
|
||||
#[cfg(feature = "web_clipboard_image")]
|
||||
fn set_clipboard_image(image: &egui::ColorImage) {
|
||||
if let Some(window) = web_sys::window() {
|
||||
if !window.is_secure_context() {
|
||||
@@ -250,6 +251,7 @@ fn set_clipboard_image(image: &egui::ColorImage) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_clipboard_image")]
|
||||
fn to_image(image: &egui::ColorImage) -> Result<image::RgbaImage, String> {
|
||||
profiling::function_scope!();
|
||||
image::RgbaImage::from_raw(
|
||||
@@ -260,6 +262,7 @@ fn to_image(image: &egui::ColorImage) -> Result<image::RgbaImage, String> {
|
||||
.ok_or_else(|| "Invalid IconData".to_owned())
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_clipboard_image")]
|
||||
fn to_png_bytes(image: &image::RgbaImage) -> Result<Vec<u8>, String> {
|
||||
profiling::function_scope!();
|
||||
let mut png_bytes: Vec<u8> = Vec::new();
|
||||
@@ -272,6 +275,7 @@ fn to_png_bytes(image: &image::RgbaImage) -> Result<Vec<u8>, String> {
|
||||
Ok(png_bytes)
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_clipboard_image")]
|
||||
fn create_clipboard_item(mime: &str, bytes: &[u8]) -> Result<web_sys::ClipboardItem, JsValue> {
|
||||
let array = js_sys::Uint8Array::from(bytes);
|
||||
let blob_parts = js_sys::Array::new();
|
||||
|
||||
Reference in New Issue
Block a user