From 12e449e0507bf3c8304e0c9a622827015ef57349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Sat, 2 May 2026 18:29:31 +0200 Subject: [PATCH] fix(size_cross_nth): get `max_cross` after constraining main Prevents visual cross sizes for the main widget and other children from becoming different. This happened when the title height became a significant-enough chunk of max main that it interfered with the preview aspect ratio after its relayout with the previously unaccounted for title height, which caused its width to shrink (to keep the aspect ratio), while the title remained at `max_cross`. --- src/widgets/size_cross_nth.rs | 36 +++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/widgets/size_cross_nth.rs b/src/widgets/size_cross_nth.rs index 9b33e7f..82a8a74 100644 --- a/src/widgets/size_cross_nth.rs +++ b/src/widgets/size_cross_nth.rs @@ -1,10 +1,10 @@ // This widget defines it's cross axis size as the `index`th child's size use cosmic::iced::advanced::layout::flex::Axis; -use cosmic::iced::advanced::layout::{self}; +use cosmic::iced::advanced::layout::{self, Limits}; use cosmic::iced::advanced::widget::{Operation, Tree}; use cosmic::iced::advanced::{Clipboard, Layout, Shell, Widget, mouse, renderer}; -use cosmic::iced::event::{self, Event}; +use cosmic::iced::event::Event; use cosmic::iced::{Length, Point, Rectangle, Size}; use std::marker::PhantomData; @@ -74,25 +74,38 @@ impl Widget for SizeCrossNth<'_, Msg> &mut self, tree: &mut Tree, renderer: &cosmic::Renderer, - limits: &layout::Limits, + limits: &Limits, ) -> layout::Node { let max_main = self.axis.main(limits.max()); let max_cross = self.axis.cross(limits.max()); - // XXX cleaner solution - // Get layout of main widget, to set overall cross axis size - let (max_width, max_height) = self.axis.pack(max_main, max_cross); - let child_limits = layout::Limits::new(Size::ZERO, Size::new(max_width, max_height)); + // Lay out all non-reference children to get their total main size + let mut total_main = 0.0; + for (i, (child, tree)) in self + .children + .iter_mut() + .zip(tree.children.iter_mut()) + .enumerate() + { + if i != self.index { + let (max_width, max_height) = self.axis.pack(max_main - total_main, max_cross); + let child_limits = Limits::new(Size::ZERO, Size::new(max_width, max_height)); + let layout = child.as_widget_mut().layout(tree, renderer, &child_limits); + total_main += self.axis.main(layout.size()); + } + } + + // Lay out reference child with remaining main to get max cross size + let (max_width, max_height) = self.axis.pack(max_main - total_main, max_cross); + let child_limits = Limits::new(Size::ZERO, Size::new(max_width, max_height)); let layout = self.children[self.index].as_widget_mut().layout( &mut tree.children[self.index], renderer, &child_limits, ); - let max_cross = self.axis.cross(layout.size()); - // XXX sill allocating maximum main axis? - // - what was it doing before? + // Lay out all children constrained to reference cross let mut total_main = 0.0; let nodes = self .children @@ -100,8 +113,7 @@ impl Widget for SizeCrossNth<'_, Msg> .zip(tree.children.iter_mut()) .map(|(child, tree)| { let (max_width, max_height) = self.axis.pack(max_main - total_main, max_cross); - let child_limits = - layout::Limits::new(Size::ZERO, Size::new(max_width, max_height)); + let child_limits = Limits::new(Size::ZERO, Size::new(max_width, max_height)); let mut layout = child.as_widget_mut().layout(tree, renderer, &child_limits); // Center on cross axis let cross = ((max_cross - self.axis.cross(layout.size())) / 2.).max(0.);