chore: update iced/libcosmic

This commit is contained in:
Vukašin Vojinović 2024-10-24 00:15:05 +02:00 committed by Victoria Brekenfeld
parent 0d0b89d538
commit 7de52054ff
12 changed files with 502 additions and 549 deletions

603
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,10 @@ use crate::{
use calloop::LoopHandle;
use cosmic::{
iced::widget::{column, container, horizontal_space, row, vertical_space},
iced::{
widget::{column, container, horizontal_space, row, vertical_space},
Alignment,
},
iced_core::{Background, Border, Color, Length},
theme,
widget::{icon::from_name, text},
@ -66,7 +69,7 @@ impl Program for ResizeIndicatorInternal {
fn view(&self) -> cosmic::Element<'_, Self::Message> {
let edges = self.edges.lock().unwrap();
let icon_container_style = || {
theme::Container::custom(|theme| container::Appearance {
theme::Container::custom(|theme| container::Style {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
@ -90,14 +93,13 @@ impl Program for ResizeIndicatorInternal {
.prefer_svg(true)
.apply(container)
.padding(8)
.style(icon_container_style())
.class(icon_container_style())
.width(Length::Shrink)
.apply(container)
.center_x()
.width(Length::Fill)
.center_x(Length::Fill)
.into()
} else {
vertical_space(36).into()
vertical_space().height(36).into()
},
row(vec![
if edges.contains(ResizeEdge::LEFT) {
@ -110,35 +112,32 @@ impl Program for ResizeIndicatorInternal {
.prefer_svg(true)
.apply(container)
.padding(8)
.style(icon_container_style())
.class(icon_container_style())
.width(Length::Shrink)
.apply(container)
.center_y()
.height(Length::Fill)
.center_y(Length::Fill)
.into()
} else {
horizontal_space(36).into()
horizontal_space().width(36).into()
},
row(vec![
text::heading(&self.shortcut1).into(),
text::body(fl!("grow-window")).into(),
horizontal_space(40).into(),
horizontal_space().width(40).into(),
text::heading(&self.shortcut2).into(),
text::body(fl!("shrink-window")).into(),
])
.apply(container)
.center_x()
.center_y()
.align_x(Alignment::Center)
.align_y(Alignment::Center)
.padding(16)
.apply(container)
.style(icon_container_style())
.class(icon_container_style())
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.height(Length::Fill)
.width(Length::Fill)
.center_x()
.center_y()
.center_x(Length::Fill)
.center_y(Length::Fill)
.into(),
if edges.contains(ResizeEdge::RIGHT) {
from_name(if self.direction == ResizeDirection::Outwards {
@ -150,14 +149,13 @@ impl Program for ResizeIndicatorInternal {
.prefer_svg(true)
.apply(container)
.padding(8)
.style(icon_container_style())
.class(icon_container_style())
.height(Length::Shrink)
.apply(container)
.center_y()
.height(Length::Fill)
.center_y(Length::Fill)
.into()
} else {
horizontal_space(36).into()
horizontal_space().width(36).into()
},
])
.width(Length::Fill)
@ -173,14 +171,13 @@ impl Program for ResizeIndicatorInternal {
.prefer_svg(true)
.apply(container)
.padding(8)
.style(icon_container_style())
.class(icon_container_style())
.width(Length::Shrink)
.apply(container)
.center_x()
.width(Length::Fill)
.center_x(Length::Fill)
.into()
} else {
vertical_space(36).into()
vertical_space().height(36).into()
},
])
.into()

View file

@ -14,9 +14,9 @@ use crate::{
};
use calloop::LoopHandle;
use cosmic::{
iced::{id::Id, widget as iced_widget},
iced::{id::Id, widget as iced_widget, Alignment},
iced_core::{border::Radius, Background, Border, Color, Length},
iced_runtime::Command,
iced_runtime::Task,
iced_widget::scrollable::AbsoluteOffset,
theme, widget as cosmic_widget, Apply, Element as CosmicElement, Theme,
};
@ -712,7 +712,7 @@ impl Program for CosmicStackInternal {
&mut self,
message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> {
) -> Task<Self::Message> {
match message {
Message::DragStart => {
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
@ -874,7 +874,7 @@ impl Program for CosmicStackInternal {
}
_ => unreachable!(),
}
Command::none()
Task::none()
}
fn view(&self) -> CosmicElement<'_, Self::Message> {
@ -890,8 +890,8 @@ impl Program for CosmicStackInternal {
.size(16)
.prefer_svg(true)
.icon()
.style(if group_focused {
theme::Svg::custom(|theme| iced_widget::svg::Appearance {
.class(if group_focused {
theme::Svg::custom(|theme| iced_widget::svg::Style {
color: Some(if theme.cosmic().is_dark {
Color::BLACK
} else {
@ -903,7 +903,7 @@ impl Program for CosmicStackInternal {
})
.apply(iced_widget::container)
.padding([4, 24])
.center_y()
.align_y(Alignment::Center)
.apply(iced_widget::mouse_area)
.on_press(Message::DragStart)
.on_right_press(Message::Menu)
@ -935,7 +935,8 @@ impl Program for CosmicStackInternal {
.height(Length::Fill)
.width(Length::Fill),
),
iced_widget::horizontal_space(0)
iced_widget::horizontal_space()
.width(Length::Fixed(0.0))
.apply(iced_widget::container)
.padding([64, 24])
.apply(iced_widget::mouse_area)
@ -953,10 +954,10 @@ impl Program for CosmicStackInternal {
iced_widget::row(elements)
.height(TAB_HEIGHT as u16)
.width(Length::Fill) //width as u16)
.width(Length::Fill)
.apply(iced_widget::container)
.center_y()
.style(theme::Container::custom(move |theme| {
.align_y(Alignment::Center)
.class(theme::Container::custom(move |theme| {
let background = if group_focused {
Some(Background::Color(theme.cosmic().accent_color().into()))
} else {
@ -965,7 +966,7 @@ impl Program for CosmicStackInternal {
)))
};
iced_widget::container::Appearance {
iced_widget::container::Style {
icon_color: Some(Color::from(theme.cosmic().background.on)),
text_color: Some(Color::from(theme.cosmic().background.on)),
background,

View file

@ -5,11 +5,7 @@ use cosmic::{
alignment, event,
layout::{Layout, Limits, Node},
mouse, overlay, renderer,
widget::{
operation::{Operation, OperationOutputWrapper},
tree::Tree,
Id, Widget,
},
widget::{operation::Operation, tree::Tree, Id, Widget},
Border, Clipboard, Color, Length, Rectangle, Shell, Size,
},
iced_widget::scrollable::AbsoluteOffset,
@ -54,19 +50,19 @@ pub(super) enum TabRuleTheme {
impl From<TabRuleTheme> for theme::Rule {
fn from(theme: TabRuleTheme) -> Self {
match theme {
TabRuleTheme::ActiveActivated => Self::custom(|theme| widget::rule::Appearance {
TabRuleTheme::ActiveActivated => Self::custom(|theme| widget::rule::Style {
color: theme.cosmic().accent_color().into(),
width: 4,
radius: 0.0.into(),
fill_mode: FillMode::Full,
}),
TabRuleTheme::ActiveDeactivated => Self::custom(|theme| widget::rule::Appearance {
TabRuleTheme::ActiveDeactivated => Self::custom(|theme| widget::rule::Style {
color: theme.cosmic().palette.neutral_5.into(),
width: 4,
radius: 0.0.into(),
fill_mode: FillMode::Full,
}),
TabRuleTheme::Default => Self::custom(|theme| widget::rule::Appearance {
TabRuleTheme::Default => Self::custom(|theme| widget::rule::Style {
color: theme.cosmic().palette.neutral_5.into(),
width: 4,
radius: 8.0.into(),
@ -96,11 +92,11 @@ impl TabBackgroundTheme {
}
}
impl From<TabBackgroundTheme> for theme::Container {
impl From<TabBackgroundTheme> for theme::Container<'_> {
fn from(background_theme: TabBackgroundTheme) -> Self {
match background_theme {
TabBackgroundTheme::ActiveActivated => {
Self::custom(move |theme| widget::container::Appearance {
Self::custom(move |theme| widget::container::Style {
icon_color: Some(Color::from(theme.cosmic().accent_text_color())),
text_color: Some(Color::from(theme.cosmic().accent_text_color())),
background: Some(background_theme.background_color(theme).into()),
@ -113,7 +109,7 @@ impl From<TabBackgroundTheme> for theme::Container {
})
}
TabBackgroundTheme::ActiveDeactivated => {
Self::custom(move |theme| widget::container::Appearance {
Self::custom(move |theme| widget::container::Style {
icon_color: None,
text_color: None,
background: Some(background_theme.background_color(theme).into()),
@ -215,20 +211,19 @@ impl<Message: TabMessage + 'static> Tab<Message> {
.icon()
.apply(widget::button)
.padding(0)
.style(theme::iced::Button::Text);
.class(theme::iced::Button::Text);
if let Some(close_message) = self.close_message {
close_button = close_button.on_press(close_message);
}
let items = vec![
widget::vertical_rule(4).style(self.rule_theme).into(),
widget::vertical_rule(4).class(self.rule_theme).into(),
self.app_icon
.clone()
.apply(widget::container)
.height(Length::Fill)
.width(Length::Shrink)
.padding([2, 4])
.center_y()
.center_y(Length::Fill)
.into(),
tab_text(self.title, self.active)
.font(self.font)
@ -238,10 +233,9 @@ impl<Message: TabMessage + 'static> Tab<Message> {
.into(),
close_button
.apply(widget::container)
.height(Length::Fill)
.width(Length::Shrink)
.padding([2, 4])
.center_y()
.center_y(Length::Fill)
.align_x(alignment::Horizontal::Right)
.into(),
];
@ -269,7 +263,7 @@ pub(super) struct TabInternal<'a, Message: TabMessage> {
id: Id,
idx: usize,
active: bool,
background: theme::Container,
background: theme::Container<'a>,
elements: Vec<cosmic::Element<'a, Message>>,
press_message: Option<Message>,
right_click_message: Option<Message>,
@ -347,7 +341,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.elements
@ -454,8 +448,8 @@ where
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
use cosmic::widget::container::StyleSheet;
let style = theme.appearance(&self.background);
use cosmic::widget::container::Catalog;
let style = theme.style(&self.background);
draw_background(renderer, &style, layout.bounds());
@ -486,7 +480,8 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
translation: cosmic::iced::Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
overlay::from_children(&mut self.elements, tree, layout, renderer)
overlay::from_children(&mut self.elements, tree, layout, renderer, translation)
}
}

View file

@ -84,7 +84,7 @@ impl TabText {
vertical_alignment: alignment::Vertical::Center,
shaping: Shaping::Advanced,
line_height: LineHeight::default(),
wrap: cosmic::iced::advanced::text::Wrap::None,
wrapping: cosmic::iced::advanced::text::Wrapping::None,
})
}
}

View file

@ -8,7 +8,7 @@ use cosmic::{
widget::{
operation::{
scrollable::{AbsoluteOffset, RelativeOffset},
Operation, OperationOutputWrapper, Scrollable,
Operation, Scrollable,
},
tree::{self, Tree},
Widget,
@ -16,10 +16,9 @@ use cosmic::{
Background, Border, Clipboard, Color, Length, Point, Rectangle, Renderer, Shell, Size,
Vector,
},
iced_style::container::StyleSheet as ContainerStyleSheet,
iced_widget::container::draw_background,
theme,
widget::icon::from_name,
widget::{container::Catalog, icon::from_name},
Apply,
};
use keyframe::{
@ -45,6 +44,7 @@ struct ScrollAnimationState {
start_time: Instant,
start: Offset,
end: Offset,
extra: Offset,
}
#[derive(Debug, Clone)]
@ -75,9 +75,24 @@ impl Scrollable for State {
start_time: Instant::now(),
start: self.offset_x,
end: new_offset,
extra: Offset::Absolute(0.),
});
self.offset_x = new_offset;
}
fn scroll_by(
&mut self,
offset: AbsoluteOffset,
_bounds: Rectangle,
_content_bounds: Rectangle,
) {
self.scroll_animation = Some(ScrollAnimationState {
start_time: Instant::now(),
start: self.offset_x,
end: self.offset_x,
extra: Offset::Absolute(offset.x.max(0.0)),
});
}
}
impl Default for State {
@ -145,7 +160,7 @@ where
Element::new(tab.internal(i))
});
let tabs_rule = widget::vertical_rule(4).style(if tabs.len() - 1 == active {
let tabs_rule = widget::vertical_rule(4).class(if tabs.len() - 1 == active {
if activated {
TabRuleTheme::ActiveActivated
} else {
@ -166,7 +181,7 @@ where
.prefer_svg(true)
.icon()
.apply(widget::button)
.style(theme::iced::Button::Text)
.class(theme::iced::Button::Text)
.on_press(Message::scroll_back());
let next_button = from_name("go-next-symbolic")
@ -174,17 +189,17 @@ where
.prefer_svg(true)
.icon()
.apply(widget::button)
.style(theme::iced::Button::Text)
.class(theme::iced::Button::Text)
.on_press(Message::scroll_further());
let mut elements = Vec::with_capacity(tabs.len() + 5);
elements.push(widget::vertical_rule(4).style(rule_style).into());
elements.push(widget::vertical_rule(4).class(rule_style).into());
elements.push(prev_button.into());
elements.extend(tabs);
elements.push(tabs_rule.into());
elements.push(next_button.into());
elements.push(widget::vertical_rule(4).style(rule_style).into());
elements.push(widget::vertical_rule(4).class(rule_style).into());
Tabs {
elements,
@ -239,6 +254,7 @@ impl State {
Vector::new(
animation.start.absolute(bounds.width, content_bounds.width)
+ animation.extra.absolute(bounds.width, content_bounds.width) * percentage
+ (animation.end.absolute(bounds.width, content_bounds.width)
- animation.start.absolute(bounds.width, content_bounds.width))
* percentage,
@ -490,9 +506,9 @@ where
height: b.bounds().height,
});
let background_style = ContainerStyleSheet::appearance(
let background_style = Catalog::style(
theme,
&theme::Container::custom(|theme| widget::container::Appearance {
&theme::Container::custom(|theme| widget::container::Style {
icon_color: None,
text_color: None,
background: Some(Background::Color(super::tab::primary_container_color(
@ -666,10 +682,12 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
operation: &mut dyn Operation<()>,
) {
let state = tree.state.downcast_mut::<State>();
let bounds = layout.bounds();
let content_layout = layout.children().next().unwrap();
let content_bounds = content_layout.bounds();
state.cleanup_old_animations();
@ -677,6 +695,7 @@ where
state,
self.id.as_ref(),
bounds,
content_bounds,
Vector { x: 0.0, y: 0.0 }, /* seemingly unused */
);
@ -819,6 +838,7 @@ where
start_time: Instant::now(),
start: Offset::Absolute(offset.x),
end: Offset::Absolute(new_offset.x),
extra: Offset::Absolute(0.),
});
state.offset_x = Offset::Absolute(new_offset.x);
}
@ -993,7 +1013,8 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
translation: cosmic::iced::Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
overlay::from_children(&mut self.elements, tree, layout, renderer)
overlay::from_children(&mut self.elements, tree, layout, renderer, translation)
}
}

View file

@ -38,16 +38,16 @@ impl Program for StackHoverInternal {
.prefer_svg(true)
.icon()
.into(),
horizontal_space(16).into(),
horizontal_space().width(16).into(),
text::title3(fl!("stack-windows")).into(),
])
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.apply(container)
.center_x()
.center_y()
.align_x(Alignment::Center)
.align_y(Alignment::Center)
.padding(16)
.apply(container)
.style(theme::Container::custom(|theme| container::Appearance {
.class(theme::Container::custom(|theme| container::Style {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
@ -61,10 +61,8 @@ impl Program for StackHoverInternal {
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y()
.center_x(Length::Fill)
.center_y(Length::Fill)
.into()
}
}

View file

@ -34,16 +34,16 @@ impl Program for SwapIndicatorInternal {
.prefer_svg(true)
.icon()
.into(),
horizontal_space(16).into(),
horizontal_space().width(16).into(),
text::title3(fl!("swap-windows")).into(),
])
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.apply(container)
.center_x()
.center_y()
.align_x(Alignment::Center)
.align_y(Alignment::Center)
.padding(16)
.apply(container)
.style(theme::Container::custom(|theme| container::Appearance {
.class(theme::Container::custom(|theme| container::Style {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
@ -57,10 +57,8 @@ impl Program for SwapIndicatorInternal {
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.height(Length::Fill)
.width(Length::Fill)
.center_x()
.center_y()
.center_x(Length::Fill)
.center_y(Length::Fill)
.into()
}
}

View file

@ -11,7 +11,7 @@ use crate::{
},
};
use calloop::LoopHandle;
use cosmic::iced::{Color, Command};
use cosmic::iced::{Color, Task};
use smithay::{
backend::{
input::KeyState,
@ -404,7 +404,7 @@ impl Program for CosmicWindowInternal {
&mut self,
message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> {
) -> Task<Self::Message> {
match message {
Message::DragStart => {
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
@ -504,7 +504,7 @@ impl Program for CosmicWindowInternal {
}
}
}
Command::none()
Task::none()
}
fn background_color(&self, theme: &cosmic::Theme) -> Color {
@ -517,7 +517,7 @@ impl Program for CosmicWindowInternal {
fn view(&self) -> cosmic::Element<'_, Self::Message> {
let mut header = cosmic::widget::header_bar()
.start(cosmic::widget::horizontal_space(32))
.start(cosmic::widget::horizontal_space().width(32))
.title(self.last_title.lock().unwrap().clone())
.on_drag(Message::DragStart)
.on_close(Message::Close)
@ -528,12 +528,12 @@ impl Program for CosmicWindowInternal {
if cosmic::config::show_minimize() {
header = header
.on_minimize(Message::Minimize)
.start(cosmic::widget::horizontal_space(40)); // 32 + 8 spacing
.start(cosmic::widget::horizontal_space().width(40)); // 32 + 8 spacing
}
if cosmic::config::show_maximize() {
header = header
.on_maximize(Message::Maximize)
.start(cosmic::widget::horizontal_space(40)); // 32 + 8 spacing
.start(cosmic::widget::horizontal_space().width(40)); // 32 + 8 spacing
}
header.into()

View file

@ -3,17 +3,17 @@ use cosmic::{
iced_core::{
event, layout, mouse, overlay,
renderer::{Quad, Style},
widget::{tree, Id, OperationOutputWrapper, Tree, Widget},
widget::{tree, Id, Tree, Widget},
Background, Border, Clipboard, Color, Event, Layout, Length, Rectangle,
Renderer as IcedRenderer, Shell, Size,
},
widget::button::StyleSheet,
widget::button::Catalog,
};
pub struct SubmenuItem<'a, Message> {
elem: cosmic::Element<'a, Message>,
idx: usize,
styling: <cosmic::Theme as StyleSheet>::Style,
styling: <cosmic::Theme as Catalog>::Class,
}
impl<'a, Message> SubmenuItem<'a, Message> {
@ -25,7 +25,7 @@ impl<'a, Message> SubmenuItem<'a, Message> {
}
}
pub fn style(mut self, style: <cosmic::Theme as StyleSheet>::Style) -> Self {
pub fn style(mut self, style: <cosmic::Theme as Catalog>::Class) -> Self {
self.styling = style;
self
}
@ -133,7 +133,7 @@ where
state: &mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
operation: &mut dyn cosmic::widget::Operation<OperationOutputWrapper<Message>>,
operation: &mut dyn cosmic::widget::Operation<()>,
) {
let state = &mut state.children[0];
let layout = layout.children().next().unwrap();
@ -206,10 +206,13 @@ where
state: &'b mut Tree,
layout: Layout<'_>,
renderer: &cosmic::Renderer,
translation: cosmic::iced::Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
let state = &mut state.children[0];
let layout = layout.children().next().unwrap();
self.elem.as_widget_mut().overlay(state, layout, renderer)
self.elem
.as_widget_mut()
.overlay(state, layout, renderer, translation)
}
}

View file

@ -7,10 +7,10 @@ use calloop::LoopHandle;
use cosmic::{
iced::{Alignment, Background},
iced_core::{alignment::Horizontal, Border, Length, Rectangle as IcedRectangle},
iced_widget::{self, text::Appearance as TextAppearance, Column, Row},
iced_widget::{self, text::Style as TextStyle, Column, Row},
theme,
widget::{button, divider, horizontal_space, icon::from_name, text},
Apply as _, Command,
Apply as _, Task,
};
use smithay::{
backend::{
@ -202,7 +202,7 @@ impl Program for ContextMenu {
&mut self,
message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> {
) -> Task<Self::Message> {
match message {
Message::ItemPressed(idx) => {
if let Some(Item::Entry { on_press, .. }) = self.items.get_mut(idx) {
@ -331,7 +331,7 @@ impl Program for ContextMenu {
}
};
Command::none()
Task::none()
}
fn view(&self) -> cosmic::Element<'_, Self::Message> {
@ -350,7 +350,7 @@ impl Program for ContextMenu {
match item {
Item::Separator => divider::horizontal::light().into(),
Item::Submenu { title, .. } => Row::with_children(vec![
horizontal_space(16).into(),
horizontal_space().width(16).into(),
text::body(title).width(mode).into(),
from_name("go-next-symbolic")
.size(16)
@ -361,7 +361,7 @@ impl Program for ContextMenu {
.spacing(8)
.width(width)
.padding([8, 16])
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.apply(|row| item::SubmenuItem::new(row, idx))
.style(theme::Button::MenuItem)
.into(),
@ -378,20 +378,20 @@ impl Program for ContextMenu {
.size(16)
.prefer_svg(true)
.icon()
.style(theme::Svg::custom(|theme| iced_widget::svg::Appearance {
.class(theme::Svg::custom(|theme| iced_widget::svg::Style {
color: Some(theme.cosmic().accent.base.into()),
}))
.into()
} else {
horizontal_space(16).into()
horizontal_space().width(16).into()
},
text::body(title)
.width(mode)
.style(if *disabled {
.class(if *disabled {
theme::Text::Custom(|theme| {
let mut color = theme.cosmic().background.component.on;
color.alpha *= 0.5;
TextAppearance {
TextStyle {
color: Some(color.into()),
}
})
@ -399,17 +399,17 @@ impl Program for ContextMenu {
theme::Text::Default
})
.into(),
horizontal_space(16).into(),
horizontal_space().width(16).into(),
];
if let Some(shortcut) = shortcut.as_ref() {
components.push(
text::body(shortcut)
.horizontal_alignment(Horizontal::Right)
.align_x(Horizontal::Right)
.width(Length::Shrink)
.style(theme::Text::Custom(|theme| {
.class(theme::Text::Custom(|theme| {
let mut color = theme.cosmic().background.component.on;
color.alpha *= 0.75;
TextAppearance {
TextStyle {
color: Some(color.into()),
}
}))
@ -420,12 +420,12 @@ impl Program for ContextMenu {
Row::with_children(components)
.spacing(8)
.width(mode)
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.apply(button::custom)
.width(width)
.padding([8, 16])
.on_press_maybe((!disabled).then_some(Message::ItemPressed(idx)))
.style(theme::Button::MenuItem)
.class(theme::Button::MenuItem)
.into()
}
}
@ -433,10 +433,10 @@ impl Program for ContextMenu {
.width(Length::Shrink)
.apply(iced_widget::container)
.padding(1)
.style(theme::Container::custom(|theme| {
.class(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background.component;
iced_widget::container::Appearance {
iced_widget::container::Style {
icon_color: Some(cosmic.accent.base.into()),
text_color: Some(component.on.into()),
background: Some(Background::Color(component.base.into())),

View file

@ -10,26 +10,24 @@ use cosmic::{
iced::{
advanced::widget::Tree,
event::Event,
futures::{FutureExt, StreamExt},
keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers},
mouse::{Button as MouseButton, Cursor, Event as MouseEvent, ScrollDelta},
touch::{Event as TouchEvent, Finger},
window::{Event as WindowEvent, Id},
Command, Limits, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize,
window::Event as WindowEvent,
Limits, Point as IcedPoint, Size as IcedSize, Task,
},
iced_core::{clipboard::Null as NullClipboard, renderer::Style, Color, Length, Pixels},
iced_renderer::graphics::Renderer as IcedGraphicsRenderer,
iced_core::{clipboard::Null as NullClipboard, id::Id, renderer::Style, Color, Length, Pixels},
iced_runtime::{
command::Action,
program::{Program as IcedProgram, State},
Debug,
task::into_stream,
Action, Debug,
},
Theme,
};
use iced_tiny_skia::{
graphics::{damage, Viewport},
Backend, Primitive,
};
use iced_tiny_skia::{graphics::Viewport, Primitive};
use once_cell::sync::Lazy;
use ordered_float::OrderedFloat;
use smithay::{
backend::{
@ -67,6 +65,8 @@ use smithay::{
},
};
static ID: Lazy<Id> = Lazy::new(|| Id::new("Program"));
pub struct IcedElement<P: Program + Send + 'static>(pub(crate) Arc<Mutex<IcedElementInternal<P>>>);
impl<P: Program + Send + 'static> fmt::Debug for IcedElement<P> {
@ -104,9 +104,9 @@ pub trait Program {
&mut self,
message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> {
) -> Task<Self::Message> {
let _ = (message, loop_handle);
Command::none()
Task::none()
}
fn view(&self) -> cosmic::Element<'_, Self::Message>;
@ -131,7 +131,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
type Renderer = cosmic::Renderer;
type Theme = cosmic::Theme;
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
self.0.update(message, &self.1)
}
@ -159,9 +159,9 @@ pub(crate) struct IcedElementInternal<P: Program + Send + 'static> {
// futures
handle: LoopHandle<'static, crate::state::State>,
scheduler: Scheduler<<P as Program>::Message>,
scheduler: Scheduler<Option<<P as Program>::Message>>,
executor_token: Option<RegistrationToken>,
rx: Receiver<<P as Program>::Message>,
rx: Receiver<Option<<P as Program>::Message>>,
}
impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
@ -178,14 +178,10 @@ impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
if !self.state.is_queue_empty() {
tracing::warn!("Missing force_update call");
}
let mut renderer = cosmic::Renderer::TinySkia(IcedGraphicsRenderer::new(
Backend::new(),
cosmic::font::default(),
Pixels(16.0),
));
let mut renderer = cosmic::Renderer::new(cosmic::font::default(), Pixels(16.0));
let mut debug = Debug::new();
let state = State::new(
Id::MAIN,
ID.clone(),
ProgramWrapper(self.state.program().0.clone(), handle.clone()),
IcedSize::new(self.size.w as f32, self.size.h as f32),
&mut renderer,
@ -244,15 +240,11 @@ impl<P: Program + Send + 'static> IcedElement<P> {
theme: cosmic::Theme,
) -> IcedElement<P> {
let size = size.into();
let mut renderer = cosmic::Renderer::TinySkia(IcedGraphicsRenderer::new(
Backend::new(),
cosmic::font::default(),
Pixels(16.0),
));
let mut renderer = cosmic::Renderer::new(cosmic::font::default(), Pixels(16.0));
let mut debug = Debug::new();
let state = State::new(
Id::MAIN,
ID.clone(),
ProgramWrapper(program, handle.clone()),
IcedSize::new(size.w as f32, size.h as f32),
&mut renderer,
@ -368,8 +360,8 @@ impl<P: Program + Send + 'static + Clone> IcedElement<P> {
impl<P: Program + Send + 'static> IcedElementInternal<P> {
#[profiling::function]
fn update(&mut self, mut force: bool) -> Vec<Action<<P as Program>::Message>> {
while let Ok(message) = self.rx.try_recv() {
fn update(&mut self, mut force: bool) -> Vec<Task<<P as Program>::Message>> {
while let Ok(Some(message)) = self.rx.try_recv() {
self.state.queue_message(message);
force = true;
}
@ -383,17 +375,16 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
.map(|p| IcedPoint::new(p.x as f32, p.y as f32))
.map(Cursor::Available)
.unwrap_or(Cursor::Unavailable);
let actions = self
.state
.update(
Id::MAIN,
ID.clone(),
IcedSize::new(self.size.w as f32, self.size.h as f32),
cursor,
&mut self.renderer,
&self.theme,
&Style {
scale_factor: 1.0, //TODO: why is this
scale_factor: 1.0, // TODO: why is this
icon_color: self.theme.cosmic().on_bg_color().into(),
text_color: self.theme.cosmic().on_bg_color().into(),
},
@ -402,17 +393,15 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
)
.1;
actions
.into_iter()
.filter_map(|action| {
if let Action::Future(future) = action {
let _ = self.scheduler.schedule(future);
None
} else {
Some(action)
if let Some(action) = actions {
if let Some(t) = into_stream(action) {
let _ = self.scheduler.schedule(t.into_future().map(|f| match f.0 {
Some(Action::Output(msg)) => Some(msg),
_ => None,
}));
}
})
.collect::<Vec<_>>()
}
Vec::new()
}
}
@ -751,14 +740,11 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
fn set_activate(&self, activated: bool) {
let mut internal = self.0.lock().unwrap();
internal.state.queue_event(Event::Window(
Id::MAIN,
if activated {
internal.state.queue_event(Event::Window(if activated {
WindowEvent::Focused
} else {
WindowEvent::Unfocused
},
));
}));
let _ = internal.update(true); // TODO
}
@ -860,64 +846,48 @@ where
} else {
false
};
if force {
internal_ref.pending_update = None;
}
let _ = internal_ref.update(force);
if let Some((buffer, ref mut old_primitives)) =
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
{
if let Some((buffer, _)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) {
let size: Size<i32, BufferCoords> = internal_ref
.size
.to_f64()
.to_buffer(scale.x, Transform::Normal)
.to_i32_round();
if size.w > 0 && size.h > 0 {
let cosmic::Renderer::TinySkia(renderer) = &mut internal_ref.renderer;
let state_ref = &internal_ref.state;
let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
let overlay = internal_ref.debug.overlay();
let theme = &internal_ref.theme;
buffer
.render()
.draw(move |buf| {
_ = buffer.render().draw(|buf| {
let mut pixels =
tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32)
.expect("Failed to create pixel map");
renderer.with_primitives(|backend, primitives| {
let background_color = state_ref.program().0.background_color(theme);
let bounds = IcedSize::new(size.w as u32, size.h as u32);
let viewport = Viewport::with_physical_size(bounds, scale.x);
let mut damage = old_primitives
.as_ref()
.and_then(|(last_primitives, last_color)| {
(last_color == &background_color)
.then(|| damage::list(last_primitives, primitives))
})
.unwrap_or_else(|| {
vec![IcedRectangle::with_size(viewport.logical_size())]
});
damage = damage::group(damage, scale.x as f32, bounds);
let damage = vec![cosmic::iced::Rectangle::new(
cosmic::iced::Point::default(),
viewport.logical_size(),
)];
if !damage.is_empty() {
backend.draw(
internal_ref.renderer.draw(
&mut pixels,
&mut clip_mask,
primitives,
&viewport,
&damage,
background_color,
&overlay,
);
*old_primitives = Some((primitives.to_vec(), background_color));
}
let damage = damage
.into_iter()
.map(|x| x.snap())
.filter_map(|x| x.snap())
.map(|damage_rect| {
Rectangle::from_loc_and_size(
(damage_rect.x as i32, damage_rect.y as i32),
@ -925,18 +895,13 @@ where
)
})
.collect::<Vec<_>>();
state_ref.program().0.foreground(
&mut pixels,
&damage,
scale.x as f32,
theme,
);
state_ref
.program()
.0
.foreground(&mut pixels, &damage, scale.x as f32, theme);
Result::<_, ()>::Ok(damage)
})
})
.unwrap();
});
}
if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer(
@ -946,9 +911,11 @@ where
Some(alpha),
Some(Rectangle::from_loc_and_size(
(0., 0.),
size.to_f64().to_logical(1.0, Transform::Normal),
size.to_f64()
.to_logical(1., Transform::Normal)
.to_i32_round(),
)),
Some(internal_ref.size),
Some(size.to_logical(1, Transform::Normal)),
Kind::Unspecified,
) {
return vec![C::from(buffer)];