From 385a4490fb6a344873ba5154275a33acc011d080 Mon Sep 17 00:00:00 2001 From: Bingus Date: Fri, 29 Mar 2024 16:58:11 -0700 Subject: Expose line_height & text_size fields for the text_editor widget --- widget/src/text_editor.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index a00df3c7..92cdb251 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -110,6 +110,21 @@ where self } + /// Sets the text size of the [`TextEditor`]. + pub fn size(mut self, size: impl Into) -> Self { + self.text_size = Some(size.into()); + self + } + + /// Sets the [`text::LineHeight`] of the [`TextEditor`]. + pub fn line_height( + mut self, + line_height: impl Into, + ) -> Self { + self.line_height = line_height.into(); + self + } + /// Sets the [`Padding`] of the [`TextEditor`]. pub fn padding(mut self, padding: impl Into) -> Self { self.padding = padding.into(); -- cgit From 31d1d5fecbef50fa319cabd5d4194f1e4aaefa21 Mon Sep 17 00:00:00 2001 From: Aaron McGuire <89317236+Aaron-McGuire@users.noreply.github.com> Date: Tue, 2 Apr 2024 03:46:35 -0500 Subject: Check is_secure before a copy/cut from TextInput (#2366) * Check is_secure before copy/cut on text_input * run cargo fmt --- widget/src/text_input.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 8cfb0408..a814df78 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -712,7 +712,8 @@ where match key.as_ref() { keyboard::Key::Character("c") - if state.keyboard_modifiers.command() => + if state.keyboard_modifiers.command() + && !self.is_secure => { if let Some((start, end)) = state.cursor.selection(&self.value) @@ -726,7 +727,8 @@ where return event::Status::Captured; } keyboard::Key::Character("x") - if state.keyboard_modifiers.command() => + if state.keyboard_modifiers.command() + && !self.is_secure => { if let Some((start, end)) = state.cursor.selection(&self.value) -- cgit From c45c79b5d6e25f73dc76a816c08a7041ad971c66 Mon Sep 17 00:00:00 2001 From: David Huculak Date: Sun, 7 Apr 2024 02:20:44 -0400 Subject: add stronger guarantee of readability/contrast for palette background/text color pairs --- core/src/theme/palette.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/src/theme/palette.rs b/core/src/theme/palette.rs index ca91c248..91543567 100644 --- a/core/src/theme/palette.rs +++ b/core/src/theme/palette.rs @@ -612,11 +612,19 @@ fn mix(a: Color, b: Color, factor: f32) -> Color { fn readable(background: Color, text: Color) -> Color { if is_readable(background, text) { - text - } else if is_dark(background) { + return text; + } + + let fallback = if is_dark(background) { Color::WHITE } else { Color::BLACK + }; + + if is_readable(background, fallback) { + fallback + } else { + fallback.inverse() } } -- cgit From a865b380026ce8c26b818e8e94ea14cb930865a3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 7 Apr 2024 08:11:42 +0200 Subject: Add a simple `wgpu` benchmark using `criterion` --- Cargo.toml | 9 +++ benches/wgpu.rs | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 benches/wgpu.rs diff --git a/Cargo.toml b/Cargo.toml index b033cf33..def40bd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -164,3 +164,12 @@ wgpu = "0.19" winapi = "0.3" window_clipboard = "0.4.1" winit = { git = "https://github.com/iced-rs/winit.git", rev = "592bd152f6d5786fae7d918532d7db752c0d164f" } + +[dev-dependencies] +criterion = "0.5" +iced_wgpu.workspace = true + +[[bench]] +name = "wgpu" +harness = false +required-features = ["canvas"] diff --git a/benches/wgpu.rs b/benches/wgpu.rs new file mode 100644 index 00000000..617be16d --- /dev/null +++ b/benches/wgpu.rs @@ -0,0 +1,185 @@ +use criterion::{criterion_group, criterion_main, Bencher, Criterion}; + +use iced::alignment; +use iced::mouse; +use iced::widget::{canvas, text}; +use iced::{ + Color, Element, Font, Length, Pixels, Point, Rectangle, Size, Theme, +}; +use iced_wgpu::Renderer; + +criterion_main!(benches); +criterion_group!(benches, wgpu_benchmark); + +pub fn wgpu_benchmark(c: &mut Criterion) { + c.bench_function("wgpu — canvas (light)", |b| benchmark(b, scene(10))); + c.bench_function("wgpu — canvas (heavy)", |b| benchmark(b, scene(1_000))); +} + +fn benchmark<'a>( + bencher: &mut Bencher<'_>, + widget: Element<'a, (), Theme, Renderer>, +) { + use iced_futures::futures::executor; + use iced_wgpu::graphics; + use iced_wgpu::graphics::Antialiasing; + use iced_wgpu::wgpu; + use iced_winit::core; + use iced_winit::runtime; + + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::all(), + ..Default::default() + }); + + let adapter = executor::block_on(instance.request_adapter( + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: None, + force_fallback_adapter: false, + }, + )) + .expect("request adapter"); + + let (device, queue) = executor::block_on(adapter.request_device( + &wgpu::DeviceDescriptor { + label: None, + required_features: wgpu::Features::empty(), + required_limits: wgpu::Limits::default(), + }, + None, + )) + .expect("request device"); + + let format = wgpu::TextureFormat::Bgra8UnormSrgb; + + let backend = iced_wgpu::Backend::new( + &adapter, + &device, + &queue, + iced_wgpu::Settings { + present_mode: wgpu::PresentMode::Immediate, + internal_backend: wgpu::Backends::all(), + default_font: Font::DEFAULT, + default_text_size: Pixels::from(16), + antialiasing: Some(Antialiasing::MSAAx4), + }, + format, + ); + + let mut renderer = Renderer::new(backend, Font::DEFAULT, Pixels::from(16)); + + let viewport = + graphics::Viewport::with_physical_size(Size::new(3840, 2160), 2.0); + + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 3840, + height: 2160, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + + let texture_view = + texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let mut user_interface = runtime::UserInterface::build( + widget, + viewport.logical_size(), + runtime::user_interface::Cache::default(), + &mut renderer, + ); + + bencher.iter(|| { + user_interface.draw( + &mut renderer, + &Theme::Dark, + &core::renderer::Style { + text_color: Color::WHITE, + }, + mouse::Cursor::Unavailable, + ); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: None, + }); + + renderer.with_primitives(|backend, primitives| { + backend.present::<&str>( + &device, + &queue, + &mut encoder, + Some(Color::BLACK), + format, + &texture_view, + primitives, + &viewport, + &[], + ); + + let submission = queue.submit(Some(encoder.finish())); + backend.recall(); + + let _ = + device.poll(wgpu::Maintain::WaitForSubmissionIndex(submission)); + }); + }); +} + +fn scene<'a, Message: 'a, Theme: 'a>( + n: usize, +) -> Element<'a, Message, Theme, Renderer> { + canvas(Scene { n }) + .width(Length::Fill) + .height(Length::Fill) + .into() +} + +struct Scene { + n: usize, +} + +impl canvas::Program for Scene { + type State = canvas::Cache; + + fn draw( + &self, + cache: &Self::State, + renderer: &Renderer, + _theme: &Theme, + bounds: Rectangle, + _cursor: mouse::Cursor, + ) -> Vec> { + vec![cache.draw(renderer, bounds.size(), |frame| { + for i in 0..self.n { + frame.fill_rectangle( + Point::new(0.0, i as f32), + Size::new(10.0, 10.0), + Color::WHITE, + ); + } + + for i in 0..self.n { + frame.fill_text(canvas::Text { + content: i.to_string(), + position: Point::new(0.0, i as f32), + color: Color::BLACK, + size: Pixels::from(16), + line_height: text::LineHeight::default(), + font: Font::DEFAULT, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Top, + shaping: text::Shaping::Basic, + }); + } + })] + } +} -- cgit From 5cd98f069dea8720bca7748d6c12fa410cbe79b5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 7 Apr 2024 12:42:12 +0200 Subject: Use built-in `[lints]` table in `Cargo.toml` --- .cargo/config.toml | 53 +------- Cargo.toml | 42 +++++- benches/wgpu.rs | 11 +- core/Cargo.toml | 3 + core/src/lib.rs | 7 - futures/Cargo.toml | 3 + futures/src/lib.rs | 7 - graphics/Cargo.toml | 3 + graphics/src/lib.rs | 8 -- graphics/src/text/cache.rs | 5 +- highlighter/Cargo.toml | 3 + highlighter/src/lib.rs | 31 ++++- renderer/Cargo.toml | 3 + renderer/src/fallback.rs | 258 +++++++++++++++++++++---------------- renderer/src/lib.rs | 3 +- runtime/Cargo.toml | 3 + runtime/src/lib.rs | 7 - src/lib.rs | 7 - tiny_skia/Cargo.toml | 3 + tiny_skia/src/backend.rs | 1 + tiny_skia/src/geometry.rs | 1 + tiny_skia/src/lib.rs | 3 +- tiny_skia/src/raster.rs | 4 +- tiny_skia/src/text.rs | 2 +- tiny_skia/src/vector.rs | 11 ++ tiny_skia/src/window/compositor.rs | 2 + wgpu/Cargo.toml | 4 + wgpu/src/lib.rs | 8 -- widget/Cargo.toml | 3 + widget/src/lib.rs | 7 - winit/Cargo.toml | 4 + winit/src/lib.rs | 8 -- 32 files changed, 274 insertions(+), 244 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 85a46cda..5de65154 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,53 +1,2 @@ [alias] -lint = """ -clippy --workspace --no-deps -- \ - -D warnings \ - -A clippy::type_complexity \ - -D clippy::semicolon_if_nothing_returned \ - -D clippy::trivially-copy-pass-by-ref \ - -D clippy::default_trait_access \ - -D clippy::match-wildcard-for-single-variants \ - -D clippy::redundant-closure-for-method-calls \ - -D clippy::filter_map_next \ - -D clippy::manual_let_else \ - -D clippy::unused_async \ - -D clippy::from_over_into \ - -D clippy::needless_borrow \ - -D clippy::new_without_default \ - -D clippy::useless_conversion -""" - -nitpick = """ -clippy --workspace --no-deps -- \ - -D warnings \ - -D clippy::pedantic \ - -A clippy::type_complexity \ - -A clippy::must_use_candidate \ - -A clippy::return_self_not_must_use \ - -A clippy::needless_pass_by_value \ - -A clippy::cast_precision_loss \ - -A clippy::cast_sign_loss \ - -A clippy::cast_possible_truncation \ - -A clippy::match_same_arms \ - -A clippy::missing-errors-doc \ - -A clippy::missing-panics-doc \ - -A clippy::cast_lossless \ - -A clippy::doc_markdown \ - -A clippy::items_after_statements \ - -A clippy::too_many_lines \ - -A clippy::module_name_repetitions \ - -A clippy::if_not_else \ - -A clippy::redundant_else \ - -A clippy::used_underscore_binding \ - -A clippy::cast_possible_wrap \ - -A clippy::unnecessary_wraps \ - -A clippy::struct-excessive-bools \ - -A clippy::float-cmp \ - -A clippy::single_match_else \ - -A clippy::unreadable_literal \ - -A clippy::explicit_deref_methods \ - -A clippy::map_unwrap_or \ - -A clippy::unnested_or_patterns \ - -A clippy::similar_names \ - -A clippy::unused_self -""" +lint = "clippy --workspace --no-deps -- -D warnings" diff --git a/Cargo.toml b/Cargo.toml index def40bd5..2b6a0d03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true @@ -74,6 +77,15 @@ thiserror.workspace = true image.workspace = true image.optional = true +[dev-dependencies] +criterion = "0.5" +iced_wgpu.workspace = true + +[[bench]] +name = "wgpu" +harness = false +required-features = ["canvas"] + [profile.release-opt] inherits = "release" codegen-units = 1 @@ -165,11 +177,27 @@ winapi = "0.3" window_clipboard = "0.4.1" winit = { git = "https://github.com/iced-rs/winit.git", rev = "592bd152f6d5786fae7d918532d7db752c0d164f" } -[dev-dependencies] -criterion = "0.5" -iced_wgpu.workspace = true +[workspace.lints.rust] +rust_2018_idioms = "forbid" +missing_debug_implementations = "deny" +missing_docs = "deny" +unsafe_code = "deny" +unused_results = "deny" -[[bench]] -name = "wgpu" -harness = false -required-features = ["canvas"] +[workspace.lints.clippy] +type-complexity = "allow" +semicolon_if_nothing_returned = "deny" +trivially-copy-pass-by-ref = "deny" +default_trait_access = "deny" +match-wildcard-for-single-variants = "deny" +redundant-closure-for-method-calls = "deny" +filter_map_next = "deny" +manual_let_else = "deny" +unused_async = "deny" +from_over_into = "deny" +needless_borrow = "deny" +new_without_default = "deny" +useless_conversion = "deny" + +[workspace.lints.rustdoc] +broken_intra_doc_links = "forbid" diff --git a/benches/wgpu.rs b/benches/wgpu.rs index 617be16d..2c117858 100644 --- a/benches/wgpu.rs +++ b/benches/wgpu.rs @@ -1,3 +1,4 @@ +#![allow(missing_docs)] use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use iced::alignment; @@ -12,8 +13,12 @@ criterion_main!(benches); criterion_group!(benches, wgpu_benchmark); pub fn wgpu_benchmark(c: &mut Criterion) { - c.bench_function("wgpu — canvas (light)", |b| benchmark(b, scene(10))); - c.bench_function("wgpu — canvas (heavy)", |b| benchmark(b, scene(1_000))); + let _ = c + .bench_function("wgpu — canvas (light)", |b| benchmark(b, scene(10))); + + let _ = c.bench_function("wgpu — canvas (heavy)", |b| { + benchmark(b, scene(1_000)) + }); } fn benchmark<'a>( @@ -98,7 +103,7 @@ fn benchmark<'a>( ); bencher.iter(|| { - user_interface.draw( + let _ = user_interface.draw( &mut renderer, &Theme::Dark, &core::renderer::Style { diff --git a/core/Cargo.toml b/core/Cargo.toml index d3529d98..7bd37021 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [features] auto-detect-theme = ["dep:dark-light"] advanced = [] diff --git a/core/src/lib.rs b/core/src/lib.rs index 832b2d2d..feda4fb4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,13 +9,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - rustdoc::broken_intra_doc_links -)] pub mod alignment; pub mod border; pub mod clipboard; diff --git a/futures/Cargo.toml b/futures/Cargo.toml index bbcfe01c..a6fcfde1 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true diff --git a/futures/src/lib.rs b/futures/src/lib.rs index b0acb76f..a874a618 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -4,13 +4,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use futures; pub use iced_core as core; diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index a42ed477..e8d27d07 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index d7f2f439..18bfd981 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -7,14 +7,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unsafe_code, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] mod antialiasing; mod cached; diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs index b6473f85..822b61c4 100644 --- a/graphics/src/text/cache.rs +++ b/graphics/src/text/cache.rs @@ -7,8 +7,7 @@ use std::collections::hash_map; use std::hash::{Hash, Hasher}; /// A store of recently used sections of text. -#[allow(missing_debug_implementations)] -#[derive(Default)] +#[derive(Debug, Default)] pub struct Cache { entries: FxHashMap, aliases: FxHashMap, @@ -135,7 +134,7 @@ impl Key<'_> { pub type KeyHash = u64; /// A cache entry. -#[allow(missing_debug_implementations)] +#[derive(Debug)] pub struct Entry { /// The buffer of text, ready for drawing. pub buffer: cosmic_text::Buffer, diff --git a/highlighter/Cargo.toml b/highlighter/Cargo.toml index 2d108d6f..7962b89d 100644 --- a/highlighter/Cargo.toml +++ b/highlighter/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [dependencies] iced_core.workspace = true diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs index 63f21fc0..7636a712 100644 --- a/highlighter/src/lib.rs +++ b/highlighter/src/lib.rs @@ -1,3 +1,4 @@ +//! A syntax highlighter for iced. use iced_core as core; use crate::core::text::highlighter::{self, Format}; @@ -16,6 +17,8 @@ static THEMES: Lazy = const LINES_PER_SNAPSHOT: usize = 50; +/// A syntax highlighter. +#[derive(Debug)] pub struct Highlighter { syntax: &'static parsing::SyntaxReference, highlighter: highlighting::Highlighter<'static>, @@ -131,25 +134,47 @@ impl highlighter::Highlighter for Highlighter { } } +/// The settings of a [`Highlighter`]. #[derive(Debug, Clone, PartialEq)] pub struct Settings { + /// The [`Theme`] of the [`Highlighter`]. + /// + /// It dictates the color scheme that will be used for highlighting. pub theme: Theme, + /// The extension of the file to highlight. + /// + /// The [`Highlighter`] will use the extension to automatically determine + /// the grammar to use for highlighting. pub extension: String, } +/// A highlight produced by a [`Highlighter`]. +#[derive(Debug)] pub struct Highlight(highlighting::StyleModifier); impl Highlight { + /// Returns the color of this [`Highlight`]. + /// + /// If `None`, the original text color should be unchanged. pub fn color(&self) -> Option { self.0.foreground.map(|color| { Color::from_rgba8(color.r, color.g, color.b, color.a as f32 / 255.0) }) } + /// Returns the font of this [`Highlight`]. + /// + /// If `None`, the original font should be unchanged. pub fn font(&self) -> Option { None } + /// Returns the [`Format`] of the [`Highlight`]. + /// + /// It contains both the [`color`] and the [`font`]. + /// + /// [`color`]: Self::color + /// [`font`]: Self::font pub fn to_format(&self) -> Format { Format { color: self.color(), @@ -158,6 +183,8 @@ impl Highlight { } } +/// A highlighting theme. +#[allow(missing_docs)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { SolarizedDark, @@ -168,6 +195,7 @@ pub enum Theme { } impl Theme { + /// A static slice containing all the available themes. pub const ALL: &'static [Self] = &[ Self::SolarizedDark, Self::Base16Mocha, @@ -176,6 +204,7 @@ impl Theme { Self::InspiredGitHub, ]; + /// Returns `true` if the [`Theme`] is dark, and false otherwise. pub fn is_dark(self) -> bool { match self { Self::SolarizedDark @@ -209,7 +238,7 @@ impl std::fmt::Display for Theme { } } -pub struct ScopeRangeIterator { +struct ScopeRangeIterator { ops: Vec<(usize, parsing::ScopeStackOp)>, line_length: usize, index: usize, diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index 39c19fa3..6fdb4228 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [features] wgpu = ["iced_wgpu"] tiny-skia = ["iced_tiny_skia"] diff --git a/renderer/src/fallback.rs b/renderer/src/fallback.rs index b9ceb4b2..85ac3d93 100644 --- a/renderer/src/fallback.rs +++ b/renderer/src/fallback.rs @@ -1,3 +1,4 @@ +//! Compose existing renderers and create type-safe fallback strategies. use crate::core::image; use crate::core::renderer; use crate::core::svg; @@ -8,24 +9,31 @@ use crate::graphics; use crate::graphics::compositor; use crate::graphics::mesh; -pub enum Renderer { - Left(L), - Right(R), +/// A renderer `A` with a fallback strategy `B`. +/// +/// This type can be used to easily compose existing renderers and +/// create custom, type-safe fallback strategies. +#[derive(Debug)] +pub enum Renderer { + /// The primary rendering option. + Primary(A), + /// The secondary (or fallback) rendering option. + Secondary(B), } macro_rules! delegate { ($renderer:expr, $name:ident, $body:expr) => { match $renderer { - Self::Left($name) => $body, - Self::Right($name) => $body, + Self::Primary($name) => $body, + Self::Secondary($name) => $body, } }; } -impl core::Renderer for Renderer +impl core::Renderer for Renderer where - L: core::Renderer, - R: core::Renderer, + A: core::Renderer, + B: core::Renderer, { fn fill_quad( &mut self, @@ -56,22 +64,22 @@ where } } -impl core::text::Renderer for Renderer +impl core::text::Renderer for Renderer where - L: core::text::Renderer, - R: core::text::Renderer< - Font = L::Font, - Paragraph = L::Paragraph, - Editor = L::Editor, + A: core::text::Renderer, + B: core::text::Renderer< + Font = A::Font, + Paragraph = A::Paragraph, + Editor = A::Editor, >, { - type Font = L::Font; - type Paragraph = L::Paragraph; - type Editor = L::Editor; + type Font = A::Font; + type Paragraph = A::Paragraph; + type Editor = A::Editor; - const ICON_FONT: Self::Font = L::ICON_FONT; - const CHECKMARK_ICON: char = L::CHECKMARK_ICON; - const ARROW_DOWN_ICON: char = L::ARROW_DOWN_ICON; + const ICON_FONT: Self::Font = A::ICON_FONT; + const CHECKMARK_ICON: char = A::CHECKMARK_ICON; + const ARROW_DOWN_ICON: char = A::ARROW_DOWN_ICON; fn default_font(&self) -> Self::Font { delegate!(self, renderer, renderer.default_font()) @@ -128,12 +136,12 @@ where } } -impl image::Renderer for Renderer +impl image::Renderer for Renderer where - L: image::Renderer, - R: image::Renderer, + A: image::Renderer, + B: image::Renderer, { - type Handle = L::Handle; + type Handle = A::Handle; fn measure_image(&self, handle: &Self::Handle) -> Size { delegate!(self, renderer, renderer.measure_image(handle)) @@ -153,10 +161,10 @@ where } } -impl svg::Renderer for Renderer +impl svg::Renderer for Renderer where - L: svg::Renderer, - R: svg::Renderer, + A: svg::Renderer, + B: svg::Renderer, { fn measure_svg(&self, handle: &svg::Handle) -> Size { delegate!(self, renderer, renderer.measure_svg(handle)) @@ -172,37 +180,49 @@ where } } -impl mesh::Renderer for Renderer +impl mesh::Renderer for Renderer where - L: mesh::Renderer, - R: mesh::Renderer, + A: mesh::Renderer, + B: mesh::Renderer, { fn draw_mesh(&mut self, mesh: graphics::Mesh) { delegate!(self, renderer, renderer.draw_mesh(mesh)); } } -pub enum Compositor +/// A compositor `A` with a fallback strategy `B`. +/// +/// It works analogously to [`Renderer`]. +#[derive(Debug)] +pub enum Compositor where - L: graphics::Compositor, - R: graphics::Compositor, + A: graphics::Compositor, + B: graphics::Compositor, { - Left(L), - Right(R), + /// The primary compositing option. + Primary(A), + /// The secondary (or fallback) compositing option. + Secondary(B), } -pub enum Surface { - Left(L), - Right(R), +/// A surface `A` with a fallback strategy `B`. +/// +/// It works analogously to [`Renderer`]. +#[derive(Debug)] +pub enum Surface { + /// The primary surface option. + Primary(A), + /// The secondary (or fallback) surface option. + Secondary(B), } -impl graphics::Compositor for Compositor +impl graphics::Compositor for Compositor where - L: graphics::Compositor, - R: graphics::Compositor, + A: graphics::Compositor, + B: graphics::Compositor, { - type Renderer = Renderer; - type Surface = Surface; + type Renderer = Renderer; + type Surface = Surface; async fn with_backend( settings: graphics::Settings, @@ -233,19 +253,19 @@ where let mut errors = vec![]; for backend in candidates.iter().map(Option::as_deref) { - match L::with_backend(settings, compatible_window.clone(), backend) + match A::with_backend(settings, compatible_window.clone(), backend) .await { - Ok(compositor) => return Ok(Self::Left(compositor)), + Ok(compositor) => return Ok(Self::Primary(compositor)), Err(error) => { errors.push(error); } } - match R::with_backend(settings, compatible_window.clone(), backend) + match B::with_backend(settings, compatible_window.clone(), backend) .await { - Ok(compositor) => return Ok(Self::Right(compositor)), + Ok(compositor) => return Ok(Self::Secondary(compositor)), Err(error) => { errors.push(error); } @@ -257,11 +277,11 @@ where fn create_renderer(&self) -> Self::Renderer { match self { - Self::Left(compositor) => { - Renderer::Left(compositor.create_renderer()) + Self::Primary(compositor) => { + Renderer::Primary(compositor.create_renderer()) } - Self::Right(compositor) => { - Renderer::Right(compositor.create_renderer()) + Self::Secondary(compositor) => { + Renderer::Secondary(compositor.create_renderer()) } } } @@ -273,12 +293,12 @@ where height: u32, ) -> Self::Surface { match self { - Self::Left(compositor) => { - Surface::Left(compositor.create_surface(window, width, height)) - } - Self::Right(compositor) => { - Surface::Right(compositor.create_surface(window, width, height)) - } + Self::Primary(compositor) => Surface::Primary( + compositor.create_surface(window, width, height), + ), + Self::Secondary(compositor) => Surface::Secondary( + compositor.create_surface(window, width, height), + ), } } @@ -289,10 +309,10 @@ where height: u32, ) { match (self, surface) { - (Self::Left(compositor), Surface::Left(surface)) => { + (Self::Primary(compositor), Surface::Primary(surface)) => { compositor.configure_surface(surface, width, height); } - (Self::Right(compositor), Surface::Right(surface)) => { + (Self::Secondary(compositor), Surface::Secondary(surface)) => { compositor.configure_surface(surface, width, height); } _ => unreachable!(), @@ -313,9 +333,9 @@ where ) -> Result<(), compositor::SurfaceError> { match (self, renderer, surface) { ( - Self::Left(compositor), - Renderer::Left(renderer), - Surface::Left(surface), + Self::Primary(compositor), + Renderer::Primary(renderer), + Surface::Primary(surface), ) => compositor.present( renderer, surface, @@ -324,9 +344,9 @@ where overlay, ), ( - Self::Right(compositor), - Renderer::Right(renderer), - Surface::Right(surface), + Self::Secondary(compositor), + Renderer::Secondary(renderer), + Surface::Secondary(surface), ) => compositor.present( renderer, surface, @@ -348,9 +368,9 @@ where ) -> Vec { match (self, renderer, surface) { ( - Self::Left(compositor), - Renderer::Left(renderer), - Surface::Left(surface), + Self::Primary(compositor), + Renderer::Primary(renderer), + Surface::Primary(surface), ) => compositor.screenshot( renderer, surface, @@ -359,9 +379,9 @@ where overlay, ), ( - Self::Right(compositor), - Renderer::Right(renderer), - Surface::Right(surface), + Self::Secondary(compositor), + Renderer::Secondary(renderer), + Surface::Secondary(surface), ) => compositor.screenshot( renderer, surface, @@ -375,10 +395,10 @@ where } #[cfg(feature = "wgpu")] -impl iced_wgpu::primitive::pipeline::Renderer for Renderer +impl iced_wgpu::primitive::pipeline::Renderer for Renderer where - L: iced_wgpu::primitive::pipeline::Renderer, - R: core::Renderer, + A: iced_wgpu::primitive::pipeline::Renderer, + B: core::Renderer, { fn draw_pipeline_primitive( &mut self, @@ -386,10 +406,10 @@ where primitive: impl iced_wgpu::primitive::pipeline::Primitive, ) { match self { - Self::Left(renderer) => { + Self::Primary(renderer) => { renderer.draw_pipeline_primitive(bounds, primitive); } - Self::Right(_) => { + Self::Secondary(_) => { log::warn!( "Custom shader primitive is not supported with this renderer." ); @@ -405,27 +425,31 @@ mod geometry { use crate::graphics::geometry::{self, Fill, Path, Stroke, Text}; use crate::graphics::Cached; - impl geometry::Renderer for Renderer + impl geometry::Renderer for Renderer where - L: geometry::Renderer, - R: geometry::Renderer, + A: geometry::Renderer, + B: geometry::Renderer, { - type Geometry = Geometry; - type Frame = Frame; + type Geometry = Geometry; + type Frame = Frame; fn new_frame(&self, size: iced_graphics::core::Size) -> Self::Frame { match self { - Self::Left(renderer) => Frame::Left(renderer.new_frame(size)), - Self::Right(renderer) => Frame::Right(renderer.new_frame(size)), + Self::Primary(renderer) => { + Frame::Primary(renderer.new_frame(size)) + } + Self::Secondary(renderer) => { + Frame::Secondary(renderer.new_frame(size)) + } } } fn draw_geometry(&mut self, geometry: Self::Geometry) { match (self, geometry) { - (Self::Left(renderer), Geometry::Left(geometry)) => { + (Self::Primary(renderer), Geometry::Primary(geometry)) => { renderer.draw_geometry(geometry); } - (Self::Right(renderer), Geometry::Right(geometry)) => { + (Self::Secondary(renderer), Geometry::Secondary(geometry)) => { renderer.draw_geometry(geometry); } _ => unreachable!(), @@ -433,44 +457,48 @@ mod geometry { } } - pub enum Geometry { - Left(L), - Right(R), + #[derive(Debug)] + pub enum Geometry { + Primary(A), + Secondary(B), } - impl Cached for Geometry + impl Cached for Geometry where - L: Cached, - R: Cached, + A: Cached, + B: Cached, { - type Cache = Geometry; + type Cache = Geometry; fn load(cache: &Self::Cache) -> Self { match cache { - Geometry::Left(cache) => Self::Left(L::load(cache)), - Geometry::Right(cache) => Self::Right(R::load(cache)), + Geometry::Primary(cache) => Self::Primary(A::load(cache)), + Geometry::Secondary(cache) => Self::Secondary(B::load(cache)), } } fn cache(self) -> Self::Cache { match self { - Self::Left(geometry) => Geometry::Left(geometry.cache()), - Self::Right(geometry) => Geometry::Right(geometry.cache()), + Self::Primary(geometry) => Geometry::Primary(geometry.cache()), + Self::Secondary(geometry) => { + Geometry::Secondary(geometry.cache()) + } } } } - pub enum Frame { - Left(L), - Right(R), + #[derive(Debug)] + pub enum Frame { + Primary(A), + Secondary(B), } - impl geometry::frame::Backend for Frame + impl geometry::frame::Backend for Frame where - L: geometry::frame::Backend, - R: geometry::frame::Backend, + A: geometry::frame::Backend, + B: geometry::frame::Backend, { - type Geometry = Geometry; + type Geometry = Geometry; fn width(&self) -> f32 { delegate!(self, frame, frame.width()) @@ -519,17 +547,17 @@ mod geometry { fn draft(&mut self, size: Size) -> Self { match self { - Self::Left(frame) => Self::Left(frame.draft(size)), - Self::Right(frame) => Self::Right(frame.draft(size)), + Self::Primary(frame) => Self::Primary(frame.draft(size)), + Self::Secondary(frame) => Self::Secondary(frame.draft(size)), } } fn paste(&mut self, frame: Self, at: Point) { match (self, frame) { - (Self::Left(target), Self::Left(source)) => { + (Self::Primary(target), Self::Primary(source)) => { target.paste(source, at); } - (Self::Right(target), Self::Right(source)) => { + (Self::Secondary(target), Self::Secondary(source)) => { target.paste(source, at); } _ => unreachable!(), @@ -554,17 +582,21 @@ mod geometry { fn into_geometry(self) -> Self::Geometry { match self { - Frame::Left(frame) => Geometry::Left(frame.into_geometry()), - Frame::Right(frame) => Geometry::Right(frame.into_geometry()), + Frame::Primary(frame) => { + Geometry::Primary(frame.into_geometry()) + } + Frame::Secondary(frame) => { + Geometry::Secondary(frame.into_geometry()) + } } } } } -impl compositor::Default for Renderer +impl compositor::Default for Renderer where - L: compositor::Default, - R: compositor::Default, + A: compositor::Default, + B: compositor::Default, { - type Compositor = Compositor; + type Compositor = Compositor; } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 7c48995d..056da5ed 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -1,5 +1,4 @@ -#![forbid(rust_2018_idioms)] -#![deny(unsafe_code, unused_results, rustdoc::broken_intra_doc_links)] +//! The official renderer for iced. #![cfg_attr(docsrs, feature(doc_auto_cfg))] #[cfg(feature = "wgpu")] pub use iced_wgpu as wgpu; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 3a47a971..21503462 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [features] debug = [] multi-window = [] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5c2836a5..5f054c46 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -8,13 +8,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod clipboard; pub mod command; diff --git a/src/lib.rs b/src/lib.rs index e67b46e3..c96c28a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,13 +165,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(rust_2018_idioms, unsafe_code)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))] use iced_widget::graphics; diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index 44a894a1..32ead3e0 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [features] image = ["iced_graphics/image"] svg = ["resvg"] diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index 0c913c02..d0f28876 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -9,6 +9,7 @@ use crate::window; use std::borrow::Cow; +#[derive(Debug)] pub struct Backend { text_pipeline: crate::text::Pipeline, diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 76482e12..9bc3664d 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -8,6 +8,7 @@ use crate::graphics::geometry::{self, Path, Style, Text}; use crate::graphics::Gradient; use crate::primitive::{self, Primitive}; +#[derive(Debug)] pub struct Frame { size: Size, transform: tiny_skia::Transform, diff --git a/tiny_skia/src/lib.rs b/tiny_skia/src/lib.rs index e7294f9b..d1f68daa 100644 --- a/tiny_skia/src/lib.rs +++ b/tiny_skia/src/lib.rs @@ -1,5 +1,4 @@ -#![forbid(rust_2018_idioms)] -#![deny(unsafe_code, unused_results, rustdoc::broken_intra_doc_links)] +#![allow(missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod window; diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index 5f17ae60..176b0da9 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -6,6 +6,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use std::cell::RefCell; use std::collections::hash_map; +#[derive(Debug)] pub struct Pipeline { cache: RefCell, } @@ -68,7 +69,7 @@ impl Pipeline { } } -#[derive(Default)] +#[derive(Debug, Default)] struct Cache { entries: FxHashMap>, hits: FxHashSet, @@ -119,6 +120,7 @@ impl Cache { } } +#[derive(Debug)] struct Entry { width: u32, height: u32, diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index d28cc483..66ee88da 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -13,7 +13,7 @@ use std::borrow::Cow; use std::cell::RefCell; use std::collections::hash_map; -#[allow(missing_debug_implementations)] +#[derive(Debug)] pub struct Pipeline { glyph_cache: GlyphCache, cache: RefCell, diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index fd1ab3de..5150cffe 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -9,6 +9,7 @@ use std::cell::RefCell; use std::collections::hash_map; use std::fs; +#[derive(Debug)] pub struct Pipeline { cache: RefCell, } @@ -203,3 +204,13 @@ impl Cache { self.raster_hits.clear(); } } + +impl std::fmt::Debug for Cache { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Cache") + .field("tree_hits", &self.tree_hits) + .field("rasters", &self.rasters) + .field("raster_hits", &self.raster_hits) + .finish_non_exhaustive() + } +} diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 25c57dc1..2350adb9 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -8,11 +8,13 @@ use crate::{Backend, Primitive, Renderer, Settings}; use std::collections::VecDeque; use std::num::NonZeroU32; +#[allow(missing_debug_implementations)] pub struct Compositor { context: softbuffer::Context>, settings: Settings, } +#[allow(missing_debug_implementations)] pub struct Surface { window: softbuffer::Surface< Box, diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 0b713784..5f464522 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true @@ -44,3 +47,4 @@ resvg.optional = true tracing.workspace = true tracing.optional = true + diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index b00e5c3c..2cb9cf04 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -20,14 +20,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unsafe_code, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod layer; pub mod primitive; diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 84525935..3c9f6a54 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 209dfad9..1eeacbae 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -2,13 +2,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_renderer as renderer; pub use iced_renderer::graphics; diff --git a/winit/Cargo.toml b/winit/Cargo.toml index 29e744b2..dccb7c07 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -10,6 +10,9 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[lints] +workspace = true + [features] default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] debug = ["iced_runtime/debug"] @@ -41,3 +44,4 @@ winapi.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] web-sys.workspace = true web-sys.features = ["Document", "Window"] + diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 64912b3f..3619cde8 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -17,14 +17,6 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(rust_2018_idioms)] -#![deny( - missing_debug_implementations, - missing_docs, - unused_results, - unsafe_code, - rustdoc::broken_intra_doc_links -)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_graphics as graphics; pub use iced_runtime as runtime; -- cgit From 8475cd7b25d8d592ab52107b72480b4c765762c6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 7 Apr 2024 13:00:13 +0200 Subject: Run `lint` workflow in `ubuntu-latest` `macOS-latest` seems to abort the build randomly for some reason. --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ccf79cb7..84f67aa0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,7 +2,7 @@ name: Lint on: [push, pull_request] jobs: all: - runs-on: macOS-latest + runs-on: ubuntu-latest steps: - uses: hecrj/setup-rust-action@v2 with: -- cgit From 1c241d1150d2f7b5d0ae154439325950e5d25f38 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 7 Apr 2024 13:04:53 +0200 Subject: Install missing dependencies in `lint` workflow --- .github/workflows/lint.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 84f67aa0..16ee8bf9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,5 +8,10 @@ jobs: with: components: clippy - uses: actions/checkout@master + - name: Install dependencies + run: | + export DEBIAN_FRONTED=noninteractive + sudo apt-get -qq update + sudo apt-get install -y libxkbcommon-dev libgtk-3-dev - name: Check lints run: cargo lint -- cgit