chore: updates after iced rebase

This commit is contained in:
Ashley Wulber 2026-03-03 13:53:45 -05:00 committed by Ashley Wulber
parent 45e01aa6e6
commit d4becdd6c5
15 changed files with 1329 additions and 1118 deletions

2092
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -7,8 +7,8 @@ edition = "2024"
anyhow = "1.0.102" anyhow = "1.0.102"
calloop = { version = "0.14.4", features = ["executor"] } calloop = { version = "0.14.4", features = ["executor"] }
clap = { version = "4", features = ["derive"] } clap = { version = "4", features = ["derive"] }
cosmic-bg-config = { git = "https://github.com/pop-os/cosmic-bg" } cosmic-bg-config = { git = "https://github.com/pop-os/cosmic-bg", branch = "iced-rebase" }
cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp" } cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp", branch = "iced-rebase" }
env_logger = "0.11.9" env_logger = "0.11.9"
gbm = "0.18.0" gbm = "0.18.0"
libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = [ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = [
@ -18,8 +18,8 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = fa
"desktop", "desktop",
"multi-window", "multi-window",
"winit", "winit",
] } ], branch = "iced-rebase" }
cosmic-config = { git = "https://github.com/pop-os/libcosmic" } cosmic-config = { git = "https://github.com/pop-os/libcosmic", branch = "iced-rebase" }
freedesktop-icons = { package = "cosmic-freedesktop-icons", git = "https://github.com/pop-os/freedesktop-icons" } freedesktop-icons = { package = "cosmic-freedesktop-icons", git = "https://github.com/pop-os/freedesktop-icons" }
memmap2 = "0.9.10" memmap2 = "0.9.10"
@ -37,7 +37,7 @@ zbus = "5.13.2"
tokio-stream = { version = "0.1.18", features = ["sync"] } tokio-stream = { version = "0.1.18", features = ["sync"] }
ash = { version = "0.38.0", features = ["loaded"] } ash = { version = "0.38.0", features = ["loaded"] }
bytemuck = "1.25.0" bytemuck = "1.25.0"
cosmic-panel-config = { git = "https://github.com/pop-os/cosmic-panel" } cosmic-panel-config = { git = "https://github.com/pop-os/cosmic-panel", branch = "iced-rebase" }
[dependencies.i18n-embed] [dependencies.i18n-embed]
version = "0.16" version = "0.16"

View file

@ -30,7 +30,7 @@ use cosmic::{
}, },
}, },
}; };
use std::{cell::RefCell, collections::HashMap, sync::Arc, thread}; use std::{cell::RefCell, collections::HashMap, hash::Hash, sync::Arc, thread};
mod buffer; mod buffer;
use buffer::Buffer; use buffer::Buffer;
@ -48,7 +48,20 @@ mod workspace;
use super::{CaptureFilter, CaptureImage, Cmd, Event}; use super::{CaptureFilter, CaptureImage, Cmd, Event};
pub fn subscription(conn: Connection) -> iced::Subscription<Event> { pub fn subscription(conn: Connection) -> iced::Subscription<Event> {
iced::Subscription::run_with_id("wayland-sub", async { start(conn) }.flatten_stream()) #[derive(Clone)]
struct WaylandSubscription(Connection);
impl Hash for WaylandSubscription {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.backend().display_id().hash(state);
}
}
iced::Subscription::run_with(
WaylandSubscription(conn.clone()),
|WaylandSubscription(conn)| {
let conn = conn.clone();
async { start(conn) }.flatten_stream()
},
)
} }
pub struct AppData { pub struct AppData {

View file

@ -1,4 +1,5 @@
use cosmic::iced::{self, futures::StreamExt}; use cosmic::iced::{self, futures::StreamExt};
use std::{any::TypeId, hash::Hash};
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tokio_stream::wrappers::BroadcastStream; use tokio_stream::wrappers::BroadcastStream;
@ -65,9 +66,23 @@ impl Interface {
} }
pub fn subscription(&self) -> iced::Subscription<Event> { pub fn subscription(&self) -> iced::Subscription<Event> {
iced::Subscription::run_with_id( #[derive(Clone)]
"workspaces-dbus-sun", struct Wrapper {
BroadcastStream::new(self.event_sender.subscribe()).filter_map(|x| async { x.ok() }), event_sender: broadcast::Sender<Event>,
}
impl Hash for Wrapper {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
TypeId::of::<Wrapper>().hash(state);
}
}
iced::Subscription::run_with(
Wrapper {
event_sender: self.event_sender.clone(),
},
|Wrapper { event_sender }| {
BroadcastStream::new(event_sender.subscribe()).filter_map(|x| async { x.ok() })
},
) )
} }
} }

View file

@ -289,7 +289,7 @@ fn workspace_item(
}; };
let workspace_footer = row![ let workspace_footer = row![
widget::horizontal_space().width(Length::Fixed(32.0)), widget::space::horizontal().width(Length::Fixed(32.0)),
widget::text::body(fl!("workspace", number = workspace.info.name.as_str())) widget::text::body(fl!("workspace", number = workspace.info.name.as_str()))
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(1))) .ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(1)))
.apply(widget::container) .apply(widget::container)
@ -346,14 +346,18 @@ fn workspace_drag_placeholder(
other_workspace.handle().clone(), other_workspace.handle().clone(),
other_output.clone(), other_output.clone(),
); );
let placeholder = widget::button::custom(widget::Space::new(Length::Fill, Length::Fill)) let placeholder = widget::button::custom(
.class(cosmic::theme::Button::Custom { widget::Space::new()
active: Box::new(|_, _| unreachable!()), .width(Length::Fill)
disabled: Box::new(|theme| workspace_item_appearance(theme, true, true)), .height(Length::Fill),
hovered: Box::new(|_, _| unreachable!()), )
pressed: Box::new(|_, _| unreachable!()), .class(cosmic::theme::Button::Custom {
}) active: Box::new(|_, _| unreachable!()),
.padding(8); disabled: Box::new(|theme| workspace_item_appearance(theme, true, true)),
hovered: Box::new(|_, _| unreachable!()),
pressed: Box::new(|_, _| unreachable!()),
})
.padding(8);
let placeholder = crate::widgets::match_size( let placeholder = crate::widgets::match_size(
workspace_item(other_workspace, other_output, layout, true, true), workspace_item(other_workspace, other_output, layout, true, true),
placeholder, placeholder,
@ -439,7 +443,10 @@ fn workspaces_sidebar<'a>(
DragWorkspace {}, DragWorkspace {},
DragSurface::Workspace(workspace.handle().clone()), DragSurface::Workspace(workspace.handle().clone()),
Some(workspace.dnd_source_id.clone()), Some(workspace.dnd_source_id.clone()),
widget::Space::new(Length::Shrink, Length::Shrink).into(), widget::Space::new()
.width(Length::Shrink)
.height(Length::Shrink)
.into(),
move || workspace_item(&workspace_clone, &output_clone, layout, false, true), move || workspace_item(&workspace_clone, &output_clone, layout, false, true),
); );
sidebar_entries.push(source); sidebar_entries.push(source);
@ -502,6 +509,7 @@ fn workspaces_sidebar<'a>(
..Default::default() ..Default::default()
}, },
shadow: Shadow::default(), shadow: Shadow::default(),
snap: true,
} }
})), })),
) )

View file

@ -41,19 +41,6 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for ImageBg<'_, Msg> {
fn children(&self) -> Vec<Tree>; fn children(&self) -> Vec<Tree>;
fn size(&self) -> Size<Length>; fn size(&self) -> Size<Length>;
fn size_hint(&self) -> Size<Length>; fn size_hint(&self) -> Size<Length>;
fn layout(
&self,
tree: &mut Tree,
renderer: &cosmic::Renderer,
limits: &layout::Limits,
) -> layout::Node;
fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
fn mouse_interaction( fn mouse_interaction(
&self, &self,
tree: &Tree, tree: &Tree,
@ -66,24 +53,38 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for ImageBg<'_, Msg> {
to self.content.as_widget_mut() { to self.content.as_widget_mut() {
fn diff(&mut self, tree: &mut Tree); fn diff(&mut self, tree: &mut Tree);
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status; );
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
viewport: &Rectangle,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>; ) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>;
fn layout(
&mut self,
tree: &mut Tree,
renderer: &cosmic::Renderer,
limits: &layout::Limits,
) -> layout::Node;
fn operate(
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
} }
} }

View file

@ -41,32 +41,32 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for MatchSize<'_, Msg> {
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
self.matched self.matched
.as_widget() .as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation); .operate(&mut tree.children[0], layout, renderer, operation);
self.shown self.shown
.as_widget() .as_widget_mut()
.operate(&mut tree.children[1], layout, renderer, operation); .operate(&mut tree.children[1], layout, renderer, operation);
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
self.shown.as_widget_mut().on_event( self.shown.as_widget_mut().update(
&mut tree.children[1], &mut tree.children[1],
event, event,
layout, layout,
@ -96,14 +96,14 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for MatchSize<'_, Msg> {
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
// TODO? // TODO?
self.matched self.matched
.as_widget() .as_widget_mut()
.layout(&mut tree.children[0], renderer, limits) .layout(&mut tree.children[0], renderer, limits)
} }

View file

@ -39,13 +39,12 @@ pub struct LayoutWrapper<'a, Msg> {
impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for LayoutWrapper<'_, Msg> { impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for LayoutWrapper<'_, Msg> {
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
dbg!(limits); self.content.as_widget_mut().layout(tree, renderer, limits)
dbg!(self.content.as_widget().layout(tree, renderer, limits))
} }
delegate::delegate! { delegate::delegate! {
@ -55,13 +54,6 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for LayoutWrapper<'_, Msg
fn children(&self) -> Vec<Tree>; fn children(&self) -> Vec<Tree>;
fn size(&self) -> Size<Length>; fn size(&self) -> Size<Length>;
fn size_hint(&self) -> Size<Length>; fn size_hint(&self) -> Size<Length>;
fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
fn draw( fn draw(
&self, &self,
state: &Tree, state: &Tree,
@ -85,25 +77,33 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for LayoutWrapper<'_, Msg
to self.content.as_widget_mut() { to self.content.as_widget_mut() {
fn diff(&mut self, tree: &mut Tree); fn diff(&mut self, tree: &mut Tree);
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status; );
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
viewport: &Rectangle,
transation: Vector, transation: Vector,
) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>; ) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>;
fn set_id(&mut self, id: Id); fn set_id(&mut self, id: Id);
fn operate(
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
} }
} }
} }

View file

@ -34,19 +34,6 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for MouseInteractionWrapp
fn children(&self) -> Vec<Tree>; fn children(&self) -> Vec<Tree>;
fn size(&self) -> Size<Length>; fn size(&self) -> Size<Length>;
fn size_hint(&self) -> Size<Length>; fn size_hint(&self) -> Size<Length>;
fn layout(
&self,
tree: &mut Tree,
renderer: &cosmic::Renderer,
limits: &layout::Limits,
) -> layout::Node;
fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
fn draw( fn draw(
&self, &self,
state: &Tree, state: &Tree,
@ -62,25 +49,39 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for MouseInteractionWrapp
to self.content.as_widget_mut() { to self.content.as_widget_mut() {
fn diff(&mut self, tree: &mut Tree); fn diff(&mut self, tree: &mut Tree);
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status; );
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
viewport: &Rectangle,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>; ) -> Option<overlay::Element<'b, Msg, cosmic::Theme, cosmic::Renderer>>;
fn set_id(&mut self, id: Id); fn set_id(&mut self, id: Id);
fn layout(
&mut self,
tree: &mut Tree,
renderer: &cosmic::Renderer,
limits: &layout::Limits,
) -> layout::Node;
fn operate(
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>,
);
} }
} }

View file

@ -75,7 +75,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for SizeCrossNth<'_, Msg>
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
@ -87,7 +87,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for SizeCrossNth<'_, Msg>
// Get layout of main widget, to set overall cross axis size // Get layout of main widget, to set overall cross axis size
let (max_width, max_height) = self.axis.pack(max_main, max_cross); 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)); let child_limits = layout::Limits::new(Size::ZERO, Size::new(max_width, max_height));
let layout = self.children[self.index].as_widget().layout( let layout = self.children[self.index].as_widget_mut().layout(
&mut tree.children[self.index], &mut tree.children[self.index],
renderer, renderer,
&child_limits, &child_limits,
@ -100,13 +100,13 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for SizeCrossNth<'_, Msg>
let mut total_main = 0.0; let mut total_main = 0.0;
let nodes = self let nodes = self
.children .children
.iter() .iter_mut()
.zip(tree.children.iter_mut()) .zip(tree.children.iter_mut())
.map(|(child, tree)| { .map(|(child, tree)| {
let (max_width, max_height) = self.axis.pack(max_main - total_main, max_cross); let (max_width, max_height) = self.axis.pack(max_main - total_main, max_cross);
let child_limits = let child_limits =
layout::Limits::new(Size::ZERO, Size::new(max_width, max_height)); layout::Limits::new(Size::ZERO, Size::new(max_width, max_height));
let mut layout = child.as_widget().layout(tree, renderer, &child_limits); let mut layout = child.as_widget_mut().layout(tree, renderer, &child_limits);
// Center on cross axis // Center on cross axis
let cross = ((max_cross - self.axis.cross(layout.size())) / 2.).max(0.); let cross = ((max_cross - self.axis.cross(layout.size())) / 2.).max(0.);
let (x, y) = self.axis.pack(total_main, cross); let (x, y) = self.axis.pack(total_main, cross);
@ -122,53 +122,47 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for SizeCrossNth<'_, Msg>
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
operation.container(None, layout.bounds(), &mut |operation| { operation.container(None, layout.bounds());
operation.traverse(&mut |operation| {
self.children self.children
.iter() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.for_each(|((child, state), layout)| { .for_each(|((child, state), layout)| {
child child
.as_widget() .as_widget_mut()
.operate(state, layout, renderer, operation); .operate(state, layout, renderer, operation);
}); });
}); });
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
self.children for ((child, state), layout) in self
.children
.iter_mut() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.map(|((child, state), layout)| { {
child.as_widget_mut().on_event( child.as_widget_mut().update(
state, state, event, layout, cursor, renderer, clipboard, shell, viewport,
event.clone(), )
layout, }
cursor,
renderer,
clipboard,
shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
} }
fn mouse_interaction( fn mouse_interaction(

View file

@ -34,7 +34,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for Toplevels<'_, Msg> {
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
@ -42,10 +42,10 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for Toplevels<'_, Msg> {
// Call `.layout()` on each child with full limits to determine "preferred" sizes // Call `.layout()` on each child with full limits to determine "preferred" sizes
let layout_toplevels = self let layout_toplevels = self
.children .children
.iter() .iter_mut()
.zip(tree.children.iter_mut()) .zip(tree.children.iter_mut())
.map(|(child, tree)| { .map(|(child, tree)| {
let preferred_size = child.as_widget().layout(tree, renderer, limits).size(); let preferred_size = child.as_widget_mut().layout(tree, renderer, limits).size();
LayoutToplevel { LayoutToplevel {
preferred_size, preferred_size,
_phantom_data: PhantomData, _phantom_data: PhantomData,
@ -58,12 +58,12 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for Toplevels<'_, Msg> {
let nodes = self let nodes = self
.children .children
.iter() .iter_mut()
.zip(tree.children.iter_mut()) .zip(tree.children.iter_mut())
.zip(assigned_rects) .zip(assigned_rects)
.map(|((child, tree), assigned_rect)| { .map(|((child, tree), assigned_rect)| {
let child_limits = layout::Limits::new(Size::ZERO, assigned_rect.size()); let child_limits = layout::Limits::new(Size::ZERO, assigned_rect.size());
let layout = child.as_widget().layout(tree, renderer, &child_limits); let layout = child.as_widget_mut().layout(tree, renderer, &child_limits);
// Center on both axes, if child didn't consume full size allocation // Center on both axes, if child didn't consume full size allocation
let centering_offset = Vector::new( let centering_offset = Vector::new(
@ -78,53 +78,47 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for Toplevels<'_, Msg> {
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
operation.container(None, layout.bounds(), &mut |operation| { operation.container(None, layout.bounds());
operation.traverse(&mut |operation| {
self.children self.children
.iter() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.for_each(|((child, state), layout)| { .for_each(|((child, state), layout)| {
child child
.as_widget() .as_widget_mut()
.operate(state, layout, renderer, operation); .operate(state, layout, renderer, operation);
}); });
}); });
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
self.children for ((child, state), layout) in self
.children
.iter_mut() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.map(|((child, state), layout)| { {
child.as_widget_mut().on_event( child.as_widget_mut().update(
state, state, event, layout, cursor, renderer, clipboard, shell, viewport,
event.clone(), );
layout, }
cursor,
renderer,
clipboard,
shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
} }
fn mouse_interaction( fn mouse_interaction(

View file

@ -100,6 +100,7 @@ impl<T: AxisToplevelLayout> ToplevelLayout for T {
&*toplevels, &*toplevels,
) )
}; };
let inner = self let inner = self
.layout(max_limit, toplevels_slice) .layout(max_limit, toplevels_slice)
.map(|rect| rect.pack(self.axis())); .map(|rect| rect.pack(self.axis()));

View file

@ -55,12 +55,17 @@ impl AxisToplevelLayout for TwoRowColToplevelLayout {
// Better layout // Better layout
if two_row_scale_factor > scale_factor { if two_row_scale_factor > scale_factor {
// TODO padding // TODO padding
let row1 = self.0.layout(half_max_limit, &toplevels[..split_point]); let spacing = self.0.spacing as f32;
let row1 = self
.0
.layout(half_max_limit, &toplevels[..split_point])
.collect::<Vec<_>>()
.into_iter();
let row2 = self let row2 = self
.0 .0
.layout(half_max_limit, &toplevels[split_point..]) .layout(half_max_limit, &toplevels[split_point..])
.map(move |mut rect| { .map(move |mut rect| {
rect.origin.cross += half_max_limit.cross + self.0.spacing as f32; rect.origin.cross += half_max_limit.cross + spacing;
rect rect
}); });
return itertools::Either::Left(row1.chain(row2)); return itertools::Either::Left(row1.chain(row2));

View file

@ -37,29 +37,29 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for VisibilityWrapper<'_,
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
self.content self.content
.as_widget() .as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation); .operate(&mut tree.children[0], layout, renderer, operation);
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
self.content.as_widget_mut().on_event( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
layout, layout,
@ -68,7 +68,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for VisibilityWrapper<'_,
clipboard, clipboard,
shell, shell,
viewport, viewport,
) );
} }
fn mouse_interaction( fn mouse_interaction(
@ -89,13 +89,13 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for VisibilityWrapper<'_,
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
self.content self.content
.as_widget() .as_widget_mut()
.layout(&mut tree.children[0], renderer, limits) .layout(&mut tree.children[0], renderer, limits)
} }

View file

@ -67,7 +67,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for WorkspaceBar<'_, Msg>
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
@ -84,16 +84,17 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for WorkspaceBar<'_, Msg>
let max_cross = self.axis.cross(limits.max()); let max_cross = self.axis.cross(limits.max());
let mut total_main = 0.0; let mut total_main = 0.0;
let mut max_child_cross = 0.0; let mut max_child_cross = 0.0;
let children_len = self.children.len();
let nodes = self let nodes = self
.children .children
.iter() .iter_mut()
.zip(tree.children.iter_mut()) .zip(tree.children.iter_mut())
.enumerate() .enumerate()
.map(|(i, (child, tree))| { .map(|(i, (child, tree))| {
let (max_width, max_height) = self.axis.pack(max_main, max_cross); let (max_width, max_height) = self.axis.pack(max_main, max_cross);
let child_limits = let child_limits =
layout::Limits::new(Size::ZERO, Size::new(max_width, max_height)); layout::Limits::new(Size::ZERO, Size::new(max_width, max_height));
let mut layout = child.as_widget().layout(tree, renderer, &child_limits); let mut layout = child.as_widget_mut().layout(tree, renderer, &child_limits);
let child_size = layout.size(); let child_size = layout.size();
let (x, y) = self.axis.pack(total_main, 0.0); let (x, y) = self.axis.pack(total_main, 0.0);
layout = layout.move_to(Point::new(x, y)); layout = layout.move_to(Point::new(x, y));
@ -102,7 +103,7 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for WorkspaceBar<'_, Msg>
// XXX Don't add spacing for 0 length `dnd_source` placeholder widget // XXX Don't add spacing for 0 length `dnd_source` placeholder widget
if main != 0.0 { if main != 0.0 {
total_main += main; total_main += main;
if i < self.children.len() - 1 { if i < children_len - 1 {
total_main += spacing; total_main += spacing;
} }
} }
@ -116,53 +117,47 @@ impl<Msg> Widget<Msg, cosmic::Theme, cosmic::Renderer> for WorkspaceBar<'_, Msg>
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
operation.container(None, layout.bounds(), &mut |operation| { operation.container(None, layout.bounds());
operation.traverse(&mut |operation| {
self.children self.children
.iter() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.for_each(|((child, state), layout)| { .for_each(|((child, state), layout)| {
child child
.as_widget() .as_widget_mut()
.operate(state, layout, renderer, operation); .operate(state, layout, renderer, operation);
}); });
}); });
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Msg>, shell: &mut Shell<'_, Msg>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
self.children for ((child, state), layout) in self
.children
.iter_mut() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.map(|((child, state), layout)| { {
child.as_widget_mut().on_event( child.as_widget_mut().update(
state, state, event, layout, cursor, renderer, clipboard, shell, viewport,
event.clone(), );
layout, }
cursor,
renderer,
clipboard,
shell,
viewport,
)
})
.fold(event::Status::Ignored, event::Status::merge)
} }
fn mouse_interaction( fn mouse_interaction(