From 2b7d8eaaca5ebb0073a36aaf702554df88c5e97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 1 Apr 2025 02:54:45 +0200 Subject: [PATCH 01/18] Test different `Theme` variants in `styling` example --- .github/workflows/test.yml | 4 +- Cargo.lock | 2 + core/src/input_method.rs | 33 ---------------- examples/styling/Cargo.toml | 4 ++ .../catppuccin_frappé-tiny-skia.sha256 | 1 + .../catppuccin_latte-tiny-skia.sha256 | 1 + .../catppuccin_macchiato-tiny-skia.sha256 | 1 + .../catppuccin_mocha-tiny-skia.sha256 | 1 + .../styling/snapshots/dark-tiny-skia.sha256 | 1 + .../snapshots/dracula-tiny-skia.sha256 | 1 + .../styling/snapshots/ferra-tiny-skia.sha256 | 1 + .../snapshots/gruvbox_dark-tiny-skia.sha256 | 1 + .../snapshots/gruvbox_light-tiny-skia.sha256 | 1 + .../kanagawa_dragon-tiny-skia.sha256 | 1 + .../snapshots/kanagawa_lotus-tiny-skia.sha256 | 1 + .../snapshots/kanagawa_wave-tiny-skia.sha256 | 1 + .../styling/snapshots/light-tiny-skia.sha256 | 1 + .../snapshots/moonfly-tiny-skia.sha256 | 1 + .../snapshots/nightfly-tiny-skia.sha256 | 1 + .../styling/snapshots/nord-tiny-skia.sha256 | 1 + .../snapshots/oxocarbon-tiny-skia.sha256 | 1 + .../snapshots/solarized_dark-tiny-skia.sha256 | 1 + .../solarized_light-tiny-skia.sha256 | 1 + .../snapshots/tokyo_night-tiny-skia.sha256 | 1 + .../tokyo_night_light-tiny-skia.sha256 | 1 + .../tokyo_night_storm-tiny-skia.sha256 | 1 + examples/styling/src/main.rs | 39 +++++++++++++++++++ 27 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 examples/styling/snapshots/catppuccin_frappé-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/catppuccin_latte-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/catppuccin_macchiato-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/catppuccin_mocha-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/dark-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/dracula-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/ferra-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/gruvbox_dark-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/gruvbox_light-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/kanagawa_dragon-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/kanagawa_lotus-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/kanagawa_wave-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/light-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/moonfly-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/nightfly-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/nord-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/oxocarbon-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/solarized_dark-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/solarized_light-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/tokyo_night-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/tokyo_night_light-tiny-skia.sha256 create mode 100644 examples/styling/snapshots/tokyo_night_storm-tiny-skia.sha256 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f35556f..1e988195 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,5 +23,5 @@ jobs: sudo apt-get install -y libxkbcommon-dev libgtk-3-dev - name: Run tests run: | - cargo test --verbose --workspace - cargo test --verbose --workspace --all-features + cargo test --verbose --workspace -- --ignored + cargo test --verbose --workspace --all-features -- --ignored diff --git a/Cargo.lock b/Cargo.lock index 8aebb086..33210bf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5519,6 +5519,8 @@ name = "styling" version = "0.1.0" dependencies = [ "iced", + "iced_test", + "rayon", ] [[package]] diff --git a/core/src/input_method.rs b/core/src/input_method.rs index cd8d459d..1d82279c 100644 --- a/core/src/input_method.rs +++ b/core/src/input_method.rs @@ -151,39 +151,6 @@ impl InputMethod { /// However, one couldn't possibly have a key for every single /// unicode character that the user might want to type. The solution operating systems employ is /// to allow the user to type these using _a sequence of keypresses_ instead. -/// -/// A prominent example of this is accents—many keyboard layouts allow you to first click the -/// "accent key", and then the character you want to apply the accent to. In this case, some -/// platforms will generate the following event sequence: -/// -/// ```ignore -/// // Press "`" key -/// Ime::Preedit("`", Some((0, 0))) -/// // Press "E" key -/// Ime::Preedit("", None) // Synthetic event generated to clear preedit. -/// Ime::Commit("é") -/// ``` -/// -/// Additionally, certain input devices are configured to display a candidate box that allow the -/// user to select the desired character interactively. (To properly position this box, you must use -/// [`Shell::request_input_method`](crate::Shell::request_input_method).) -/// -/// An example of a keyboard layout which uses candidate boxes is pinyin. On a latin keyboard the -/// following event sequence could be obtained: -/// -/// ```ignore -/// // Press "A" key -/// Ime::Preedit("a", Some((1, 1))) -/// // Press "B" key -/// Ime::Preedit("a b", Some((3, 3))) -/// // Press left arrow key -/// Ime::Preedit("a b", Some((1, 1))) -/// // Press space key -/// Ime::Preedit("啊b", Some((3, 3))) -/// // Press space key -/// Ime::Preedit("", None) // Synthetic event generated to clear preedit. -/// Ime::Commit("啊不") -/// ``` #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Event { /// Notifies when the IME was opened. diff --git a/examples/styling/Cargo.toml b/examples/styling/Cargo.toml index 75cc520d..6e05ae34 100644 --- a/examples/styling/Cargo.toml +++ b/examples/styling/Cargo.toml @@ -7,3 +7,7 @@ publish = false [dependencies] iced.workspace = true + +[dev-dependencies] +iced_test.workspace = true +rayon = "1" diff --git a/examples/styling/snapshots/catppuccin_frappé-tiny-skia.sha256 b/examples/styling/snapshots/catppuccin_frappé-tiny-skia.sha256 new file mode 100644 index 00000000..e4038c0b --- /dev/null +++ b/examples/styling/snapshots/catppuccin_frappé-tiny-skia.sha256 @@ -0,0 +1 @@ +9e67e429f88fd5a64744d9cd4d42e123950bea4a45fea78581bc3d64b12e11f0 \ No newline at end of file diff --git a/examples/styling/snapshots/catppuccin_latte-tiny-skia.sha256 b/examples/styling/snapshots/catppuccin_latte-tiny-skia.sha256 new file mode 100644 index 00000000..43f380cf --- /dev/null +++ b/examples/styling/snapshots/catppuccin_latte-tiny-skia.sha256 @@ -0,0 +1 @@ +811a22238f3a40e3e3998f514c0a95f24f2b45449250682d86c8ec392fec5e28 \ No newline at end of file diff --git a/examples/styling/snapshots/catppuccin_macchiato-tiny-skia.sha256 b/examples/styling/snapshots/catppuccin_macchiato-tiny-skia.sha256 new file mode 100644 index 00000000..4d7e694e --- /dev/null +++ b/examples/styling/snapshots/catppuccin_macchiato-tiny-skia.sha256 @@ -0,0 +1 @@ +6bf957efe807f87f38cfc672f9a05325aadee6256aacca87bbc3281b98160c8a \ No newline at end of file diff --git a/examples/styling/snapshots/catppuccin_mocha-tiny-skia.sha256 b/examples/styling/snapshots/catppuccin_mocha-tiny-skia.sha256 new file mode 100644 index 00000000..12ca25d5 --- /dev/null +++ b/examples/styling/snapshots/catppuccin_mocha-tiny-skia.sha256 @@ -0,0 +1 @@ +d3f4110fae78a3be3b7a4813e9a432b48b81fff1e982c0244e4ea394074bef55 \ No newline at end of file diff --git a/examples/styling/snapshots/dark-tiny-skia.sha256 b/examples/styling/snapshots/dark-tiny-skia.sha256 new file mode 100644 index 00000000..f4d2328e --- /dev/null +++ b/examples/styling/snapshots/dark-tiny-skia.sha256 @@ -0,0 +1 @@ +578e7420de69d82906d284c59d81fcea0edf81098481fc4dd7b4c1fb577b7f1c \ No newline at end of file diff --git a/examples/styling/snapshots/dracula-tiny-skia.sha256 b/examples/styling/snapshots/dracula-tiny-skia.sha256 new file mode 100644 index 00000000..9c3af7e9 --- /dev/null +++ b/examples/styling/snapshots/dracula-tiny-skia.sha256 @@ -0,0 +1 @@ +422e841113efaa86e9e37593d0d14f8dd36ad483a81c30a08588f48805e4f9f3 \ No newline at end of file diff --git a/examples/styling/snapshots/ferra-tiny-skia.sha256 b/examples/styling/snapshots/ferra-tiny-skia.sha256 new file mode 100644 index 00000000..f344175f --- /dev/null +++ b/examples/styling/snapshots/ferra-tiny-skia.sha256 @@ -0,0 +1 @@ +3d616a31842a29b4a3d31fbeef25f95c7b50f33360f1c05e069e0b29b3f7553e \ No newline at end of file diff --git a/examples/styling/snapshots/gruvbox_dark-tiny-skia.sha256 b/examples/styling/snapshots/gruvbox_dark-tiny-skia.sha256 new file mode 100644 index 00000000..528e4662 --- /dev/null +++ b/examples/styling/snapshots/gruvbox_dark-tiny-skia.sha256 @@ -0,0 +1 @@ +9a21865bfc075669d368ccac69b975c3e1f6c22ba297dddfa003d4ee1a06641c \ No newline at end of file diff --git a/examples/styling/snapshots/gruvbox_light-tiny-skia.sha256 b/examples/styling/snapshots/gruvbox_light-tiny-skia.sha256 new file mode 100644 index 00000000..0846526d --- /dev/null +++ b/examples/styling/snapshots/gruvbox_light-tiny-skia.sha256 @@ -0,0 +1 @@ +d5164fb10a92177afd0aab353557d1e3fdaa743962c6a901f05cbfcd0d91e9fb \ No newline at end of file diff --git a/examples/styling/snapshots/kanagawa_dragon-tiny-skia.sha256 b/examples/styling/snapshots/kanagawa_dragon-tiny-skia.sha256 new file mode 100644 index 00000000..1ea91e22 --- /dev/null +++ b/examples/styling/snapshots/kanagawa_dragon-tiny-skia.sha256 @@ -0,0 +1 @@ +3d5ba3b50f192f8700edbfbf54007e92dfd66997bce7342671afc2b60d556aca \ No newline at end of file diff --git a/examples/styling/snapshots/kanagawa_lotus-tiny-skia.sha256 b/examples/styling/snapshots/kanagawa_lotus-tiny-skia.sha256 new file mode 100644 index 00000000..aed0d8ba --- /dev/null +++ b/examples/styling/snapshots/kanagawa_lotus-tiny-skia.sha256 @@ -0,0 +1 @@ +90cb13c900d58a56ce170afeefbceb77410d024e7eae6030e181df1c929c3944 \ No newline at end of file diff --git a/examples/styling/snapshots/kanagawa_wave-tiny-skia.sha256 b/examples/styling/snapshots/kanagawa_wave-tiny-skia.sha256 new file mode 100644 index 00000000..e5785815 --- /dev/null +++ b/examples/styling/snapshots/kanagawa_wave-tiny-skia.sha256 @@ -0,0 +1 @@ +71b625bc39aaead7a1298e4b2dad51b266526c53deab139858774986395878db \ No newline at end of file diff --git a/examples/styling/snapshots/light-tiny-skia.sha256 b/examples/styling/snapshots/light-tiny-skia.sha256 new file mode 100644 index 00000000..e2bc2896 --- /dev/null +++ b/examples/styling/snapshots/light-tiny-skia.sha256 @@ -0,0 +1 @@ +f08f80a79959ef1c2fd8f8696a26555f2b2eab6618dd3653a042acab563bcced \ No newline at end of file diff --git a/examples/styling/snapshots/moonfly-tiny-skia.sha256 b/examples/styling/snapshots/moonfly-tiny-skia.sha256 new file mode 100644 index 00000000..f873883f --- /dev/null +++ b/examples/styling/snapshots/moonfly-tiny-skia.sha256 @@ -0,0 +1 @@ +3302b7934051ff8aa01d70c45e28c444bdc93e8a4da219931aa22465b51c6748 \ No newline at end of file diff --git a/examples/styling/snapshots/nightfly-tiny-skia.sha256 b/examples/styling/snapshots/nightfly-tiny-skia.sha256 new file mode 100644 index 00000000..4c44a93c --- /dev/null +++ b/examples/styling/snapshots/nightfly-tiny-skia.sha256 @@ -0,0 +1 @@ +661ec43b66213f369ce5a3680e9e8ead56c98d94718da25b12fbb313386944e0 \ No newline at end of file diff --git a/examples/styling/snapshots/nord-tiny-skia.sha256 b/examples/styling/snapshots/nord-tiny-skia.sha256 new file mode 100644 index 00000000..8dc1da2e --- /dev/null +++ b/examples/styling/snapshots/nord-tiny-skia.sha256 @@ -0,0 +1 @@ +b5dd22b064220d5f2f90c6f0f381eff41d25f534587d1649ed59e25f878eda97 \ No newline at end of file diff --git a/examples/styling/snapshots/oxocarbon-tiny-skia.sha256 b/examples/styling/snapshots/oxocarbon-tiny-skia.sha256 new file mode 100644 index 00000000..56f26dc9 --- /dev/null +++ b/examples/styling/snapshots/oxocarbon-tiny-skia.sha256 @@ -0,0 +1 @@ +dd6e7e7ba125a2549143501c3de44427633f0bfa6c0d8b6f66aa95d503874065 \ No newline at end of file diff --git a/examples/styling/snapshots/solarized_dark-tiny-skia.sha256 b/examples/styling/snapshots/solarized_dark-tiny-skia.sha256 new file mode 100644 index 00000000..063a9c50 --- /dev/null +++ b/examples/styling/snapshots/solarized_dark-tiny-skia.sha256 @@ -0,0 +1 @@ +44b5afe743b753a54f3e68da2fd2701837e7e8cff276ff1e8c349030c83ac72e \ No newline at end of file diff --git a/examples/styling/snapshots/solarized_light-tiny-skia.sha256 b/examples/styling/snapshots/solarized_light-tiny-skia.sha256 new file mode 100644 index 00000000..0bb49deb --- /dev/null +++ b/examples/styling/snapshots/solarized_light-tiny-skia.sha256 @@ -0,0 +1 @@ +1b46820f12611b2759eb843688cd13b6024f2096b7986f205398bb029e0c60bd \ No newline at end of file diff --git a/examples/styling/snapshots/tokyo_night-tiny-skia.sha256 b/examples/styling/snapshots/tokyo_night-tiny-skia.sha256 new file mode 100644 index 00000000..d6eb163d --- /dev/null +++ b/examples/styling/snapshots/tokyo_night-tiny-skia.sha256 @@ -0,0 +1 @@ +27a9a8bb08cea7b0a9b9763e332a6833d4fead1a885cdd59a1f5161e3726d6b1 \ No newline at end of file diff --git a/examples/styling/snapshots/tokyo_night_light-tiny-skia.sha256 b/examples/styling/snapshots/tokyo_night_light-tiny-skia.sha256 new file mode 100644 index 00000000..f9eb9211 --- /dev/null +++ b/examples/styling/snapshots/tokyo_night_light-tiny-skia.sha256 @@ -0,0 +1 @@ +ab0dee2cc24f30eb51b376a0385302b45bfeddb373348525dab7f551c27ffec2 \ No newline at end of file diff --git a/examples/styling/snapshots/tokyo_night_storm-tiny-skia.sha256 b/examples/styling/snapshots/tokyo_night_storm-tiny-skia.sha256 new file mode 100644 index 00000000..a642d939 --- /dev/null +++ b/examples/styling/snapshots/tokyo_night_storm-tiny-skia.sha256 @@ -0,0 +1 @@ +aef404c7e38aec5387c39cf3a2911688324c1b9b520e5f541b9fd3fd6eefd3a8 \ No newline at end of file diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index fce2b162..322b2b94 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -167,3 +167,42 @@ impl Styling { self.theme.clone() } } + +#[cfg(test)] +mod tests { + use super::*; + use rayon::prelude::*; + + use iced_test::{Error, simulator}; + + #[test] + #[ignore] + fn it_showcases_every_theme() -> Result<(), Error> { + Theme::ALL + .par_iter() + .map(|theme| { + let mut styling = Styling::default(); + styling.update(Message::ThemeChanged(theme.clone())); + + let theme = styling.theme(); + + let mut ui = simulator(styling.view()); + + let snapshot = ui.snapshot(&theme)?; + + assert!( + snapshot.matches_hash(format!( + "snapshots/{theme}", + theme = theme + .to_string() + .to_ascii_lowercase() + .replace(" ", "_") + ))?, + "snapshots for {theme} should match!" + ); + + Ok(()) + }) + .collect() + } +} From 44e13db1ef76c30b95e70eacab3c528542ecf1b2 Mon Sep 17 00:00:00 2001 From: edwloef Date: Thu, 13 Mar 2025 16:32:53 +0100 Subject: [PATCH 02/18] get rid of palette dependency --- Cargo.lock | 1 - Cargo.toml | 1 - core/Cargo.toml | 1 - core/src/color.rs | 63 ---------------- core/src/theme/palette.rs | 116 +++++++++++++++++++++++------ examples/color_palette/Cargo.toml | 2 +- examples/color_palette/src/main.rs | 34 +++++++-- 7 files changed, 119 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33210bf2..143d8771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2527,7 +2527,6 @@ dependencies = [ "lilt", "log", "num-traits", - "palette", "rustc-hash 2.1.1", "smol_str", "thiserror 1.0.69", diff --git a/Cargo.toml b/Cargo.toml index 7e8bbc34..056f8a7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -164,7 +164,6 @@ lyon = "1.0" lyon_path = "1.0" num-traits = "0.2" ouroboros = "0.18" -palette = "0.7" png = "0.17" pulldown-cmark = "0.12" qrcode = { version = "0.13", default-features = false } diff --git a/core/Cargo.toml b/core/Cargo.toml index 1ca7260c..60920e46 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -24,7 +24,6 @@ glam.workspace = true lilt.workspace = true log.workspace = true num-traits.workspace = true -palette.workspace = true rustc-hash.workspace = true smol_str.workspace = true thiserror.workspace = true diff --git a/core/src/color.rs b/core/src/color.rs index a9183776..37a8921d 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -1,5 +1,3 @@ -use palette::rgb::{Srgb, Srgba}; - /// A color in the `sRGB` color space. #[derive(Debug, Clone, Copy, PartialEq, Default)] pub struct Color { @@ -242,70 +240,9 @@ macro_rules! color { }}; } -/// Converts from palette's `Rgba` type to a [`Color`]. -impl From for Color { - fn from(rgba: Srgba) -> Self { - Color::new(rgba.red, rgba.green, rgba.blue, rgba.alpha) - } -} - -/// Converts from [`Color`] to palette's `Rgba` type. -impl From for Srgba { - fn from(c: Color) -> Self { - Srgba::new(c.r, c.g, c.b, c.a) - } -} - -/// Converts from palette's `Rgb` type to a [`Color`]. -impl From for Color { - fn from(rgb: Srgb) -> Self { - Color::new(rgb.red, rgb.green, rgb.blue, 1.0) - } -} - -/// Converts from [`Color`] to palette's `Rgb` type. -impl From for Srgb { - fn from(c: Color) -> Self { - Srgb::new(c.r, c.g, c.b) - } -} - #[cfg(test)] mod tests { use super::*; - use palette::blend::Blend; - - #[test] - fn srgba_traits() { - let c = Color::from_rgb(0.5, 0.4, 0.3); - // Round-trip conversion to the palette::Srgba type - let s: Srgba = c.into(); - let r: Color = s.into(); - assert_eq!(c, r); - } - - #[test] - fn color_manipulation() { - use approx::assert_relative_eq; - - let c1 = Color::from_rgb(0.5, 0.4, 0.3); - let c2 = Color::from_rgb(0.2, 0.5, 0.3); - - // Convert to linear color for manipulation - let l1 = Srgba::from(c1).into_linear(); - let l2 = Srgba::from(c2).into_linear(); - - // Take the lighter of each of the sRGB components - let lighter = l1.lighten(l2); - - // Convert back to our Color - let result: Color = Srgba::from_linear(lighter).into(); - - assert_relative_eq!(result.r, 0.5); - assert_relative_eq!(result.g, 0.5); - assert_relative_eq!(result.b, 0.3); - assert_relative_eq!(result.a, 1.0); - } #[test] fn parse() { diff --git a/core/src/theme/palette.rs b/core/src/theme/palette.rs index faffee8b..7be5a98e 100644 --- a/core/src/theme/palette.rs +++ b/core/src/theme/palette.rs @@ -1,10 +1,6 @@ //! Define the colors of a theme. use crate::{Color, color}; -use palette::color_difference::Wcag21RelativeContrast; -use palette::rgb::Rgb; -use palette::{FromColor, Hsl, Mix}; - use std::sync::LazyLock; /// A color palette. @@ -607,13 +603,20 @@ impl Danger { } } +struct Hsl { + h: f32, + s: f32, + l: f32, + a: f32, +} + fn darken(color: Color, amount: f32) -> Color { let mut hsl = to_hsl(color); - hsl.lightness = if hsl.lightness - amount < 0.0 { + hsl.l = if hsl.l - amount < 0.0 { 0.0 } else { - hsl.lightness - amount + hsl.l - amount }; from_hsl(hsl) @@ -622,10 +625,10 @@ fn darken(color: Color, amount: f32) -> Color { fn lighten(color: Color, amount: f32) -> Color { let mut hsl = to_hsl(color); - hsl.lightness = if hsl.lightness + amount > 1.0 { + hsl.l = if hsl.l + amount > 1.0 { 1.0 } else { - hsl.lightness + amount + hsl.l + amount }; from_hsl(hsl) @@ -642,17 +645,24 @@ fn deviate(color: Color, amount: f32) -> Color { fn muted(color: Color) -> Color { let mut hsl = to_hsl(color); - hsl.saturation = hsl.saturation.min(0.5); + hsl.s = hsl.s.min(0.5); from_hsl(hsl) } fn mix(a: Color, b: Color, factor: f32) -> Color { - let a_lin = Rgb::from(a).into_linear(); - let b_lin = Rgb::from(b).into_linear(); + let b_amount = factor.clamp(0.0, 1.0); + let a_amount = 1.0 - b_amount; - let mixed = a_lin.mix(b_lin, factor); - Rgb::from_linear(mixed).into() + let a_linear = a.into_linear().map(|c| c * a_amount); + let b_linear = b.into_linear().map(|c| c * b_amount); + + Color::from_linear_rgba( + a_linear[0] + b_linear[0], + a_linear[1] + b_linear[1], + a_linear[2] + b_linear[2], + a_linear[3] + b_linear[3], + ) } fn readable(background: Color, text: Color) -> Color { @@ -680,27 +690,85 @@ fn readable(background: Color, text: Color) -> Color { } fn is_dark(color: Color) -> bool { - to_hsl(color).lightness < 0.6 + to_hsl(color).l < 0.6 } fn is_readable(a: Color, b: Color) -> bool { - let a_srgb = Rgb::from(a); - let b_srgb = Rgb::from(b); - - a_srgb.has_enhanced_contrast_text(b_srgb) + relative_contrast(a, b) >= 7.0 } +// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio fn relative_contrast(a: Color, b: Color) -> f32 { - let a_srgb = Rgb::from(a); - let b_srgb = Rgb::from(b); - - a_srgb.relative_contrast(b_srgb) + let lum_a = relative_luminance(a); + let lum_b = relative_luminance(b); + (lum_a.max(lum_b) + 0.05) / (lum_a.min(lum_b) + 0.05) } +// https://www.w3.org/TR/WCAG21/#dfn-relative-luminance +fn relative_luminance(color: Color) -> f32 { + let linear = color.into_linear(); + 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2] +} + +// https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB fn to_hsl(color: Color) -> Hsl { - Hsl::from_color(Rgb::from(color)) + let x_max = color.r.max(color.g).max(color.b); + let x_min = color.r.min(color.g).min(color.b); + let c = x_max - x_min; + let l = x_max.midpoint(x_min); + + let h = if c == 0.0 { + 0.0 + } else if x_max == color.r { + 60.0 * ((color.g - color.b) / c).rem_euclid(6.0) + } else if x_max == color.g { + 60.0 * (((color.b - color.r) / c) + 2.0) + } else { + // x_max == color.b + 60.0 * (((color.r - color.g) / c) + 4.0) + }; + + let s = if l == 0.0 || l == 1.0 { + 0.0 + } else { + (x_max - l) / l.min(1.0 - l) + }; + + Hsl { + h, + s, + l, + a: color.a, + } } +// https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB fn from_hsl(hsl: Hsl) -> Color { - Rgb::from_color(hsl).into() + let c = (1.0 - (2.0 * hsl.l - 1.0).abs()) * hsl.s; + let h = hsl.h / 60.0; + let x = c * (1.0 - (h.rem_euclid(2.0) - 1.0).abs()); + + let (r1, g1, b1) = if h < 1.0 { + (c, x, 0.0) + } else if h < 2.0 { + (x, c, 0.0) + } else if h < 3.0 { + (0.0, c, x) + } else if h < 4.0 { + (0.0, x, c) + } else if h < 5.0 { + (x, 0.0, c) + } else { + // h < 6.0 + (c, 0.0, x) + }; + + let m = hsl.l - (c / 2.0); + + Color { + r: r1 + m, + g: g1 + m, + b: b1 + m, + a: hsl.a, + } } diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index 27d67f55..efa744b0 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -9,4 +9,4 @@ publish = false iced.workspace = true iced.features = ["canvas"] -palette.workspace = true +palette = "0.7" diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index b11c8a2b..2662d063 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -46,7 +46,7 @@ pub enum Message { impl ColorPalette { fn update(&mut self, message: Message) { let srgb = match message { - Message::RgbColorChanged(rgb) => Rgb::from(rgb), + Message::RgbColorChanged(rgb) => to_rgb(rgb), Message::HslColorChanged(hsl) => Rgb::from_color(hsl), Message::HsvColorChanged(hsv) => Rgb::from_color(hsv), Message::HwbColorChanged(hwb) => Rgb::from_color(hwb), @@ -54,13 +54,13 @@ impl ColorPalette { Message::LchColorChanged(lch) => Rgb::from_color(lch), }; - self.theme = Theme::new(srgb); + self.theme = Theme::new(to_color(srgb)); } fn view(&self) -> Element { let base = self.theme.base; - let srgb = Rgb::from(base); + let srgb = to_rgb(base); let hsl = palette::Hsl::from_color(srgb); let hsv = palette::Hsv::from_color(srgb); let hwb = palette::Hwb::from_color(srgb); @@ -109,7 +109,7 @@ impl Theme { let base = base.into(); // Convert to HSL color for manipulation - let hsl = Hsl::from_color(Rgb::from(base)); + let hsl = Hsl::from_color(to_rgb(base)); let lower = [ hsl.shift_hue(-135.0).lighten(0.075), @@ -128,12 +128,12 @@ impl Theme { Theme { lower: lower .iter() - .map(|&color| Rgb::from_color(color).into()) + .map(|&color| to_color(Rgb::from_color(color))) .collect(), base, higher: higher .iter() - .map(|&color| Rgb::from_color(color).into()) + .map(|&color| to_color(Rgb::from_color(color))) .collect(), canvas_cache: canvas::Cache::default(), } @@ -216,14 +216,14 @@ impl Theme { text.align_y = alignment::Vertical::Bottom; - let hsl = Hsl::from_color(Rgb::from(self.base)); + let hsl = Hsl::from_color(to_rgb(self.base)); for i in 0..self.len() { let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0); let graded = Hsl { lightness: 1.0 - pct, ..hsl }; - let color: Color = Rgb::from_color(graded).into(); + let color: Color = to_color(Rgb::from_color(graded)); let anchor = Point { x: (i as f32) * box_size.width, @@ -475,3 +475,21 @@ impl ColorSpace for palette::Lch { ) } } + +fn to_rgb(color: Color) -> Rgb { + Rgb { + red: color.r, + green: color.g, + blue: color.b, + ..Rgb::default() + } +} + +fn to_color(rgb: Rgb) -> Color { + Color { + r: rgb.red, + g: rgb.green, + b: rgb.blue, + a: 1.0, + } +} From 9ac50ad094aa9e10dee33263f5d912dd00779042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 1 Apr 2025 03:13:02 +0200 Subject: [PATCH 03/18] Use `cloned` in `styling` test --- examples/styling/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 322b2b94..b0adc8e8 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -180,14 +180,14 @@ mod tests { fn it_showcases_every_theme() -> Result<(), Error> { Theme::ALL .par_iter() + .cloned() .map(|theme| { let mut styling = Styling::default(); - styling.update(Message::ThemeChanged(theme.clone())); + styling.update(Message::ThemeChanged(theme)); let theme = styling.theme(); let mut ui = simulator(styling.view()); - let snapshot = ui.snapshot(&theme)?; assert!( From 5f00aef426a19913cb611aef496905cc15bde6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 1 Apr 2025 08:20:59 +0200 Subject: [PATCH 04/18] Remove `approx` dependency and update `Cargo.lock` --- Cargo.lock | 436 +++++++++++++++++++++++++++++++----------------- core/Cargo.toml | 3 - 2 files changed, 285 insertions(+), 154 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 143d8771..429175c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3" +checksum = "de3d60bee1a1d38c2077030f4788e1b4e31058d2e79a8cfc8f2b440bd44db290" dependencies = [ "async-fs 2.1.2", "async-net 2.0.0", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "async-std" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" dependencies = [ "async-channel 1.9.0", "async-global-executor", @@ -472,9 +472,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.87" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -702,9 +702,9 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.8.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", @@ -731,9 +731,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2c12f985c78475a6b8d629afd0c360260ef34cfef52efccdcfd31972f81c2e" +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "cairo-sys-rs" @@ -779,9 +779,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -880,18 +880,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.31" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" dependencies = [ "anstyle", "clap_lex", @@ -1097,9 +1097,9 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529a7d4dccf42dd5e93dc3d2e66c7c9121b9779ac8886d2582d0df48fdfcc407" +checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892" dependencies = [ "bitflags 2.9.0", "fontdb 0.16.2", @@ -1298,9 +1298,9 @@ checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", ] @@ -1551,9 +1551,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener 5.4.0", "pin-project-lite", @@ -1655,15 +1655,15 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "font-types" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d868ec188a98bb014c606072edd47e52e7ab7297db943b0b28503121e1d037bd" +checksum = "1fa6a5e5a77b5f3f7f9e32879f484aa5b3632ddfbe568a16266c904a6f32cdaf" dependencies = [ "bytemuck", ] @@ -1980,14 +1980,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -2210,7 +2210,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.2.0", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -2220,9 +2220,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "cfg-if", "crunchy", @@ -2325,9 +2325,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -2352,18 +2352,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.2.0", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", - "http 1.2.0", + "futures-core", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] @@ -2397,7 +2397,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.8", + "socket2 0.5.9", "tokio", "tower-service", "tracing", @@ -2414,7 +2414,7 @@ dependencies = [ "futures-channel", "futures-util", "h2 0.4.8", - "http 1.2.0", + "http 1.3.1", "http-body 1.0.1", "httparse", "itoa", @@ -2431,10 +2431,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http 1.2.0", + "http 1.3.1", "hyper 1.6.0", "hyper-util", - "rustls 0.23.23", + "rustls 0.23.25", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", @@ -2459,18 +2459,19 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body 1.0.1", "hyper 1.6.0", + "libc", "pin-project-lite", - "socket2 0.5.8", + "socket2 0.5.9", "tokio", "tower-service", "tracing", @@ -2478,16 +2479,17 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.61.0", ] [[package]] @@ -2519,7 +2521,6 @@ dependencies = [ name = "iced_core" version = "0.14.0-dev" dependencies = [ - "approx", "bitflags 2.9.0", "bytes", "dark-light", @@ -2721,9 +2722,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -2745,9 +2746,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -2766,9 +2767,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -2821,9 +2822,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.5" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" dependencies = [ "bytemuck", "byteorder-lite", @@ -2866,9 +2867,9 @@ checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", @@ -3109,9 +3110,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libfuzzer-sys" @@ -3152,9 +3153,9 @@ dependencies = [ [[package]] name = "lilt" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab94c7e69044511f79ce4b4201a49324b7f5b35410f862264e044690b950a67" +checksum = "f67562e5eff6b20553fa9be1c503356768420994e28f67e3eafe6f41910e57ad" dependencies = [ "web-time", ] @@ -3185,9 +3186,9 @@ checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" [[package]] name = "linux-raw-sys" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" @@ -3221,9 +3222,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" dependencies = [ "value-bag", ] @@ -3952,9 +3953,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "onig" @@ -4308,9 +4309,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" dependencies = [ "base64 0.22.1", "indexmap", @@ -4415,7 +4416,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.23", + "zerocopy 0.8.24", ] [[package]] @@ -4539,22 +4540,28 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.2" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" +checksum = "bf763ab1c7a3aa408be466efc86efe35ed1bd3dd74173ed39d6b0d0a6f0ba148" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -4574,7 +4581,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.23", + "zerocopy 0.8.24", ] [[package]] @@ -4612,7 +4619,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", ] [[package]] @@ -4785,9 +4792,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest" -version = "0.12.12" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", "bytes", @@ -4795,7 +4802,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.4.8", - "http 1.2.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.6.0", @@ -4879,9 +4886,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.13" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", @@ -4944,14 +4951,14 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys 0.9.2", + "linux-raw-sys 0.9.3", "windows-sys 0.59.0", ] @@ -4964,20 +4971,20 @@ dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "once_cell", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.1", "subtle", "zeroize", ] @@ -5008,6 +5015,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.20" @@ -5399,9 +5417,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5688,15 +5706,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.18.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand 2.3.0", - "getrandom 0.3.1", + "getrandom 0.3.2", "once_cell", - "rustix 1.0.2", + "rustix 1.0.3", "windows-sys 0.59.0", ] @@ -5781,9 +5798,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -5796,15 +5813,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -5909,9 +5926,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -5919,7 +5936,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.8", + "socket2 0.5.9", "windows-sys 0.52.0", ] @@ -5950,7 +5967,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.23", + "rustls 0.23.25", "tokio", ] @@ -5968,9 +5985,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -6149,7 +6166,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.2.0", + "http 1.3.1", "httparse", "log", "rand 0.8.5", @@ -6322,11 +6339,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.15.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", "js-sys", "rand 0.9.0", "serde", @@ -6352,9 +6369,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" [[package]] name = "vcpkg" @@ -6459,9 +6476,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -6657,7 +6674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", - "quick-xml 0.37.2", + "quick-xml 0.37.3", "quote", ] @@ -6737,9 +6754,9 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" -version = "24.0.1" +version = "24.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47f55718f85c2fa756edffa0e7f0e0a60aba463d1362b57e23123c58f035e4b6" +checksum = "35904fb00ba2d2e0a4d002fcbbb6e1b89b574d272a50e5fc95f6e81cf281c245" dependencies = [ "arrayvec", "bitflags 2.9.0", @@ -6909,15 +6926,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.57.0" @@ -6939,10 +6947,23 @@ dependencies = [ "windows-implement 0.58.0", "windows-interface 0.58.0", "windows-result 0.2.0", - "windows-strings", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.2", + "windows-strings 0.4.0", +] + [[package]] name = "windows-implement" version = "0.57.0" @@ -6965,6 +6986,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.57.0" @@ -6988,20 +7020,31 @@ dependencies = [ ] [[package]] -name = "windows-link" -version = "0.1.0" +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-registry" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result 0.2.0", - "windows-strings", - "windows-targets 0.52.6", + "windows-result 0.3.2", + "windows-strings 0.3.1", + "windows-targets 0.53.0", ] [[package]] @@ -7022,6 +7065,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.1.0" @@ -7032,6 +7084,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -7107,13 +7177,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -7132,6 +7218,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -7150,6 +7242,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -7168,12 +7266,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -7192,6 +7302,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -7210,6 +7326,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -7228,6 +7350,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -7246,6 +7374,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winit" version = "0.30.8" @@ -7299,9 +7433,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] @@ -7318,9 +7452,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.9.0", ] @@ -7541,11 +7675,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "zerocopy-derive 0.8.23", + "zerocopy-derive 0.8.24", ] [[package]] @@ -7561,9 +7695,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", diff --git a/core/Cargo.toml b/core/Cargo.toml index 60920e46..fff5ac09 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -31,6 +31,3 @@ web-time.workspace = true dark-light.workspace = true dark-light.optional = true - -[dev-dependencies] -approx = "0.5" From a3a7503eef5ffe2144dde774aa0ca1b7178299c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 09:03:02 +0200 Subject: [PATCH 05/18] Update `smol` dependency to `2.0` --- Cargo.lock | 301 +++++++++++------------------------------------------ Cargo.toml | 2 +- 2 files changed, 64 insertions(+), 239 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 429175c6..9606b9a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -193,8 +193,8 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3d60bee1a1d38c2077030f4788e1b4e31058d2e79a8cfc8f2b440bd44db290" dependencies = [ - "async-fs 2.1.2", - "async-net 2.0.0", + "async-fs", + "async-net", "enumflags2", "futures-channel", "futures-util", @@ -248,32 +248,20 @@ checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.3.0", - "futures-lite 2.6.0", + "fastrand", + "futures-lite", "slab", ] -[[package]] -name = "async-fs" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "blocking", - "futures-lite 1.13.0", -] - [[package]] name = "async-fs" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock 3.4.0", + "async-lock", "blocking", - "futures-lite 2.6.0", + "futures-lite", ] [[package]] @@ -284,61 +272,32 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.3.1", "async-executor", - "async-io 2.4.0", - "async-lock 3.4.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.6.0", + "futures-lite", "once_cell", ] -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.28", - "slab", - "socket2 0.4.10", - "waker-fn", -] - [[package]] name = "async-io" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ - "async-lock 3.4.0", + "async-lock", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.6.0", + "futures-lite", "parking", - "polling 3.7.4", + "polling", "rustix 0.38.44", "slab", "tracing", "windows-sys 0.59.0", ] -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - [[package]] name = "async-lock" version = "3.4.0" @@ -350,43 +309,15 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-net" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" -dependencies = [ - "async-io 1.13.0", - "blocking", - "futures-lite 1.13.0", -] - [[package]] name = "async-net" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io 2.4.0", + "async-io", "blocking", - "futures-lite 2.6.0", -] - -[[package]] -name = "async-process" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" -dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", - "async-signal", - "blocking", - "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.44", - "windows-sys 0.48.0", + "futures-lite", ] [[package]] @@ -396,14 +327,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ "async-channel 2.3.1", - "async-io 2.4.0", - "async-lock 3.4.0", + "async-io", + "async-lock", "async-signal", "async-task", "blocking", "cfg-if", "event-listener 5.4.0", - "futures-lite 2.6.0", + "futures-lite", "rustix 0.38.44", "tracing", ] @@ -425,8 +356,8 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.4.0", - "async-lock 3.4.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", @@ -445,14 +376,14 @@ checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" dependencies = [ "async-channel 1.9.0", "async-global-executor", - "async-io 2.4.0", - "async-lock 3.4.0", - "async-process 2.3.0", + "async-io", + "async-lock", + "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 2.6.0", + "futures-lite", "gloo-timers", "kv-log-macro", "log", @@ -663,7 +594,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.6.0", + "futures-lite", "piper", ] @@ -753,7 +684,7 @@ checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ "bitflags 2.9.0", "log", - "polling 3.7.4", + "polling", "rustix 0.38.44", "slab", "thiserror 1.0.69", @@ -880,18 +811,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstyle", "clap_lex", @@ -1527,17 +1458,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "event-listener" version = "5.4.0" @@ -1594,15 +1514,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.3.0" @@ -1627,9 +1538,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -1805,28 +1716,13 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ - "fastrand 2.3.0", + "fastrand", "futures-core", "futures-io", "parking", @@ -2397,7 +2293,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.9", + "socket2", "tokio", "tower-service", "tracing", @@ -2471,7 +2367,7 @@ dependencies = [ "hyper 1.6.0", "libc", "pin-project-lite", - "socket2 0.5.9", + "socket2", "tokio", "tower-service", "tracing", @@ -2875,15 +2771,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "integration" version = "0.1.0" @@ -2909,17 +2796,6 @@ dependencies = [ "syn", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -3004,10 +2880,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] @@ -3166,12 +3043,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -4297,7 +4168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.3.0", + "fastrand", "futures-io", ] @@ -4373,22 +4244,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - [[package]] name = "polling" version = "3.7.4" @@ -4540,9 +4395,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.3" +version = "0.37.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf763ab1c7a3aa408be466efc86efe35ed1bd3dd74173ed39d6b0d0a6f0ba148" +checksum = "a4ce8c88de324ff838700f36fb6ab86c96df0e3c4ab6ef3a9b2044465cce1369" dependencies = [ "memchr", ] @@ -4922,20 +4777,6 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustix" -version = "0.37.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - [[package]] name = "rustix" version = "0.38.44" @@ -4951,9 +4792,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", @@ -5381,19 +5222,19 @@ dependencies = [ [[package]] name = "smol" -version = "1.3.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.3.1", "async-executor", - "async-fs 1.6.0", - "async-io 1.13.0", - "async-lock 2.8.0", - "async-net 1.8.0", - "async-process 1.8.1", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", "blocking", - "futures-lite 1.13.0", + "futures-lite", ] [[package]] @@ -5405,16 +5246,6 @@ dependencies = [ "serde", ] -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.9" @@ -5436,7 +5267,7 @@ dependencies = [ "cfg_aliases", "core-graphics 0.24.0", "drm", - "fastrand 2.3.0", + "fastrand", "foreign-types 0.5.0", "js-sys", "log", @@ -5571,9 +5402,9 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d5bbc2aa266907ed8ee977c9c9e16363cc2b001266104e13397b57f1d15f71" +checksum = "fae9a562c7b46107d9c78cd78b75bbe1e991c16734c0aee8ff0ee711fb8b620a" dependencies = [ "skrifa", "yazi", @@ -5710,10 +5541,10 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "fastrand 2.3.0", + "fastrand", "getrandom 0.3.2", "once_cell", - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -5936,7 +5767,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.9", + "socket2", "windows-sys 0.52.0", ] @@ -6414,12 +6245,6 @@ dependencies = [ "maybe_parallel_iterator", ] -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - [[package]] name = "walkdir" version = "2.5.0" @@ -6674,7 +6499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", - "quick-xml 0.37.3", + "quick-xml 0.37.4", "quote", ] @@ -7603,10 +7428,10 @@ checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236" dependencies = [ "async-broadcast", "async-executor", - "async-fs 2.1.2", - "async-io 2.4.0", - "async-lock 3.4.0", - "async-process 2.3.0", + "async-fs", + "async-io", + "async-lock", + "async-process", "async-recursion", "async-task", "async-trait", @@ -7614,7 +7439,7 @@ dependencies = [ "enumflags2", "event-listener 5.4.0", "futures-core", - "futures-lite 2.6.0", + "futures-lite", "hex", "nix", "ordered-stream", diff --git a/Cargo.toml b/Cargo.toml index 056f8a7e..c5e8f865 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -172,7 +172,7 @@ resvg = "0.42" rustc-hash = "2.0" sha2 = "0.10" sipper = "0.1" -smol = "1.0" +smol = "2" smol_str = "0.2" softbuffer = "0.4" syntect = "5.1" From baadcc150f54012668f5484f5fbe8dd2516ebb10 Mon Sep 17 00:00:00 2001 From: edwloef Date: Thu, 13 Mar 2025 23:12:44 +0100 Subject: [PATCH 06/18] don't use futures-executor when it's not the default executor --- Cargo.lock | 1 + Cargo.toml | 6 ++++-- examples/integration/Cargo.toml | 3 +++ futures/src/backend/native/async_std.rs | 4 ++++ futures/src/backend/native/smol.rs | 4 ++++ futures/src/backend/native/thread_pool.rs | 4 ++++ futures/src/backend/native/tokio.rs | 7 +++++++ futures/src/backend/null.rs | 6 ++++++ futures/src/backend/wasm/wasm_bindgen.rs | 4 ++++ futures/src/executor.rs | 3 +++ runtime/Cargo.toml | 1 - winit/src/program.rs | 10 +--------- 12 files changed, 41 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9606b9a6..ae3436ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2777,6 +2777,7 @@ version = "0.1.0" dependencies = [ "console_error_panic_hook", "console_log", + "futures", "iced_wgpu", "iced_widget", "iced_winit", diff --git a/Cargo.toml b/Cargo.toml index c5e8f865..f5527e53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ all-features = true maintenance = { status = "actively-developed" } [features] -default = ["wgpu", "tiny-skia", "auto-detect-theme"] +default = ["wgpu", "tiny-skia", "auto-detect-theme", "futures-executor"] # Enables the `wgpu` GPU-accelerated renderer backend wgpu = ["iced_renderer/wgpu", "iced_widget/wgpu"] # Enables the `tiny-skia` software renderer backend @@ -43,6 +43,8 @@ markdown = ["iced_widget/markdown"] lazy = ["iced_widget/lazy"] # Enables a debug view in native platforms (press F12) debug = ["iced_winit/debug"] +# Enables `futures-executor` as the `executor::Default` on native platforms +futures-executor = ["iced_futures/thread-pool"] # Enables `tokio` as the `executor::Default` on native platforms tokio = ["iced_futures/tokio"] # Enables `async-std` as the `executor::Default` on native platforms @@ -150,7 +152,7 @@ bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" cosmic-text = "0.13" dark-light = "2.0" -futures = "0.3" +futures = { version = "0.3", default-features = false, features = ["std", "async-await"] } glam = "0.25" cryoglyph = { git = "https://github.com/iced-rs/cryoglyph.git", rev = "be2defe4a13fd7c97c6f4c81e8e085463eb578dc" } guillotiere = "0.6" diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index 3bdf9408..2b5f99e4 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -12,6 +12,9 @@ iced_wgpu.workspace = true iced_widget.workspace = true iced_widget.features = ["wgpu"] +futures.workspace = true +futures.features = ["thread-pool"] + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tracing-subscriber = "0.3" diff --git a/futures/src/backend/native/async_std.rs b/futures/src/backend/native/async_std.rs index be258b26..9acafd9c 100644 --- a/futures/src/backend/native/async_std.rs +++ b/futures/src/backend/native/async_std.rs @@ -13,6 +13,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { let _ = async_std::task::spawn(future); } + + fn block_on(future: impl Future + 'static) { + async_std::task::block_on(future); + } } pub mod time { diff --git a/futures/src/backend/native/smol.rs b/futures/src/backend/native/smol.rs index 9ac6a27d..27998e8f 100644 --- a/futures/src/backend/native/smol.rs +++ b/futures/src/backend/native/smol.rs @@ -12,6 +12,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { smol::spawn(future).detach(); } + + fn block_on(future: impl Future + 'static) { + smol::block_on(future); + } } pub mod time { diff --git a/futures/src/backend/native/thread_pool.rs b/futures/src/backend/native/thread_pool.rs index a90cc53a..92004bc7 100644 --- a/futures/src/backend/native/thread_pool.rs +++ b/futures/src/backend/native/thread_pool.rs @@ -11,6 +11,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { self.spawn_ok(future); } + + fn block_on(future: impl Future + 'static) { + futures::executor::block_on(future); + } } pub mod time { diff --git a/futures/src/backend/native/tokio.rs b/futures/src/backend/native/tokio.rs index 911d788c..0670c5ee 100644 --- a/futures/src/backend/native/tokio.rs +++ b/futures/src/backend/native/tokio.rs @@ -17,6 +17,13 @@ impl crate::Executor for Executor { let _guard = tokio::runtime::Runtime::enter(self); f() } + + fn block_on(future: impl Future + 'static) { + tokio::runtime::Builder::new_current_thread() + .build() + .unwrap() + .block_on(future); + } } pub mod time { diff --git a/futures/src/backend/null.rs b/futures/src/backend/null.rs index f31415b9..151d5587 100644 --- a/futures/src/backend/null.rs +++ b/futures/src/backend/null.rs @@ -14,6 +14,12 @@ impl crate::Executor for Executor { #[cfg(target_arch = "wasm32")] fn spawn(&self, _future: impl Future + 'static) {} + + #[cfg(not(target_arch = "wasm32"))] + fn block_on(_future: impl Future + 'static) {} + + #[cfg(target_arch = "wasm32")] + fn block_on(_future: impl Future + 'static) {} } pub mod time { diff --git a/futures/src/backend/wasm/wasm_bindgen.rs b/futures/src/backend/wasm/wasm_bindgen.rs index 4811e7f4..667bf2fa 100644 --- a/futures/src/backend/wasm/wasm_bindgen.rs +++ b/futures/src/backend/wasm/wasm_bindgen.rs @@ -12,6 +12,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl futures::Future + 'static) { wasm_bindgen_futures::spawn_local(future); } + + fn block_on(future: impl futures::Future + 'static) { + wasm_bindgen_futures::spawn_local(future); + } } pub mod time { diff --git a/futures/src/executor.rs b/futures/src/executor.rs index 9c14a2c9..22ed4212 100644 --- a/futures/src/executor.rs +++ b/futures/src/executor.rs @@ -20,4 +20,7 @@ pub trait Executor: Sized { fn enter(&self, f: impl FnOnce() -> R) -> R { f() } + + /// Runs the future on the current thread, blocking it until it is completed. + fn block_on(future: impl Future + 'static); } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index fc212ef8..35704e0f 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -21,7 +21,6 @@ multi-window = [] bytes.workspace = true iced_core.workspace = true iced_futures.workspace = true -iced_futures.features = ["thread-pool"] raw-window-handle.workspace = true sipper.workspace = true diff --git a/winit/src/program.rs b/winit/src/program.rs index 6904c02a..ee921adb 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -662,15 +662,7 @@ async fn run_instance( } }; - #[cfg(not(target_arch = "wasm32"))] - crate::futures::futures::executor::block_on( - create_compositor, - ); - - #[cfg(target_arch = "wasm32")] - { - wasm_bindgen_futures::spawn_local(create_compositor); - } + P::Executor::block_on(create_compositor); continue; } From 57cb14ce38360a885c2fb7e5d1e7a52797b7e73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 10:39:27 +0200 Subject: [PATCH 07/18] Remove `Executor::block_on` and simplify `Compositor` creation --- Cargo.toml | 8 +-- futures/Cargo.toml | 2 + futures/src/backend/native/async_std.rs | 4 -- futures/src/backend/native/smol.rs | 4 -- futures/src/backend/native/thread_pool.rs | 4 -- futures/src/backend/native/tokio.rs | 7 -- futures/src/backend/null.rs | 13 +--- futures/src/backend/wasm/wasm_bindgen.rs | 4 -- futures/src/executor.rs | 3 - futures/src/runtime.rs | 20 ++---- graphics/src/compositor.rs | 6 +- src/lib.rs | 7 ++ winit/src/program.rs | 84 ++++++++++------------- 13 files changed, 58 insertions(+), 108 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f5527e53..5df2f12b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ all-features = true maintenance = { status = "actively-developed" } [features] -default = ["wgpu", "tiny-skia", "auto-detect-theme", "futures-executor"] +default = ["wgpu", "tiny-skia", "auto-detect-theme", "thread-pool"] # Enables the `wgpu` GPU-accelerated renderer backend wgpu = ["iced_renderer/wgpu", "iced_widget/wgpu"] # Enables the `tiny-skia` software renderer backend @@ -43,8 +43,8 @@ markdown = ["iced_widget/markdown"] lazy = ["iced_widget/lazy"] # Enables a debug view in native platforms (press F12) debug = ["iced_winit/debug"] -# Enables `futures-executor` as the `executor::Default` on native platforms -futures-executor = ["iced_futures/thread-pool"] +# Enables the `thread-pool` futures executor as the `executor::Default` on native platforms +thread-pool = ["iced_futures/thread-pool"] # Enables `tokio` as the `executor::Default` on native platforms tokio = ["iced_futures/tokio"] # Enables `async-std` as the `executor::Default` on native platforms @@ -152,7 +152,7 @@ bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" cosmic-text = "0.13" dark-light = "2.0" -futures = { version = "0.3", default-features = false, features = ["std", "async-await"] } +futures = { version = "0.3", default-features = false } glam = "0.25" cryoglyph = { git = "https://github.com/iced-rs/cryoglyph.git", rev = "be2defe4a13fd7c97c6f4c81e8e085463eb578dc" } guillotiere = "0.6" diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 3984ce83..6a49e9e8 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -24,6 +24,8 @@ thread-pool = ["futures/thread-pool"] iced_core.workspace = true futures.workspace = true +futures.features = ["std"] + log.workspace = true rustc-hash.workspace = true diff --git a/futures/src/backend/native/async_std.rs b/futures/src/backend/native/async_std.rs index 9acafd9c..be258b26 100644 --- a/futures/src/backend/native/async_std.rs +++ b/futures/src/backend/native/async_std.rs @@ -13,10 +13,6 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { let _ = async_std::task::spawn(future); } - - fn block_on(future: impl Future + 'static) { - async_std::task::block_on(future); - } } pub mod time { diff --git a/futures/src/backend/native/smol.rs b/futures/src/backend/native/smol.rs index 27998e8f..9ac6a27d 100644 --- a/futures/src/backend/native/smol.rs +++ b/futures/src/backend/native/smol.rs @@ -12,10 +12,6 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { smol::spawn(future).detach(); } - - fn block_on(future: impl Future + 'static) { - smol::block_on(future); - } } pub mod time { diff --git a/futures/src/backend/native/thread_pool.rs b/futures/src/backend/native/thread_pool.rs index 92004bc7..a90cc53a 100644 --- a/futures/src/backend/native/thread_pool.rs +++ b/futures/src/backend/native/thread_pool.rs @@ -11,10 +11,6 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { self.spawn_ok(future); } - - fn block_on(future: impl Future + 'static) { - futures::executor::block_on(future); - } } pub mod time { diff --git a/futures/src/backend/native/tokio.rs b/futures/src/backend/native/tokio.rs index 0670c5ee..911d788c 100644 --- a/futures/src/backend/native/tokio.rs +++ b/futures/src/backend/native/tokio.rs @@ -17,13 +17,6 @@ impl crate::Executor for Executor { let _guard = tokio::runtime::Runtime::enter(self); f() } - - fn block_on(future: impl Future + 'static) { - tokio::runtime::Builder::new_current_thread() - .build() - .unwrap() - .block_on(future); - } } pub mod time { diff --git a/futures/src/backend/null.rs b/futures/src/backend/null.rs index 151d5587..59b740e3 100644 --- a/futures/src/backend/null.rs +++ b/futures/src/backend/null.rs @@ -1,4 +1,5 @@ //! A backend that does nothing! +use crate::MaybeSend; /// An executor that drops all the futures, instead of spawning them. #[derive(Debug)] @@ -9,17 +10,7 @@ impl crate::Executor for Executor { Ok(Self) } - #[cfg(not(target_arch = "wasm32"))] - fn spawn(&self, _future: impl Future + Send + 'static) {} - - #[cfg(target_arch = "wasm32")] - fn spawn(&self, _future: impl Future + 'static) {} - - #[cfg(not(target_arch = "wasm32"))] - fn block_on(_future: impl Future + 'static) {} - - #[cfg(target_arch = "wasm32")] - fn block_on(_future: impl Future + 'static) {} + fn spawn(&self, _future: impl Future + MaybeSend + 'static) {} } pub mod time { diff --git a/futures/src/backend/wasm/wasm_bindgen.rs b/futures/src/backend/wasm/wasm_bindgen.rs index 667bf2fa..4811e7f4 100644 --- a/futures/src/backend/wasm/wasm_bindgen.rs +++ b/futures/src/backend/wasm/wasm_bindgen.rs @@ -12,10 +12,6 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl futures::Future + 'static) { wasm_bindgen_futures::spawn_local(future); } - - fn block_on(future: impl futures::Future + 'static) { - wasm_bindgen_futures::spawn_local(future); - } } pub mod time { diff --git a/futures/src/executor.rs b/futures/src/executor.rs index 22ed4212..9c14a2c9 100644 --- a/futures/src/executor.rs +++ b/futures/src/executor.rs @@ -20,7 +20,4 @@ pub trait Executor: Sized { fn enter(&self, f: impl FnOnce() -> R) -> R { f() } - - /// Runs the future on the current thread, blocking it until it is completed. - fn block_on(future: impl Future + 'static); } diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index 0f30b469..72252458 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -1,6 +1,6 @@ //! Run commands and keep track of subscriptions. use crate::subscription; -use crate::{BoxFuture, BoxStream, Executor, MaybeSend}; +use crate::{BoxStream, Executor, MaybeSend}; use futures::{Sink, channel::mpsc}; use std::marker::PhantomData; @@ -51,20 +51,10 @@ where } /// Spawns a [`Future`] in the [`Runtime`]. - /// - /// The resulting `Message` will be forwarded to the `Sender` of the - /// [`Runtime`]. - /// - /// [`Future`]: BoxFuture - pub fn spawn(&mut self, future: BoxFuture) { - use futures::{FutureExt, SinkExt}; - - let mut sender = self.sender.clone(); - - let future = future.then(|message| async move { - let _ = sender.send(message).await; - }); - + pub fn spawn( + &mut self, + future: impl Future + MaybeSend + 'static, + ) { self.executor.spawn(future); } diff --git a/graphics/src/compositor.rs b/graphics/src/compositor.rs index e9063678..f0f67607 100644 --- a/graphics/src/compositor.rs +++ b/graphics/src/compositor.rs @@ -10,7 +10,7 @@ use thiserror::Error; use std::borrow::Cow; /// A graphics compositor that can draw to windows. -pub trait Compositor: Sized { +pub trait Compositor: Sized + MaybeSend { /// The iced renderer of the backend. type Renderer; @@ -21,7 +21,7 @@ pub trait Compositor: Sized { fn new( settings: Settings, compatible_window: W, - ) -> impl Future> { + ) -> impl Future> + MaybeSend { Self::with_backend(settings, compatible_window, None) } @@ -33,7 +33,7 @@ pub trait Compositor: Sized { _settings: Settings, _compatible_window: W, _backend: Option<&str>, - ) -> impl Future>; + ) -> impl Future> + MaybeSend; /// Creates a [`Self::Renderer`] for the [`Compositor`]. fn create_renderer(&self) -> Self::Renderer; diff --git a/src/lib.rs b/src/lib.rs index 95820ed7..9b3f3788 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -480,6 +480,13 @@ use iced_winit::runtime; pub use iced_futures::futures; pub use iced_futures::stream; +#[cfg(not(any(feature = "thread-pool", feature = "tokio", feature = "smol")))] +compile_error!( + "No futures executor has been enabled! You must enable an + executor feature.\n + Available options: thread-pool, tokio, smol, or async-std." +); + #[cfg(feature = "highlighter")] pub use iced_highlighter as highlighter; diff --git a/winit/src/program.rs b/winit/src/program.rs index ee921adb..77b4f9d7 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -18,7 +18,7 @@ use crate::futures::futures::channel::oneshot; use crate::futures::futures::task; use crate::futures::futures::{Future, StreamExt}; use crate::futures::subscription::{self, Subscription}; -use crate::futures::{Executor, Runtime}; +use crate::futures::{Executor, MaybeSend, Runtime}; use crate::graphics; use crate::graphics::{Compositor, compositor}; use crate::runtime::Debug; @@ -149,7 +149,7 @@ pub fn run( ) -> Result<(), Error> where P: Program + 'static, - C: Compositor + 'static, + C: Compositor + MaybeSend + 'static, P::Theme: theme::Base, { use winit::event_loop::EventLoop; @@ -494,9 +494,7 @@ where event_loop.exit(); } }, - _ => { - break; - } + _ => break, }, task::Poll::Ready(_) => { event_loop.exit(); @@ -562,7 +560,7 @@ async fn run_instance( default_fonts: Vec>, ) where P: Program + 'static, - C: Compositor + 'static, + C: Compositor + MaybeSend + 'static, P::Theme: theme::Base, { use winit::event; @@ -579,35 +577,11 @@ async fn run_instance( let mut ui_caches = FxHashMap::default(); let mut user_interfaces = ManuallyDrop::new(FxHashMap::default()); let mut clipboard = Clipboard::unconnected(); - let mut compositor_receiver: Option> = None; debug.startup_finished(); loop { - let event = if compositor_receiver.is_some() { - let compositor_receiver = - compositor_receiver.take().expect("Waiting for compositor"); - - match compositor_receiver.await { - Ok(Ok((new_compositor, event))) => { - compositor = Some(new_compositor); - - Some(event) - } - Ok(Err(error)) => { - control_sender - .start_send(Control::Crash( - Error::GraphicsCreationFailed(error), - )) - .expect("Send control action"); - break; - } - Err(error) => { - panic!("Compositor initialization failed: {error}") - } - } - // Empty the queue if possible - } else if let Ok(event) = event_receiver.try_next() { + let event = if let Ok(event) = event_receiver.try_next() { event } else { event_receiver.next().await @@ -626,17 +600,17 @@ async fn run_instance( on_open, } => { if compositor.is_none() { - let (compositor_sender, new_compositor_receiver) = + let (compositor_sender, compositor_receiver) = oneshot::channel(); - compositor_receiver = Some(new_compositor_receiver); - let create_compositor = { + let window = window.clone(); + let mut proxy = proxy.clone(); let default_fonts = default_fonts.clone(); async move { let mut compositor = - C::new(graphics_settings, window.clone()).await; + C::new(graphics_settings, window).await; if let Ok(compositor) = &mut compositor { for font in default_fonts { @@ -645,26 +619,38 @@ async fn run_instance( } compositor_sender - .send(compositor.map(|compositor| { - ( - compositor, - Event::WindowCreated { - id, - window, - exit_on_close_request, - make_visible, - on_open, - }, - ) - })) + .send(compositor) .ok() .expect("Send compositor"); + + // HACK! Send a proxy event on completion to trigger + // a runtime re-poll + // TODO: Send compositor through proxy (?) + { + let (sender, _receiver) = oneshot::channel(); + + proxy.send_action(Action::Window( + runtime::window::Action::GetLatest(sender), + )); + } } }; - P::Executor::block_on(create_compositor); + runtime.spawn(create_compositor); - continue; + match compositor_receiver + .await + .expect("Wait for compositor") + { + Ok(new_compositor) => { + compositor = Some(new_compositor); + } + Err(error) => { + let _ = control_sender + .start_send(Control::Crash(error.into())); + break; + } + } } let window = window_manager.insert( From 91996372cb6bcf686f004ae5b313a28cc2e91ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 10:45:27 +0200 Subject: [PATCH 08/18] Remove `async-std` support (RIP) --- Cargo.lock | 4 +- Cargo.toml | 3 -- examples/todos/Cargo.toml | 4 +- examples/todos/src/main.rs | 27 +++--------- futures/Cargo.toml | 4 -- futures/src/backend/default.rs | 16 ++----- futures/src/backend/native.rs | 3 -- futures/src/backend/native/async_std.rs | 56 ------------------------- 8 files changed, 13 insertions(+), 104 deletions(-) delete mode 100644 futures/src/backend/native/async_std.rs diff --git a/Cargo.lock b/Cargo.lock index ae3436ca..dbcd5060 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,7 +378,6 @@ dependencies = [ "async-global-executor", "async-io", "async-lock", - "async-process", "crossbeam-utils", "futures-channel", "futures-core", @@ -2434,7 +2433,6 @@ dependencies = [ name = "iced_futures" version = "0.14.0-dev" dependencies = [ - "async-std", "futures", "iced_core", "log", @@ -5744,12 +5742,12 @@ dependencies = [ name = "todos" version = "0.1.0" dependencies = [ - "async-std", "directories", "iced", "iced_test", "serde", "serde_json", + "tokio", "tracing-subscriber", "uuid", "wasmtimer", diff --git a/Cargo.toml b/Cargo.toml index 5df2f12b..f7318b98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,8 +47,6 @@ debug = ["iced_winit/debug"] thread-pool = ["iced_futures/thread-pool"] # Enables `tokio` as the `executor::Default` on native platforms tokio = ["iced_futures/tokio"] -# Enables `async-std` as the `executor::Default` on native platforms -async-std = ["iced_futures/async-std"] # Enables `smol` as the `executor::Default` on native platforms smol = ["iced_futures/smol"] # Enables querying system information @@ -146,7 +144,6 @@ iced_wgpu = { version = "0.14.0-dev", path = "wgpu" } iced_widget = { version = "0.14.0-dev", path = "widget" } iced_winit = { version = "0.14.0-dev", path = "winit" } -async-std = "1.0" bitflags = "2.0" bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 77b776d5..981b9e5f 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -7,14 +7,14 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["async-std", "debug"] +iced.features = ["tokio", "debug"] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -async-std.workspace = true +tokio.workspace = true directories = "6.0" tracing-subscriber = "0.3" diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 65a34c64..03e62d3c 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -482,7 +482,6 @@ enum LoadError { #[derive(Debug, Clone)] enum SaveError { - File, Write, Format, } @@ -504,15 +503,7 @@ impl SavedState { } async fn load() -> Result { - use async_std::prelude::*; - - let mut contents = String::new(); - - let mut file = async_std::fs::File::open(Self::path()) - .await - .map_err(|_| LoadError::File)?; - - file.read_to_string(&mut contents) + let contents = tokio::fs::read_to_string(Self::path()) .await .map_err(|_| LoadError::File)?; @@ -520,31 +511,25 @@ impl SavedState { } async fn save(self) -> Result<(), SaveError> { - use async_std::prelude::*; - let json = serde_json::to_string_pretty(&self) .map_err(|_| SaveError::Format)?; let path = Self::path(); if let Some(dir) = path.parent() { - async_std::fs::create_dir_all(dir) + tokio::fs::create_dir_all(dir) .await - .map_err(|_| SaveError::File)?; + .map_err(|_| SaveError::Write)?; } { - let mut file = async_std::fs::File::create(path) - .await - .map_err(|_| SaveError::File)?; - - file.write_all(json.as_bytes()) + tokio::fs::write(path, json.as_bytes()) .await .map_err(|_| SaveError::Write)?; } // This is a simple way to save at most once every couple seconds - async_std::task::sleep(std::time::Duration::from_secs(2)).await; + tokio::time::sleep(std::time::Duration::from_secs(2)).await; Ok(()) } @@ -570,7 +555,7 @@ impl SavedState { } async fn save(self) -> Result<(), SaveError> { - let storage = Self::storage().ok_or(SaveError::File)?; + let storage = Self::storage().ok_or(SaveError::Write)?; let json = serde_json::to_string_pretty(&self) .map_err(|_| SaveError::Format)?; diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 6a49e9e8..e2c342ff 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -30,10 +30,6 @@ log.workspace = true rustc-hash.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -async-std.workspace = true -async-std.optional = true -async-std.features = ["unstable"] - smol.workspace = true smol.optional = true diff --git a/futures/src/backend/default.rs b/futures/src/backend/default.rs index 842b5927..4418834e 100644 --- a/futures/src/backend/default.rs +++ b/futures/src/backend/default.rs @@ -2,10 +2,9 @@ //! //! - On native platforms, it will use: //! - `backend::native::tokio` when the `tokio` feature is enabled. -//! - `backend::native::async-std` when the `async-std` feature is -//! enabled. //! - `backend::native::smol` when the `smol` feature is enabled. -//! - `backend::native::thread_pool` otherwise. +//! - `backend::native::thread_pool` when the `thread-pool` feature is enabled. +//! - `backend::null` otherwise. //! //! - On Wasm, it will use `backend::wasm::wasm_bindgen`. #[cfg(not(target_arch = "wasm32"))] @@ -13,24 +12,17 @@ mod platform { #[cfg(feature = "tokio")] pub use crate::backend::native::tokio::*; - #[cfg(all(feature = "async-std", not(feature = "tokio"),))] - pub use crate::backend::native::async_std::*; - - #[cfg(all( - feature = "smol", - not(any(feature = "tokio", feature = "async-std")), - ))] + #[cfg(all(feature = "smol", not(feature = "tokio"),))] pub use crate::backend::native::smol::*; #[cfg(all( feature = "thread-pool", - not(any(feature = "tokio", feature = "async-std", feature = "smol")) + not(any(feature = "tokio", feature = "smol")) ))] pub use crate::backend::native::thread_pool::*; #[cfg(not(any( feature = "tokio", - feature = "async-std", feature = "smol", feature = "thread-pool" )))] diff --git a/futures/src/backend/native.rs b/futures/src/backend/native.rs index 85af2c88..e5595bdb 100644 --- a/futures/src/backend/native.rs +++ b/futures/src/backend/native.rs @@ -2,9 +2,6 @@ #[cfg(feature = "tokio")] pub mod tokio; -#[cfg(feature = "async-std")] -pub mod async_std; - #[cfg(feature = "smol")] pub mod smol; diff --git a/futures/src/backend/native/async_std.rs b/futures/src/backend/native/async_std.rs deleted file mode 100644 index be258b26..00000000 --- a/futures/src/backend/native/async_std.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! An `async-std` backend. - -/// An `async-std` executor. -#[derive(Debug)] -pub struct Executor; - -impl crate::Executor for Executor { - fn new() -> Result { - Ok(Self) - } - - #[allow(clippy::let_underscore_future)] - fn spawn(&self, future: impl Future + Send + 'static) { - let _ = async_std::task::spawn(future); - } -} - -pub mod time { - //! Listen and react to time. - use crate::subscription::{self, Hasher, Subscription}; - - /// Returns a [`Subscription`] that produces messages at a set interval. - /// - /// The first message is produced after a `duration`, and then continues to - /// produce more messages every `duration` after that. - pub fn every( - duration: std::time::Duration, - ) -> Subscription { - subscription::from_recipe(Every(duration)) - } - - #[derive(Debug)] - struct Every(std::time::Duration); - - impl subscription::Recipe for Every { - type Output = std::time::Instant; - - fn hash(&self, state: &mut Hasher) { - use std::hash::Hash; - - std::any::TypeId::of::().hash(state); - self.0.hash(state); - } - - fn stream( - self: Box, - _input: subscription::EventStream, - ) -> futures::stream::BoxStream<'static, Self::Output> { - use futures::stream::StreamExt; - - async_std::stream::interval(self.0) - .map(|_| std::time::Instant::now()) - .boxed() - } - } -} From cf827dd349f28bdab82f71c0d33791d67480c0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 10:46:25 +0200 Subject: [PATCH 09/18] Allow disabling all executor features on Wasm builds --- src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 9b3f3788..2d4b6b69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -480,7 +480,12 @@ use iced_winit::runtime; pub use iced_futures::futures; pub use iced_futures::stream; -#[cfg(not(any(feature = "thread-pool", feature = "tokio", feature = "smol")))] +#[cfg(not(any( + target_arch = "wasm32", + feature = "thread-pool", + feature = "tokio", + feature = "smol" +)))] compile_error!( "No futures executor has been enabled! You must enable an executor feature.\n From 9f1beba5839fad7fa8fe22f37774e0ea900b87e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 10:58:09 +0200 Subject: [PATCH 10/18] Make `sipper` dependency optional --- Cargo.lock | 1 + Cargo.toml | 3 +++ examples/download_progress/Cargo.toml | 2 +- examples/gallery/Cargo.toml | 2 +- examples/websocket/Cargo.toml | 2 +- runtime/Cargo.toml | 4 +++- runtime/src/task.rs | 5 ++++- src/lib.rs | 7 ++++--- 8 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbcd5060..efa3db2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2405,6 +2405,7 @@ dependencies = [ "iced_futures", "iced_highlighter", "iced_renderer", + "iced_runtime", "iced_wgpu", "iced_widget", "iced_winit", diff --git a/Cargo.toml b/Cargo.toml index f7318b98..b13c26f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,11 +67,14 @@ auto-detect-theme = ["iced_core/auto-detect-theme"] strict-assertions = ["iced_renderer/strict-assertions"] # Redraws on every runtime event, and not only when a widget requests it unconditional-rendering = ["iced_winit/unconditional-rendering"] +# Enables support for the `sipper` library +sipper = ["iced_runtime/sipper"] [dependencies] iced_core.workspace = true iced_futures.workspace = true iced_renderer.workspace = true +iced_runtime.workspace = true iced_widget.workspace = true iced_winit.features = ["program"] iced_winit.workspace = true diff --git a/examples/download_progress/Cargo.toml b/examples/download_progress/Cargo.toml index 9c52b2bd..56c538fe 100644 --- a/examples/download_progress/Cargo.toml +++ b/examples/download_progress/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["tokio"] +iced.features = ["tokio", "sipper"] [dependencies.reqwest] version = "0.12" diff --git a/examples/gallery/Cargo.toml b/examples/gallery/Cargo.toml index 5161f368..3dd5d378 100644 --- a/examples/gallery/Cargo.toml +++ b/examples/gallery/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["tokio", "image", "web-colors", "debug"] +iced.features = ["tokio", "sipper", "image", "web-colors", "debug"] reqwest.version = "0.12" reqwest.features = ["json"] diff --git a/examples/websocket/Cargo.toml b/examples/websocket/Cargo.toml index 88ebdae1..c47e3c93 100644 --- a/examples/websocket/Cargo.toml +++ b/examples/websocket/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["debug", "tokio"] +iced.features = ["debug", "tokio", "sipper"] warp = "0.3" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 35704e0f..5fc67b97 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -23,5 +23,7 @@ iced_core.workspace = true iced_futures.workspace = true raw-window-handle.workspace = true -sipper.workspace = true thiserror.workspace = true + +sipper.workspace = true +sipper.optional = true diff --git a/runtime/src/task.rs b/runtime/src/task.rs index fd5970ac..624fc3a7 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -7,8 +7,10 @@ use crate::futures::futures::future::{self, FutureExt}; use crate::futures::futures::stream::{self, Stream, StreamExt}; use crate::futures::{BoxStream, MaybeSend, boxed_stream}; +use std::convert::Infallible; use std::sync::Arc; +#[cfg(feature = "sipper")] #[doc(no_inline)] pub use sipper::{Never, Sender, Sipper, Straw, sipper, stream}; @@ -60,6 +62,7 @@ impl Task { /// Creates a [`Task`] that runs the given [`Sipper`] to completion, mapping /// progress with the first closure and the output with the second one. + #[cfg(feature = "sipper")] pub fn sip( sipper: S, on_progress: impl FnMut(S::Progress) -> T + MaybeSend + 'static, @@ -391,7 +394,7 @@ where } /// Creates a new [`Task`] that executes the given [`Action`] and produces no output. -pub fn effect(action: impl Into>) -> Task { +pub fn effect(action: impl Into>) -> Task { let action = action.into(); Task(Some(boxed_stream(stream::once(async move { diff --git a/src/lib.rs b/src/lib.rs index 2d4b6b69..ebb80282 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -531,9 +531,10 @@ pub use alignment::Vertical::{Bottom, Top}; pub mod task { //! Create runtime tasks. - pub use crate::runtime::task::{ - Handle, Never, Sipper, Straw, Task, sipper, stream, - }; + pub use crate::runtime::task::{Handle, Task}; + + #[cfg(feature = "sipper")] + pub use crate::runtime::task::{Never, Sipper, Straw, sipper, stream}; } pub mod clipboard { From 5b8d92ed5bcb0719ec7ba6d0f067bd669e6d226d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 11:08:23 +0200 Subject: [PATCH 11/18] Remove leftover mentions of `async-std` --- src/lib.rs | 15 ++------------- src/time.rs | 1 - 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ebb80282..dd879bf6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -489,7 +489,7 @@ pub use iced_futures::stream; compile_error!( "No futures executor has been enabled! You must enable an executor feature.\n - Available options: thread-pool, tokio, smol, or async-std." + Available options: thread-pool, tokio, or smol." ); #[cfg(feature = "highlighter")] @@ -547,18 +547,7 @@ pub mod clipboard { pub mod executor { //! Choose your preferred executor to power your application. pub use iced_futures::Executor; - - /// A default cross-platform executor. - /// - /// - On native platforms, it will use: - /// - `iced_futures::backend::native::tokio` when the `tokio` feature is enabled. - /// - `iced_futures::backend::native::async-std` when the `async-std` feature is - /// enabled. - /// - `iced_futures::backend::native::smol` when the `smol` feature is enabled. - /// - `iced_futures::backend::native::thread_pool` otherwise. - /// - /// - On Wasm, it will use `iced_futures::backend::wasm::wasm_bindgen`. - pub type Default = iced_futures::backend::default::Executor; + pub use iced_futures::backend::default::Executor as Default; } pub mod font { diff --git a/src/time.rs b/src/time.rs index 98a800ac..f32eeb17 100644 --- a/src/time.rs +++ b/src/time.rs @@ -6,7 +6,6 @@ pub use crate::core::time::*; docsrs, doc(cfg(any( feature = "tokio", - feature = "async-std", feature = "smol", target_arch = "wasm32" ))) From 5d1de9dc95bd981be122f6442d7d77de80d5d176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 11:50:27 +0200 Subject: [PATCH 12/18] Enable `async-await` feature in `iced_futures` --- futures/Cargo.toml | 2 +- src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/futures/Cargo.toml b/futures/Cargo.toml index e2c342ff..8bc693e9 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -24,7 +24,7 @@ thread-pool = ["futures/thread-pool"] iced_core.workspace = true futures.workspace = true -futures.features = ["std"] +futures.features = ["std", "async-await"] log.workspace = true rustc-hash.workspace = true diff --git a/src/lib.rs b/src/lib.rs index dd879bf6..21543fac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -487,8 +487,8 @@ pub use iced_futures::stream; feature = "smol" )))] compile_error!( - "No futures executor has been enabled! You must enable an - executor feature.\n + "No futures executor has been enabled! You must enable an \ + executor feature.\n\ Available options: thread-pool, tokio, or smol." ); From 15530cd57d8efd83fbc0869560f5021e013bc685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 11:53:48 +0200 Subject: [PATCH 13/18] Enable `fs` feature for `tokio` in `todos` example --- examples/todos/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 981b9e5f..fd3433e6 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -15,6 +15,7 @@ uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio.workspace = true +tokio.features = ["fs", "time"] directories = "6.0" tracing-subscriber = "0.3" From d203392c9d4f565e4f3ae91899cd390c4d947ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 20:19:40 +0200 Subject: [PATCH 14/18] Enable `web-colors` by default Broken color blending is unfortunately the standard, and many fonts simply look terrible without it. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b13c26f4..8392d735 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ all-features = true maintenance = { status = "actively-developed" } [features] -default = ["wgpu", "tiny-skia", "auto-detect-theme", "thread-pool"] +default = ["wgpu", "tiny-skia", "web-colors", "auto-detect-theme", "thread-pool"] # Enables the `wgpu` GPU-accelerated renderer backend wgpu = ["iced_renderer/wgpu", "iced_widget/wgpu"] # Enables the `tiny-skia` software renderer backend From 1b22d7d5fcdf519a3cac7a3cfd14398a3108c3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Apr 2025 20:33:22 +0200 Subject: [PATCH 15/18] Fix `Compositor` concurrent initialization It seems that initializing the compositor in a different thread can cause issues in some environments. --- futures/src/backend/native/smol.rs | 4 ++++ futures/src/backend/native/thread_pool.rs | 4 ++++ futures/src/backend/native/tokio.rs | 4 ++++ futures/src/backend/null.rs | 5 +++++ futures/src/executor.rs | 4 ++++ futures/src/runtime.rs | 10 ++++------ graphics/src/compositor.rs | 6 +++--- winit/src/program.rs | 14 +++++++++----- 8 files changed, 37 insertions(+), 14 deletions(-) diff --git a/futures/src/backend/native/smol.rs b/futures/src/backend/native/smol.rs index 9ac6a27d..3080d5ff 100644 --- a/futures/src/backend/native/smol.rs +++ b/futures/src/backend/native/smol.rs @@ -12,6 +12,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { smol::spawn(future).detach(); } + + fn block_on(&self, future: impl Future) -> T { + smol::block_on(future) + } } pub mod time { diff --git a/futures/src/backend/native/thread_pool.rs b/futures/src/backend/native/thread_pool.rs index a90cc53a..a71ab8c2 100644 --- a/futures/src/backend/native/thread_pool.rs +++ b/futures/src/backend/native/thread_pool.rs @@ -11,6 +11,10 @@ impl crate::Executor for Executor { fn spawn(&self, future: impl Future + Send + 'static) { self.spawn_ok(future); } + + fn block_on(&self, future: impl Future) -> T { + futures::executor::block_on(future) + } } pub mod time { diff --git a/futures/src/backend/native/tokio.rs b/futures/src/backend/native/tokio.rs index 911d788c..93600635 100644 --- a/futures/src/backend/native/tokio.rs +++ b/futures/src/backend/native/tokio.rs @@ -17,6 +17,10 @@ impl crate::Executor for Executor { let _guard = tokio::runtime::Runtime::enter(self); f() } + + fn block_on(&self, future: impl Future) -> T { + self.block_on(future) + } } pub mod time { diff --git a/futures/src/backend/null.rs b/futures/src/backend/null.rs index 59b740e3..67a17d68 100644 --- a/futures/src/backend/null.rs +++ b/futures/src/backend/null.rs @@ -11,6 +11,11 @@ impl crate::Executor for Executor { } fn spawn(&self, _future: impl Future + MaybeSend + 'static) {} + + #[cfg(not(target_arch = "wasm32"))] + fn block_on(&self, _future: impl Future) -> T { + unimplemented!() + } } pub mod time { diff --git a/futures/src/executor.rs b/futures/src/executor.rs index 9c14a2c9..00fecb1a 100644 --- a/futures/src/executor.rs +++ b/futures/src/executor.rs @@ -11,6 +11,10 @@ pub trait Executor: Sized { /// Spawns a future in the [`Executor`]. fn spawn(&self, future: impl Future + MaybeSend + 'static); + /// Runs a future to completion in the current thread within the [`Executor`]. + #[cfg(not(target_arch = "wasm32"))] + fn block_on(&self, future: impl Future) -> T; + /// Runs the given closure inside the [`Executor`]. /// /// Some executors, like `tokio`, require some global state to be in place diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index 72252458..e25ba1d7 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -50,12 +50,10 @@ where self.executor.enter(f) } - /// Spawns a [`Future`] in the [`Runtime`]. - pub fn spawn( - &mut self, - future: impl Future + MaybeSend + 'static, - ) { - self.executor.spawn(future); + /// Runs a future to completion in the current thread within the [`Runtime`]. + #[cfg(not(target_arch = "wasm32"))] + pub fn block_on(&mut self, future: impl Future) -> T { + self.executor.block_on(future) } /// Runs a [`Stream`] in the [`Runtime`] until completion. diff --git a/graphics/src/compositor.rs b/graphics/src/compositor.rs index f0f67607..e9063678 100644 --- a/graphics/src/compositor.rs +++ b/graphics/src/compositor.rs @@ -10,7 +10,7 @@ use thiserror::Error; use std::borrow::Cow; /// A graphics compositor that can draw to windows. -pub trait Compositor: Sized + MaybeSend { +pub trait Compositor: Sized { /// The iced renderer of the backend. type Renderer; @@ -21,7 +21,7 @@ pub trait Compositor: Sized + MaybeSend { fn new( settings: Settings, compatible_window: W, - ) -> impl Future> + MaybeSend { + ) -> impl Future> { Self::with_backend(settings, compatible_window, None) } @@ -33,7 +33,7 @@ pub trait Compositor: Sized + MaybeSend { _settings: Settings, _compatible_window: W, _backend: Option<&str>, - ) -> impl Future> + MaybeSend; + ) -> impl Future>; /// Creates a [`Self::Renderer`] for the [`Compositor`]. fn create_renderer(&self) -> Self::Renderer; diff --git a/winit/src/program.rs b/winit/src/program.rs index 77b4f9d7..f47dfdf5 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -18,7 +18,7 @@ use crate::futures::futures::channel::oneshot; use crate::futures::futures::task; use crate::futures::futures::{Future, StreamExt}; use crate::futures::subscription::{self, Subscription}; -use crate::futures::{Executor, MaybeSend, Runtime}; +use crate::futures::{Executor, Runtime}; use crate::graphics; use crate::graphics::{Compositor, compositor}; use crate::runtime::Debug; @@ -149,7 +149,7 @@ pub fn run( ) -> Result<(), Error> where P: Program + 'static, - C: Compositor + MaybeSend + 'static, + C: Compositor + 'static, P::Theme: theme::Base, { use winit::event_loop::EventLoop; @@ -560,7 +560,7 @@ async fn run_instance( default_fonts: Vec>, ) where P: Program + 'static, - C: Compositor + MaybeSend + 'static, + C: Compositor + 'static, P::Theme: theme::Base, { use winit::event; @@ -636,7 +636,11 @@ async fn run_instance( } }; - runtime.spawn(create_compositor); + #[cfg(target_arch = "wasm32")] + wasm_bindgen_futures::spawn_local(create_compositor); + + #[cfg(not(target_arch = "wasm32"))] + runtime.block_on(create_compositor); match compositor_receiver .await @@ -648,7 +652,7 @@ async fn run_instance( Err(error) => { let _ = control_sender .start_send(Control::Crash(error.into())); - break; + continue; } } } From 53ce0e3a882cb399eaf0a67dd5ba5357f5c601b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 3 Apr 2025 16:59:55 +0200 Subject: [PATCH 16/18] Fix lints for Rust 1.86 --- examples/download_progress/src/main.rs | 10 ++++------ examples/pokedex/src/main.rs | 2 +- examples/toast/src/main.rs | 7 ++++--- wgpu/src/buffer.rs | 5 ++--- widget/src/text_input/value.rs | 8 +++++--- widget/src/tooltip.rs | 8 +++++--- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 0ba8a297..30559401 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -117,9 +117,7 @@ impl Download { pub fn start(&mut self) -> Task { match self.state { - State::Idle { .. } - | State::Finished { .. } - | State::Errored { .. } => { + State::Idle | State::Finished | State::Errored => { let (task, handle) = Task::sip( download( "https://huggingface.co/\ @@ -161,10 +159,10 @@ impl Download { pub fn view(&self) -> Element { let current_progress = match &self.state { - State::Idle { .. } => 0.0, + State::Idle => 0.0, State::Downloading { progress, .. } => *progress, - State::Finished { .. } => 100.0, - State::Errored { .. } => 0.0, + State::Finished => 100.0, + State::Errored => 0.0, }; let progress_bar = progress_bar(0.0..=100.0, current_progress); diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 2e972f6b..d8ccd27c 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -33,7 +33,7 @@ impl Pokedex { let subtitle = match self { Pokedex::Loading => "Loading", Pokedex::Loaded { pokemon, .. } => &pokemon.name, - Pokedex::Errored { .. } => "Whoops!", + Pokedex::Errored => "Whoops!", }; format!("{subtitle} - Pokédex") diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index dc314df8..b5d6d523 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -327,9 +327,10 @@ mod toast { instants.truncate(new); } (old, new) if old < new => { - instants.extend( - std::iter::repeat(Some(Instant::now())).take(new - old), - ); + instants.extend(std::iter::repeat_n( + Some(Instant::now()), + new - old, + )); } _ => {} } diff --git a/wgpu/src/buffer.rs b/wgpu/src/buffer.rs index 463ea24a..99092fc2 100644 --- a/wgpu/src/buffer.rs +++ b/wgpu/src/buffer.rs @@ -4,9 +4,8 @@ use std::ops::RangeBounds; pub const MAX_WRITE_SIZE: usize = 100 * 1024; -#[allow(unsafe_code)] -const MAX_WRITE_SIZE_U64: NonZeroU64 = - unsafe { NonZeroU64::new_unchecked(MAX_WRITE_SIZE as u64) }; +const MAX_WRITE_SIZE_U64: NonZeroU64 = NonZeroU64::new(MAX_WRITE_SIZE as u64) + .expect("MAX_WRITE_SIZE must be non-zero"); #[derive(Debug)] pub struct Buffer { diff --git a/widget/src/text_input/value.rs b/widget/src/text_input/value.rs index 46a1f754..7456ce63 100644 --- a/widget/src/text_input/value.rs +++ b/widget/src/text_input/value.rs @@ -120,9 +120,11 @@ impl Value { /// dot ('•') character. pub fn secure(&self) -> Self { Self { - graphemes: std::iter::repeat(String::from("•")) - .take(self.graphemes.len()) - .collect(), + graphemes: std::iter::repeat_n( + String::from("•"), + self.graphemes.len(), + ) + .collect(), } } } diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 2d674bca..ce34f2a5 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -386,9 +386,11 @@ where renderer, &layout::Limits::new( Size::ZERO, - self.snap_within_viewport - .then(|| viewport.size()) - .unwrap_or(Size::INFINITY), + if self.snap_within_viewport { + viewport.size() + } else { + Size::INFINITY + }, ) .shrink(Padding::new(self.padding)), ); From 33d20763c841767faf77baf853194c22a7bfa459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 3 Apr 2025 20:27:17 +0200 Subject: [PATCH 17/18] Annotate root crate tests with `standalone_crate` The new Rustdoc combined tests are an order of magnitude slower in my machine for the `iced` root crate. --- src/application.rs | 4 ++-- src/lib.rs | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/application.rs b/src/application.rs index c79ed62b..c220131a 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,7 +1,7 @@ //! Create and run iced applications step by step. //! //! # Example -//! ```no_run +//! ```no_run,standalone_crate //! use iced::widget::{button, column, text, Column}; //! use iced::Theme; //! @@ -42,7 +42,7 @@ use std::borrow::Cow; /// Creates an iced [`Application`] given its title, update, and view logic. /// /// # Example -/// ```no_run +/// ```no_run,standalone_crate /// use iced::widget::{button, column, text, Column}; /// /// pub fn main() -> iced::Result { diff --git a/src/lib.rs b/src/lib.rs index 21543fac..3ad685fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ //! # The Pocket Guide //! Start by calling [`run`]: //! -//! ```rust,no_run +//! ```no_run,standalone_crate //! pub fn main() -> iced::Result { //! iced::run("A cool counter", update, view) //! } @@ -39,7 +39,7 @@ //! //! Define an `update` function to __change__ your state: //! -//! ```rust +//! ```standalone_crate //! fn update(counter: &mut u64, message: Message) { //! match message { //! Message::Increment => *counter += 1, @@ -51,7 +51,7 @@ //! //! Define a `view` function to __display__ your state: //! -//! ```rust +//! ```standalone_crate //! use iced::widget::{button, text}; //! use iced::Element; //! @@ -64,7 +64,7 @@ //! //! And create a `Message` enum to __connect__ `view` and `update` together: //! -//! ```rust +//! ```standalone_crate //! #[derive(Debug, Clone)] //! enum Message { //! Increment, @@ -74,7 +74,7 @@ //! ## Custom State //! You can define your own struct for your state: //! -//! ```rust +//! ```standalone_crate //! #[derive(Default)] //! struct Counter { //! value: u64, @@ -83,7 +83,7 @@ //! //! But you have to change `update` and `view` accordingly: //! -//! ```rust +//! ```standalone_crate //! # struct Counter { value: u64 } //! # #[derive(Clone)] //! # enum Message { Increment } @@ -108,7 +108,7 @@ //! //! Widgets are configured using the builder pattern: //! -//! ```rust +//! ```standalone_crate //! # struct Counter { value: u64 } //! # #[derive(Clone)] //! # enum Message { Increment } @@ -138,7 +138,7 @@ //! Building your layout will often consist in using a combination of //! [rows], [columns], and [containers]: //! -//! ```rust +//! ```standalone_crate //! # struct State; //! # enum Message {} //! use iced::widget::{column, container, row}; @@ -181,7 +181,7 @@ //! //! A fixed numeric [`Length`] in [`Pixels`] can also be used: //! -//! ```rust +//! ```standalone_crate //! # struct State; //! # enum Message {} //! use iced::widget::container; @@ -197,7 +197,7 @@ //! function and leveraging the [`Application`] builder, instead of directly //! calling [`run`]: //! -//! ```rust,no_run +//! ```no_run,standalone_crate //! # #[derive(Default)] //! # struct State; //! use iced::Theme; @@ -227,7 +227,7 @@ //! //! The appearance of a widget can be changed by calling its `style` method: //! -//! ```rust +//! ```standalone_crate //! # struct State; //! # enum Message {} //! use iced::widget::container; @@ -241,7 +241,7 @@ //! The `style` method of a widget takes a closure that, given the current active //! [`Theme`], returns the widget style: //! -//! ```rust +//! ```standalone_crate //! # struct State; //! # #[derive(Clone)] //! # enum Message {} @@ -286,7 +286,7 @@ //! A [`Task`] can be leveraged to perform asynchronous work, like running a //! future or a stream: //! -//! ```rust +//! ```standalone_crate //! # #[derive(Clone)] //! # struct Weather; //! use iced::Task; @@ -334,7 +334,7 @@ //! //! You will need to define a `subscription` function and use the [`Application`] builder: //! -//! ```rust,no_run +//! ```no_run,standalone_crate //! # #[derive(Default)] //! # struct State; //! use iced::window; @@ -375,7 +375,7 @@ //! A common pattern is to leverage this composability to split an //! application into different screens: //! -//! ```rust +//! ```standalone_crate //! # mod contacts { //! # use iced::{Element, Task}; //! # pub struct Contacts; @@ -656,7 +656,7 @@ pub type Result = std::result::Result<(), Error>; /// This is equivalent to chaining [`application()`] with [`Application::run`]. /// /// # Example -/// ```no_run +/// ```no_run,standalone_crate /// use iced::widget::{button, column, text, Column}; /// /// pub fn main() -> iced::Result { From cd27dae8abdecc5ff751e1e201ade79bc6b8e23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 3 Apr 2025 20:36:30 +0200 Subject: [PATCH 18/18] Fix submission in `integration` example --- examples/integration/src/main.rs | 42 +++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 6c6cb120..025971a4 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -35,9 +35,10 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { Loading, Ready { window: Arc, + queue: wgpu::Queue, + device: wgpu::Device, surface: wgpu::Surface<'static>, format: wgpu::TextureFormat, - device: wgpu::Device, renderer: Renderer, scene: Scene, state: program::State, @@ -143,10 +144,18 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { // Initialize iced let mut debug = Debug::new(); - let engine = - Engine::new(&adapter, device.clone(), queue, format, None); - let mut renderer = - Renderer::new(engine, Font::default(), Pixels::from(16)); + + let mut renderer = { + let engine = Engine::new( + &adapter, + device.clone(), + queue.clone(), + format, + None, + ); + + Renderer::new(engine, Font::default(), Pixels::from(16)) + }; let state = program::State::new( controls, @@ -160,10 +169,11 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { *self = Self::Ready { window, + device, + queue, + renderer, surface, format, - device, - renderer, scene, state, cursor_position: None, @@ -185,6 +195,7 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { let Self::Ready { window, device, + queue, surface, format, renderer, @@ -230,18 +241,18 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { match surface.get_current_texture() { Ok(frame) => { - let mut encoder = device.create_command_encoder( - &wgpu::CommandEncoderDescriptor { label: None }, - ); - let program = state.program(); let view = frame.texture.create_view( &wgpu::TextureViewDescriptor::default(), ); + let mut encoder = device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + ); + { - // We clear the frame + // Clear the frame let mut render_pass = Scene::clear( &view, &mut encoder, @@ -252,7 +263,10 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { scene.draw(&mut render_pass); } - // And then iced on top + // Submit the scene + queue.submit([encoder.finish()]); + + // Draw iced on top renderer.present( None, frame.texture.format(), @@ -261,7 +275,7 @@ pub fn main() -> Result<(), winit::error::EventLoopError> { &debug.overlay(), ); - // Then we submit the work + // Present the frame frame.present(); // Update the mouse cursor