Skip to content

Commit

Permalink
update iced
Browse files Browse the repository at this point in the history
  • Loading branch information
git-f0x committed Nov 15, 2024
1 parent 39de757 commit 6cd36d1
Show file tree
Hide file tree
Showing 9 changed files with 1,803 additions and 916 deletions.
2,424 changes: 1,659 additions & 765 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ cosmic-greeter-daemon = { path = "daemon" }
dirs = "5"
env_logger.workspace = true
freedesktop_entry_parser = "1.3.0"
libcosmic = { workspace = true, features = ["tokio", "wayland"] }
libcosmic = { workspace = true, features = [
"tokio",
"wayland",
"multi-window",
"winit",
] }
log.workspace = true
pam-client = "0.5.0"
pwd.workspace = true
Expand Down
149 changes: 73 additions & 76 deletions src/greeter.rs

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions src/greeter/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only

use super::{Message, SocketState};
use cosmic::iced::Subscription;
use cosmic::iced::{stream, Subscription};
use futures_util::SinkExt;
use greetd_ipc::codec::TokioCodec;
use std::sync::Arc;
Expand All @@ -11,10 +11,9 @@ use tokio::sync::mpsc;

pub fn subscription() -> Subscription<Message> {
struct GreetdSubscription;
cosmic::iced::subscription::channel(
Subscription::run_with_id(
std::any::TypeId::of::<GreetdSubscription>(),
1,
|mut sender| async move {
stream::channel(1, |mut sender| async move {
let (tx, mut rx) = mpsc::channel::<greetd_ipc::Request>(1);
_ = sender.send(Message::GreetdChannel(tx)).await;

Expand Down Expand Up @@ -123,6 +122,6 @@ pub fn subscription() -> Subscription<Message> {
}

futures_util::future::pending().await
},
}),
)
}
16 changes: 9 additions & 7 deletions src/image_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@ use cosmic::iced::widget::{
image::{draw, FilterMethod, Handle},
Container,
};
use cosmic::iced::ContentFit;
use cosmic::iced::{ContentFit, Radians, Vector};
use cosmic::iced_core::event::{self, Event};
use cosmic::iced_core::layout;
use cosmic::iced_core::mouse;
use cosmic::iced_core::overlay;
use cosmic::iced_core::renderer;
use cosmic::iced_core::widget::{Operation, Tree};
use cosmic::iced_core::{Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Widget};
use cosmic::iced_renderer::core::widget::OperationOutputWrapper;

pub use cosmic::iced_style::container::StyleSheet;
pub use cosmic::widget::container::Catalog;

pub struct ImageContainer<'a, Message, Theme, Renderer>
where
Renderer: cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer<Handle = Handle>,
Theme: StyleSheet,
Theme: Catalog,
{
container: Container<'a, Message, Theme, Renderer>,
image_opt: Option<Handle>,
Expand All @@ -27,7 +26,7 @@ where
impl<'a, Message, Renderer> ImageContainer<'a, Message, cosmic::Theme, Renderer>
where
Renderer: cosmic::iced_core::Renderer + cosmic::iced_core::image::Renderer<Handle = Handle>,
cosmic::Theme: StyleSheet,
cosmic::Theme: Catalog,
{
pub fn new(container: Container<'a, Message, cosmic::Theme, Renderer>) -> Self {
Self {
Expand Down Expand Up @@ -79,7 +78,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
operation: &mut dyn Operation<()>,
) {
self.container.operate(tree, layout, renderer, operation)
}
Expand Down Expand Up @@ -129,6 +128,8 @@ where
image,
self.content_fit,
FilterMethod::Linear,
Radians(0.0).into(),
1.0,
[0.0, 0.0, 0.0, 0.0],
),
None => {}
Expand All @@ -150,8 +151,9 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, Renderer>> {
self.container.overlay(tree, layout, renderer)
self.container.overlay(tree, layout, renderer, translation)
}
}

Expand Down
87 changes: 40 additions & 47 deletions src/locker.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// Copyright 2023 System76 <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only

use cosmic::app::{message, Command, Core, Settings};
use cosmic::app::{message, Core, Settings, Task};
use cosmic::{
executor,
iced::{
self, alignment,
self,
event::{
self,
wayland::{Event as WaylandEvent, OutputEvent, SessionLockEvent},
},
futures::{self, SinkExt},
subscription,
wayland::session_lock::{destroy_lock_surface, get_lock_surface, lock, unlock},
Length, Subscription,
stream, Alignment, Length, Subscription,
},
iced_runtime::core::window::Id as SurfaceId,
iced_winit::wayland::commands::session_lock::{
destroy_lock_surface, get_lock_surface, lock, unlock,
},
style, widget, Element,
};
use cosmic_config::CosmicConfigEntry;
Expand Down Expand Up @@ -55,7 +56,7 @@ pub fn main(current_user: pwd::Passwd) -> Result<(), Box<dyn std::error::Error>>
let icon_path = Path::new("/var/lib/AccountsService/icons").join(&current_user.name);
let icon_opt = if icon_path.is_file() {
match fs::read(&icon_path) {
Ok(icon_data) => Some(widget::image::Handle::from_memory(icon_data)),
Ok(icon_data) => Some(widget::image::Handle::from_bytes(icon_data)),
Err(err) => {
log::error!("failed to read {:?}: {:?}", icon_path, err);
None
Expand Down Expand Up @@ -274,7 +275,7 @@ impl App {
cosmic_bg_config::Source::Path(path) => {
match fs::read(path) {
Ok(bytes) => {
let image = widget::image::Handle::from_memory(bytes);
let image = widget::image::Handle::from_bytes(bytes);
self.surface_images.insert(*surface_id, image);
//TODO: what to do about duplicates?
break;
Expand Down Expand Up @@ -323,7 +324,7 @@ impl cosmic::Application for App {
}

/// Creates the application, and optionally emits command on initialize.
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
fn init(mut core: Core, flags: Self::Flags) -> (Self, Task<Self::Message>) {
core.window.show_window_menu = false;
core.window.show_headerbar = false;
core.window.sharp_corners = true;
Expand Down Expand Up @@ -361,7 +362,7 @@ impl cosmic::Application for App {
lock()
} else {
// When logind feature is used, wait for lock signal
Command::none()
Task::none()
}
} else {
// When logind feature not used, lock immediately
Expand All @@ -374,7 +375,7 @@ impl cosmic::Application for App {
}

/// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
match message {
Message::None => {}
Message::OutputEvent(output_event, output) => {
Expand Down Expand Up @@ -416,7 +417,7 @@ impl cosmic::Application for App {
.insert(surface_id, text_input_id.clone());

if matches!(self.state, State::Locked) {
return Command::batch([
return Task::batch([
get_lock_surface(surface_id, output),
widget::text_input::focus(text_input_id),
]);
Expand Down Expand Up @@ -461,7 +462,7 @@ impl cosmic::Application for App {
for (output, surface_id) in self.surface_ids.iter() {
commands.push(get_lock_surface(*surface_id, output.clone()));
}
return Command::batch(commands);
return Task::batch(commands);
}
SessionLockEvent::Unlocked => {
log::info!("session unlocked");
Expand Down Expand Up @@ -584,7 +585,7 @@ impl cosmic::Application for App {
// Tell compositor to unlock
commands.push(unlock());
// Wait to exit until `Unlocked` event, when server has processed unlock
return Command::batch(commands);
return Task::batch(commands);
}
State::Locking => {
log::info!("session still locking");
Expand All @@ -595,7 +596,7 @@ impl cosmic::Application for App {
}
}
}
Command::none()
Task::none()
}

// Not used for layer surface window
Expand All @@ -614,13 +615,13 @@ impl cosmic::Application for App {

let date = dt.format_localized("%A, %B %-d", locale);
column = column
.push(widget::text::title2(format!("{}", date)).style(style::Text::Accent));
.push(widget::text::title2(format!("{}", date)).class(style::Text::Accent));

let time = dt.format_localized("%R", locale);
column = column.push(
widget::text(format!("{}", time))
.size(112.0)
.style(style::Text::Accent),
.class(style::Text::Accent),
);

column
Expand All @@ -641,18 +642,18 @@ impl cosmic::Application for App {

//TODO: implement these buttons
let button_row = iced::widget::row![
widget::button(widget::icon::from_name(
widget::button::custom(widget::icon::from_name(
"applications-accessibility-symbolic"
))
.padding(12.0)
.on_press(Message::None),
widget::button(widget::icon::from_name("input-keyboard-symbolic"))
widget::button::custom(widget::icon::from_name("input-keyboard-symbolic"))
.padding(12.0)
.on_press(Message::None),
widget::button(widget::icon::from_name("system-users-symbolic"))
widget::button::custom(widget::icon::from_name("system-users-symbolic"))
.padding(12.0)
.on_press(Message::None),
widget::button(widget::icon::from_name("system-suspend-symbolic"))
widget::button::custom(widget::icon::from_name("system-suspend-symbolic"))
.padding(12.0)
.on_press(Message::Suspend),
]
Expand All @@ -667,7 +668,7 @@ impl cosmic::Application for App {
button_row,
])
.width(Length::Fill)
.align_x(alignment::Horizontal::Left)
.align_x(Alignment::Start)
};

let right_element = {
Expand All @@ -683,8 +684,7 @@ impl cosmic::Application for App {
.width(Length::Fixed(78.0))
.height(Length::Fixed(78.0)),
)
.width(Length::Fill)
.align_x(alignment::Horizontal::Center),
.center_x(Length::Fill),
)
}
None => {}
Expand All @@ -699,9 +699,7 @@ impl cosmic::Application for App {
Some(gecos) => {
let full_name = gecos.split(",").next().unwrap_or_default();
column = column.push(
widget::container(widget::text::title4(full_name))
.width(Length::Fill)
.align_x(alignment::Horizontal::Center),
widget::container(widget::text::title4(full_name)).center_x(Length::Fill),
);
}
None => {}
Expand Down Expand Up @@ -744,27 +742,24 @@ impl cosmic::Application for App {
column = column.push(widget::text(error));
}

widget::container(column)
.align_x(alignment::Horizontal::Center)
.width(Length::Fill)
widget::container(column).center_x(Length::Fill)
};

crate::image_container::ImageContainer::new(
widget::container(
widget::layer_container(
iced::widget::row![left_element, right_element]
.align_items(alignment::Alignment::Center),
iced::widget::row![left_element, right_element].align_y(Alignment::Center),
)
.layer(cosmic::cosmic_theme::Layer::Background)
.padding(16)
.style(cosmic::theme::Container::Custom(Box::new(
.class(cosmic::theme::Container::Custom(Box::new(
|theme: &cosmic::Theme| {
// Use background appearance as the base
let mut appearance = widget::container::StyleSheet::appearance(
let mut appearance = widget::container::Catalog::style(
theme,
&cosmic::theme::Container::Background,
);
appearance.border = iced::Border::with_radius(16.0);
appearance.border = iced::Border::rounded(appearance.border, 16.0);
appearance
},
)))
Expand All @@ -773,14 +768,14 @@ impl cosmic::Application for App {
.padding([32.0, 0.0, 0.0, 0.0])
.width(Length::Fill)
.height(Length::Fill)
.align_x(alignment::Horizontal::Center)
.align_y(alignment::Vertical::Top)
.style(cosmic::theme::Container::Transparent),
.align_x(Alignment::Center)
.align_y(Alignment::Start)
.class(cosmic::theme::Container::Transparent),
)
.image(match self.surface_images.get(&surface_id) {
Some(some) => some.clone(),
//TODO: default image
None => widget::image::Handle::from_pixels(1, 1, vec![0x00, 0x00, 0x00, 0xFF]),
None => widget::image::Handle::from_rgba(1, 1, vec![0x00, 0x00, 0x00, 0xFF]),
})
.content_fit(iced::ContentFit::Cover)
.into()
Expand All @@ -789,7 +784,7 @@ impl cosmic::Application for App {
fn subscription(&self) -> Subscription<Self::Message> {
let mut subscriptions = Vec::with_capacity(7);

subscriptions.push(event::listen_with(|event, _| match event {
subscriptions.push(event::listen_with(|event, _, _| match event {
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(
wayland_event,
)) => match wayland_event {
Expand Down Expand Up @@ -819,26 +814,24 @@ impl cosmic::Application for App {

if matches!(self.state, State::Locked) {
struct HeartbeatSubscription;
subscriptions.push(subscription::channel(
subscriptions.push(Subscription::run_with_id(
TypeId::of::<HeartbeatSubscription>(),
16,
|mut msg_tx| async move {
stream::channel(16, |mut msg_tx| async move {
loop {
// Send heartbeat once a second to update time
//TODO: only send this when needed
msg_tx.send(Message::None).await.unwrap();
time::sleep(time::Duration::new(1, 0)).await;
}
},
}),
));

struct PamSubscription;
//TODO: how to avoid cloning this on every time subscription is called?
let username = self.flags.current_user.name.clone();
subscriptions.push(subscription::channel(
subscriptions.push(Subscription::run_with_id(
TypeId::of::<PamSubscription>(),
16,
|mut msg_tx| async move {
stream::channel(16, |mut msg_tx| async move {
loop {
let (value_tx, value_rx) = mpsc::channel(16);
msg_tx.send(Message::Channel(value_tx)).await.unwrap();
Expand Down Expand Up @@ -869,7 +862,7 @@ impl cosmic::Application for App {
loop {
time::sleep(time::Duration::new(60, 0)).await;
}
},
}),
));
}

Expand Down
Loading

0 comments on commit 6cd36d1

Please sign in to comment.