From 874245bc2e10ccbb86a979976d8d448d6f05a6bb Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 24 Mar 2025 14:59:25 -0700 Subject: [PATCH] Use `aliasable` in `AxisToplevelLayout` to use slice in argument This makes layouts possible to compose without clones. --- Cargo.lock | 1 + Cargo.toml | 1 + .../toplevel_layout/axis_toplevel_layout.rs | 31 ++++++++++++++++--- .../row_col_toplevel_layout.rs | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f375cf2..8e4ded3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,6 +1252,7 @@ dependencies = [ name = "cosmic-workspaces" version = "0.1.0" dependencies = [ + "aliasable", "anyhow", "calloop 0.14.2", "calloop-wayland-source 0.4.0", diff --git a/Cargo.toml b/Cargo.toml index 1ef45fb..876eb22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ i18n-embed-fl = "0.9.0" rust-embed = "8.1.0" rustix = { version = "0.38.30", features = ["fs"] } calloop-wayland-source = "0.4.0" +aliasable = "0.1.3" [dependencies.i18n-embed] version = "0.15.3" diff --git a/src/widgets/toplevels/toplevel_layout/axis_toplevel_layout.rs b/src/widgets/toplevels/toplevel_layout/axis_toplevel_layout.rs index e349766..bc8c850 100644 --- a/src/widgets/toplevels/toplevel_layout/axis_toplevel_layout.rs +++ b/src/widgets/toplevels/toplevel_layout/axis_toplevel_layout.rs @@ -1,3 +1,4 @@ +use aliasable::vec::AliasableVec; use cosmic::iced::{advanced::layout::flex::Axis, Length, Point, Rectangle, Size}; use std::marker::PhantomData; @@ -70,7 +71,7 @@ pub trait AxisToplevelLayout { fn layout( &self, max_limit: AxisSize, - toplevels: Vec>, + toplevels: &[LayoutToplevel<'_, AxisSize>], ) -> impl Iterator; } @@ -79,10 +80,10 @@ impl ToplevelLayout for T { self.size().pack(self.axis()) } - fn layout( + fn layout<'a>( &self, max_limit: Size, - toplevels: &[LayoutToplevel<'_>], + toplevels: &[LayoutToplevel<'a>], ) -> impl Iterator { let max_limit = AxisSize::unpack(self.axis(), max_limit); let toplevels = toplevels @@ -92,7 +93,27 @@ impl ToplevelLayout for T { _phantom_data: PhantomData, }) .collect::>(); - self.layout(max_limit, toplevels) - .map(|rect| rect.pack(self.axis())) + let toplevels = AliasableVec::from_unique(toplevels); + // Extend lifetime + let toplevels_slice = + unsafe { std::mem::transmute::<_, &'a [LayoutToplevel<'a, AxisSize>]>(&*toplevels) }; + let inner = self + .layout(max_limit, toplevels_slice) + .map(|rect| rect.pack(self.axis())); + AxisLayoutIterator { inner, toplevels } + } +} + +struct AxisLayoutIterator<'a, I: Iterator> { + inner: I, + // After `inner` so it is dropped only after that is dropped + toplevels: AliasableVec>, +} + +impl<'a, I: Iterator> Iterator for AxisLayoutIterator<'a, I> { + type Item = Rectangle; + + fn next(&mut self) -> Option { + self.inner.next() } } diff --git a/src/widgets/toplevels/toplevel_layout/row_col_toplevel_layout.rs b/src/widgets/toplevels/toplevel_layout/row_col_toplevel_layout.rs index 9e4c193..1ec209c 100644 --- a/src/widgets/toplevels/toplevel_layout/row_col_toplevel_layout.rs +++ b/src/widgets/toplevels/toplevel_layout/row_col_toplevel_layout.rs @@ -33,7 +33,7 @@ impl AxisToplevelLayout for RowColToplevelLayout { fn layout( &self, max_limit: AxisSize, - toplevels: Vec>, + toplevels: &[LayoutToplevel<'_, AxisSize>], ) -> impl Iterator { let requested_main_total = self.requested_main_total(&toplevels); let scale_factor = (max_limit.main / requested_main_total).min(1.0);