chore: updates after iced rebase
This commit is contained in:
parent
63cd93bddd
commit
89671a793f
10 changed files with 2367 additions and 2486 deletions
4282
Cargo.lock
generated
4282
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
37
Cargo.toml
37
Cargo.toml
|
|
@ -40,13 +40,20 @@ xdg = "3.0"
|
|||
#TODO: reduce features
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
wayland-client = "0.31.11"
|
||||
cosmic-settings-subscriptions = { git = "https://github.com/pop-os/cosmic-settings-subscriptions", default-features = false, features = [
|
||||
"accessibility",
|
||||
"cosmic_a11y_manager",
|
||||
] }
|
||||
# cosmic-settings-subscriptions = { git = "https://github.com/pop-os/cosmic-settings-subscriptions", default-features = false, features = [
|
||||
# "accessibility",
|
||||
# "cosmic_a11y_manager",
|
||||
# ] }
|
||||
|
||||
# cosmic-settings-daemon-config = { git = "https://github.com/pop-os/cosmic-settings-daemon", default-features = false, features = [
|
||||
# "greeter",
|
||||
# ] }
|
||||
cosmic-settings-accessibility-subscription = { git = "https://github.com/pop-os/cosmic-settings", default-features = false, branch = "iced-rebase" }
|
||||
cosmic-settings-a11y-manager-subscription = { git = "https://github.com/pop-os/cosmic-settings", default-features = false, branch = "iced-rebase" }
|
||||
cosmic-settings-daemon-config = { git = "https://github.com/pop-os/cosmic-settings-daemon", default-features = false, features = [
|
||||
"greeter",
|
||||
] }
|
||||
], branch = "iced-rebase" }
|
||||
|
||||
cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit" }
|
||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [
|
||||
"client",
|
||||
|
|
@ -129,14 +136,20 @@ cosmic-randr-shell = { git = "https://github.com/pop-os/cosmic-randr", default-f
|
|||
|
||||
[workspace.dependencies.cosmic-applets-config]
|
||||
git = "https://github.com/pop-os/cosmic-applets"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-applets/cosmic-applets-config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-bg-config]
|
||||
git = "https://github.com/pop-os/cosmic-bg"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-bg/config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-comp-config]
|
||||
git = "https://github.com/pop-os/cosmic-comp"
|
||||
branch = "iced-rebase"
|
||||
# path = "../cosmic-comp/cosmic-comp-config"
|
||||
default-features = false
|
||||
features = ["output", "randr"]
|
||||
|
||||
|
|
@ -145,14 +158,19 @@ path = "cosmic-greeter-config"
|
|||
|
||||
[workspace.dependencies.cosmic-config]
|
||||
git = "https://github.com/pop-os/libcosmic"
|
||||
branch = "iced-rebase"
|
||||
# path = "../libcosmic/cosmic-config"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.cosmic-theme]
|
||||
git = "https://github.com/pop-os/libcosmic"
|
||||
branch = "iced-rebase"
|
||||
# path = "../libcosmic/cosmic-theme"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.libcosmic]
|
||||
git = "https://github.com/pop-os/libcosmic"
|
||||
branch = "iced-rebase"
|
||||
default-features = false
|
||||
|
||||
[patch."https://github.com/smithay/client-toolkit.git"]
|
||||
|
|
@ -162,6 +180,9 @@ sctk = { package = "smithay-client-toolkit", version = "0.20.0" }
|
|||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols//" }
|
||||
cctk = { git = "https://github.com/pop-os/cosmic-protocols//", package = "cosmic-client-toolkit" }
|
||||
|
||||
# libcosmic = { path = "../libcosmic" }
|
||||
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
||||
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }
|
||||
[patch."https://github.com/pop-os/libcosmic"]
|
||||
iced_core = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" }
|
||||
iced_futures = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" }
|
||||
libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" }
|
||||
cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" }
|
||||
cosmic-theme = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "1.85.1"
|
||||
channel = "1.92.0"
|
||||
components = ["clippy", "rustfmt"]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use cosmic::cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity
|
|||
use cosmic::iced::event::listen_with;
|
||||
use cosmic::iced::{Point, Size, window};
|
||||
use cosmic::iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings;
|
||||
use cosmic::iced_runtime::task::widget;
|
||||
use cosmic::widget::text;
|
||||
use cosmic::{
|
||||
Element,
|
||||
|
|
@ -39,9 +40,7 @@ use cosmic::{
|
|||
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
||||
use cosmic_greeter_daemon::{UserData, UserFilter};
|
||||
use cosmic_randr_shell::{KdlParseWithError, List};
|
||||
use cosmic_settings_subscriptions::cosmic_a11y_manager::{
|
||||
AccessibilityEvent, AccessibilityRequest,
|
||||
};
|
||||
use cosmic_settings_a11y_manager_subscription::{AccessibilityEvent, AccessibilityRequest};
|
||||
use greetd_ipc::Request;
|
||||
use kdl::KdlDocument;
|
||||
use std::process::Stdio;
|
||||
|
|
@ -536,9 +535,11 @@ impl App {
|
|||
.width(Length::Fixed(16.0))
|
||||
.into()
|
||||
} else {
|
||||
widget::Space::with_width(Length::Fixed(17.0)).into()
|
||||
widget::space::horizontal()
|
||||
.width(Length::Fixed(17.0))
|
||||
.into()
|
||||
},
|
||||
widget::Space::with_width(Length::Fixed(8.0)).into(),
|
||||
widget::space::horizontal().width(Length::Fixed(8.0)).into(),
|
||||
widget::text(label)
|
||||
.align_x(iced::alignment::Horizontal::Left)
|
||||
.into(),
|
||||
|
|
@ -615,7 +616,7 @@ impl App {
|
|||
}
|
||||
let item_cnt = items.len();
|
||||
let menu_button = widget::menu::menu_button(vec![
|
||||
Element::from(widget::Space::with_width(Length::Fixed(10.0))),
|
||||
Element::from(widget::space::horizontal().width(Length::Fixed(10.0))),
|
||||
widget::text(fl!("enter-user"))
|
||||
.align_x(iced::alignment::Horizontal::Left)
|
||||
.into(),
|
||||
|
|
@ -767,7 +768,7 @@ impl App {
|
|||
|
||||
// Add top spacing for better visual appearance
|
||||
// Bottom of the password text input field should align with bottom of time widget
|
||||
column = column.push(widget::Space::with_height(Length::Fixed(space_height)));
|
||||
column = column.push(widget::space::vertical().height(Length::Fixed(space_height)));
|
||||
|
||||
match &self.socket_state {
|
||||
SocketState::Pending => {
|
||||
|
|
@ -799,10 +800,9 @@ impl App {
|
|||
} else {
|
||||
// Empty transparent box for users without icons
|
||||
column = column.push(
|
||||
widget::container(widget::Space::new(
|
||||
Length::Fixed(78.0),
|
||||
Length::Fixed(78.0),
|
||||
))
|
||||
widget::container(
|
||||
widget::space::horizontal().width(Length::Fixed(78.0)),
|
||||
)
|
||||
.padding(0.0)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(78.0))
|
||||
|
|
@ -942,7 +942,9 @@ impl App {
|
|||
.width(Length::Fill)
|
||||
};
|
||||
let menu = widget::container(widget::column::with_children(vec![
|
||||
widget::Space::with_height(Length::FillPortion(1)).into(),
|
||||
widget::space::vertical()
|
||||
.height(Length::FillPortion(1))
|
||||
.into(),
|
||||
widget::layer_container(
|
||||
iced::widget::row![left_element, right_element].align_y(Alignment::Start),
|
||||
)
|
||||
|
|
@ -962,7 +964,9 @@ impl App {
|
|||
.class(cosmic::theme::Container::Background)
|
||||
.width(Length::Fixed(800.0))
|
||||
.into(),
|
||||
widget::Space::with_height(Length::FillPortion(4)).into(),
|
||||
widget::space::vertical()
|
||||
.height(Length::FillPortion(4))
|
||||
.into(),
|
||||
]))
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
|
|
@ -1285,7 +1289,7 @@ impl cosmic::Application for App {
|
|||
id: surface_id,
|
||||
layer: Layer::Overlay,
|
||||
keyboard_interactivity: KeyboardInteractivity::Exclusive,
|
||||
pointer_interactivity: true,
|
||||
input_zone: None,
|
||||
anchor: Anchor::TOP | Anchor::LEFT | Anchor::BOTTOM | Anchor::RIGHT,
|
||||
output: IcedOutput::Output(output),
|
||||
namespace: "cosmic-locker".into(),
|
||||
|
|
@ -1484,19 +1488,21 @@ impl cosmic::Application for App {
|
|||
|
||||
// Start spinner animation if not already running
|
||||
if self.spinner_handle.is_none() {
|
||||
let (spinner_task, handle) = cosmic::task::stream(
|
||||
cosmic::iced_futures::stream::channel(1, |mut msg_tx| async move {
|
||||
let mut interval = time::interval(Duration::from_millis(16)); // ~60fps
|
||||
loop {
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::SpinnerTick))
|
||||
.await
|
||||
.unwrap();
|
||||
interval.tick().await;
|
||||
}
|
||||
}),
|
||||
)
|
||||
.abortable();
|
||||
let (spinner_task, handle) =
|
||||
cosmic::task::stream(cosmic::iced_futures::stream::channel(
|
||||
1,
|
||||
|mut msg_tx: iced::futures::channel::mpsc::Sender<_>| async move {
|
||||
let mut interval = time::interval(Duration::from_millis(16)); // ~60fps
|
||||
loop {
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::SpinnerTick))
|
||||
.await
|
||||
.unwrap();
|
||||
interval.tick().await;
|
||||
}
|
||||
},
|
||||
))
|
||||
.abortable();
|
||||
self.spinner_handle = Some(handle);
|
||||
return spinner_task;
|
||||
}
|
||||
|
|
@ -1606,22 +1612,24 @@ impl cosmic::Application for App {
|
|||
});
|
||||
|
||||
if self.heartbeat_handle.is_none() {
|
||||
let (heartbeat, handle) = cosmic::task::stream(
|
||||
cosmic::iced_futures::stream::channel(1, |mut msg_tx| async move {
|
||||
let mut interval = time::interval(Duration::from_secs(1));
|
||||
let (heartbeat, handle) =
|
||||
cosmic::task::stream(cosmic::iced_futures::stream::channel(
|
||||
1,
|
||||
|mut msg_tx: iced::futures::channel::mpsc::Sender<_>| async move {
|
||||
let mut interval = time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
// Send heartbeat once a second to update time
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Heartbeat))
|
||||
.await
|
||||
.unwrap();
|
||||
loop {
|
||||
// Send heartbeat once a second to update time
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Heartbeat))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}),
|
||||
)
|
||||
.abortable();
|
||||
interval.tick().await;
|
||||
}
|
||||
},
|
||||
))
|
||||
.abortable();
|
||||
|
||||
self.heartbeat_handle = Some(handle);
|
||||
return heartbeat;
|
||||
|
|
|
|||
|
|
@ -38,139 +38,145 @@ fn greetd_error_to_message(error_type: greetd_ipc::ErrorType, description: &str)
|
|||
|
||||
pub fn subscription() -> Subscription<Message> {
|
||||
struct GreetdSubscription;
|
||||
Subscription::run_with_id(
|
||||
std::any::TypeId::of::<GreetdSubscription>(),
|
||||
cosmic::iced_futures::stream::channel(1, |mut sender| async move {
|
||||
let (tx, mut rx) = mpsc::channel::<greetd_ipc::Request>(1);
|
||||
_ = sender.send(Message::GreetdChannel(tx)).await;
|
||||
Subscription::run_with(std::any::TypeId::of::<GreetdSubscription>(), |_| {
|
||||
cosmic::iced_futures::stream::channel(
|
||||
1,
|
||||
|mut sender: cosmic::iced::futures::channel::mpsc::Sender<_>| async move {
|
||||
let (tx, mut rx) = mpsc::channel::<greetd_ipc::Request>(1);
|
||||
_ = sender.send(Message::GreetdChannel(tx)).await;
|
||||
|
||||
let socket_path =
|
||||
std::env::var_os("GREETD_SOCK").expect("GREETD_SOCK environment not set");
|
||||
let socket_path =
|
||||
std::env::var_os("GREETD_SOCK").expect("GREETD_SOCK environment not set");
|
||||
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
_ = sender.send(Message::Reconnect).await;
|
||||
loop {
|
||||
_ = sender.send(Message::Reconnect).await;
|
||||
|
||||
let mut stream = match UnixStream::connect(&socket_path).await {
|
||||
Ok(stream) => stream,
|
||||
Err(why) => {
|
||||
tracing::error!("greetd IPC socket connection failed: {why:?}");
|
||||
_ = sender.send(Message::Socket(SocketState::Error(Arc::new(why))));
|
||||
let mut stream = match UnixStream::connect(&socket_path).await {
|
||||
Ok(stream) => stream,
|
||||
Err(why) => {
|
||||
tracing::error!("greetd IPC socket connection failed: {why:?}");
|
||||
_ = sender.send(Message::Socket(SocketState::Error(Arc::new(why))));
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
_ = sender.send(Message::Socket(SocketState::Open)).await;
|
||||
_ = sender.send(Message::Socket(SocketState::Open)).await;
|
||||
|
||||
while let Some(request) = rx.recv().await {
|
||||
if let Err(why) = request.write_to(&mut stream).await {
|
||||
tracing::error!("error writing to GREETD_SOCK stream: {why:?}");
|
||||
break;
|
||||
}
|
||||
while let Some(request) = rx.recv().await {
|
||||
if let Err(why) = request.write_to(&mut stream).await {
|
||||
tracing::error!("error writing to GREETD_SOCK stream: {why:?}");
|
||||
break;
|
||||
}
|
||||
|
||||
match greetd_ipc::Response::read_from(&mut stream).await {
|
||||
Ok(response) => {
|
||||
match response {
|
||||
greetd_ipc::Response::AuthMessage {
|
||||
auth_message_type,
|
||||
auth_message,
|
||||
} => match auth_message_type {
|
||||
greetd_ipc::AuthMessageType::Secret => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(
|
||||
auth_message,
|
||||
true,
|
||||
Some(String::new()),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Visible => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(
|
||||
auth_message,
|
||||
false,
|
||||
Some(String::new()),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Info => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(auth_message, false, None)
|
||||
match greetd_ipc::Response::read_from(&mut stream).await {
|
||||
Ok(response) => {
|
||||
match response {
|
||||
greetd_ipc::Response::AuthMessage {
|
||||
auth_message_type,
|
||||
auth_message,
|
||||
} => match auth_message_type {
|
||||
greetd_ipc::AuthMessageType::Secret => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(
|
||||
auth_message,
|
||||
true,
|
||||
Some(String::new()),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Error => {
|
||||
_ = sender.send(Message::Error(auth_message)).await;
|
||||
}
|
||||
},
|
||||
greetd_ipc::Response::Error {
|
||||
error_type,
|
||||
description,
|
||||
} => {
|
||||
match request {
|
||||
greetd_ipc::Request::CancelSession => {
|
||||
// Do not send errors for cancel session to gui
|
||||
tracing::warn!(
|
||||
"error while cancelling session: {}",
|
||||
description
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Visible => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(
|
||||
auth_message,
|
||||
false,
|
||||
Some(String::new()),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Info => {
|
||||
_ = sender
|
||||
.send(
|
||||
common::Message::Prompt(
|
||||
auth_message,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
greetd_ipc::AuthMessageType::Error => {
|
||||
_ = sender.send(Message::Error(auth_message)).await;
|
||||
}
|
||||
},
|
||||
greetd_ipc::Response::Error {
|
||||
error_type,
|
||||
description,
|
||||
} => {
|
||||
match request {
|
||||
greetd_ipc::Request::CancelSession => {
|
||||
// Do not send errors for cancel session to gui
|
||||
tracing::warn!(
|
||||
"error while cancelling session: {}",
|
||||
description
|
||||
);
|
||||
|
||||
// Reconnect to socket
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
_ = sender
|
||||
.send(Message::Error(greetd_error_to_message(
|
||||
error_type,
|
||||
&description,
|
||||
)))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
greetd_ipc::Response::Success => match request {
|
||||
greetd_ipc::Request::CreateSession { .. } => {
|
||||
// User has no auth required, proceed to login
|
||||
_ = sender.send(Message::Login).await;
|
||||
}
|
||||
greetd_ipc::Request::PostAuthMessageResponse { .. } => {
|
||||
// All auth is completed, proceed to login
|
||||
_ = sender.send(Message::Login).await;
|
||||
}
|
||||
greetd_ipc::Request::StartSession { .. } => {
|
||||
// Session has been started, exit greeter
|
||||
_ = sender.send(Message::Exit).await;
|
||||
}
|
||||
greetd_ipc::Request::CancelSession => {
|
||||
tracing::info!("greetd IPC session canceled");
|
||||
// Reconnect to socket
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
_ = sender
|
||||
.send(Message::Error(greetd_error_to_message(
|
||||
error_type,
|
||||
&description,
|
||||
)))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
greetd_ipc::Response::Success => match request {
|
||||
greetd_ipc::Request::CreateSession { .. } => {
|
||||
// User has no auth required, proceed to login
|
||||
_ = sender.send(Message::Login).await;
|
||||
}
|
||||
greetd_ipc::Request::PostAuthMessageResponse { .. } => {
|
||||
// All auth is completed, proceed to login
|
||||
_ = sender.send(Message::Login).await;
|
||||
}
|
||||
greetd_ipc::Request::StartSession { .. } => {
|
||||
// Session has been started, exit greeter
|
||||
_ = sender.send(Message::Exit).await;
|
||||
}
|
||||
greetd_ipc::Request::CancelSession => {
|
||||
tracing::info!("greetd IPC session canceled");
|
||||
// Reconnect to socket
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("failed to read socket: {:?}", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("failed to read socket: {:?}", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tracing::info!("reconnecting to greetd IPC socket");
|
||||
interval.tick().await;
|
||||
}
|
||||
|
||||
tracing::info!("reconnecting to greetd IPC socket");
|
||||
interval.tick().await;
|
||||
}
|
||||
|
||||
futures_util::future::pending().await
|
||||
}),
|
||||
)
|
||||
futures_util::future::pending().await
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
171
src/locker.rs
171
src/locker.rs
|
|
@ -211,9 +211,7 @@ impl Conversation {
|
|||
|
||||
futures::executor::block_on(async {
|
||||
self.msg_tx
|
||||
.send(cosmic::Action::App(
|
||||
Message::Error(prompt.to_string()),
|
||||
))
|
||||
.send(cosmic::Action::App(Message::Error(prompt.to_string())))
|
||||
.await
|
||||
})
|
||||
.map_err(|err| {
|
||||
|
|
@ -367,9 +365,11 @@ impl App {
|
|||
.width(Length::Fixed(16.0))
|
||||
.into()
|
||||
} else {
|
||||
widget::Space::with_width(Length::Fixed(17.0)).into()
|
||||
widget::space::horizontal()
|
||||
.width(Length::Fixed(17.0))
|
||||
.into()
|
||||
},
|
||||
widget::Space::with_width(Length::Fixed(8.0)).into(),
|
||||
widget::space::horizontal().width(Length::Fixed(8.0)).into(),
|
||||
widget::text(label)
|
||||
.align_x(iced::alignment::Horizontal::Left)
|
||||
.into(),
|
||||
|
|
@ -477,7 +477,7 @@ impl App {
|
|||
|
||||
// Add top spacing for better visual appearance
|
||||
// Bottom of the password text input field should align with bottom of time widget
|
||||
column = column.push(widget::Space::with_height(Length::Fixed(space_height)));
|
||||
column = column.push(widget::space::vertical().height(Length::Fixed(space_height)));
|
||||
|
||||
// Display user icon or empty transparent box
|
||||
if let Some(icon_handle) = &self.flags.user_icon {
|
||||
|
|
@ -496,7 +496,7 @@ impl App {
|
|||
} else {
|
||||
// Empty transparent box for users without icons
|
||||
column = column.push(
|
||||
widget::container(widget::Space::new(Length::Fixed(78.0), Length::Fixed(78.0)))
|
||||
widget::container(widget::space::horizontal().width(Length::Fixed(78.0)))
|
||||
.padding(0.0)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(78.0))
|
||||
|
|
@ -602,7 +602,9 @@ impl App {
|
|||
};
|
||||
|
||||
widget::container(widget::column::with_children(vec![
|
||||
widget::Space::with_height(Length::FillPortion(1)).into(),
|
||||
widget::space::vertical()
|
||||
.height(Length::FillPortion(1))
|
||||
.into(),
|
||||
widget::layer_container(
|
||||
iced::widget::row![left_element, right_element].align_y(Alignment::Start),
|
||||
)
|
||||
|
|
@ -622,7 +624,9 @@ impl App {
|
|||
.width(Length::Fill)
|
||||
.height(Length::Shrink)
|
||||
.into(),
|
||||
widget::Space::with_height(Length::FillPortion(4)).into(),
|
||||
widget::space::vertical()
|
||||
.height(Length::FillPortion(4))
|
||||
.into(),
|
||||
]))
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
|
|
@ -865,72 +869,77 @@ impl cosmic::Application for App {
|
|||
}
|
||||
|
||||
let username = self.flags.user_data.name.clone();
|
||||
let (locked_task, locked_handle) = cosmic::task::stream(
|
||||
cosmic::iced_futures::stream::channel(16, |mut msg_tx| async move {
|
||||
// Send heartbeat once a second to update time.
|
||||
let heartbeat_future = {
|
||||
let mut output = msg_tx.clone();
|
||||
async move {
|
||||
let mut interval =
|
||||
tokio::time::interval(Duration::from_secs(1));
|
||||
let (locked_task, locked_handle) =
|
||||
cosmic::task::stream(cosmic::iced_futures::stream::channel(
|
||||
16,
|
||||
|mut msg_tx: futures::channel::mpsc::Sender<_>| async move {
|
||||
// Send heartbeat once a second to update time.
|
||||
let heartbeat_future = {
|
||||
let mut output = msg_tx.clone();
|
||||
async move {
|
||||
let mut interval =
|
||||
tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
output
|
||||
.send(cosmic::Action::App(Message::None))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let pam_future = async {
|
||||
loop {
|
||||
output
|
||||
.send(cosmic::Action::App(Message::None))
|
||||
let (value_tx, value_rx) = mpsc::channel(16);
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Channel(value_tx)))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
};
|
||||
let pam_res = {
|
||||
let username = username.clone();
|
||||
let msg_tx = msg_tx.clone();
|
||||
task::spawn_blocking(move || {
|
||||
pam_thread(
|
||||
username,
|
||||
Conversation { msg_tx, value_rx },
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let pam_future = async {
|
||||
loop {
|
||||
let (value_tx, value_rx) = mpsc::channel(16);
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Channel(value_tx)))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pam_res = {
|
||||
let username = username.clone();
|
||||
let msg_tx = msg_tx.clone();
|
||||
task::spawn_blocking(move || {
|
||||
pam_thread(username, Conversation { msg_tx, value_rx })
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
match pam_res {
|
||||
Ok(()) => {
|
||||
tracing::info!("successfully authenticated");
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Unlock))
|
||||
.await
|
||||
.unwrap();
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::warn!("authentication error: {}", err);
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Error(
|
||||
pam_error_to_message(&err),
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
match pam_res {
|
||||
Ok(()) => {
|
||||
tracing::info!("successfully authenticated");
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Unlock))
|
||||
.await
|
||||
.unwrap();
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::warn!("authentication error: {}", err);
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Error(
|
||||
pam_error_to_message(&err),
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
futures::pin_mut!(heartbeat_future);
|
||||
futures::pin_mut!(pam_future);
|
||||
futures::future::select(heartbeat_future, pam_future).await;
|
||||
}),
|
||||
)
|
||||
.abortable();
|
||||
futures::pin_mut!(heartbeat_future);
|
||||
futures::pin_mut!(pam_future);
|
||||
futures::future::select(heartbeat_future, pam_future).await;
|
||||
},
|
||||
))
|
||||
.abortable();
|
||||
|
||||
let mut commands = Vec::with_capacity(self.common.surface_ids.len() + 1);
|
||||
commands.push(locked_task);
|
||||
|
|
@ -1046,20 +1055,22 @@ impl cosmic::Application for App {
|
|||
Some(value_tx) => {
|
||||
// Start spinner animation if not already running
|
||||
if self.spinner_handle.is_none() {
|
||||
let (spinner_task, handle) = cosmic::task::stream(
|
||||
cosmic::iced_futures::stream::channel(1, |mut msg_tx| async move {
|
||||
let mut interval =
|
||||
tokio::time::interval(Duration::from_millis(16)); // ~60fps
|
||||
loop {
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::SpinnerTick))
|
||||
.await
|
||||
.unwrap();
|
||||
interval.tick().await;
|
||||
}
|
||||
}),
|
||||
)
|
||||
.abortable();
|
||||
let (spinner_task, handle) =
|
||||
cosmic::task::stream(cosmic::iced_futures::stream::channel(
|
||||
1,
|
||||
|mut msg_tx: futures::channel::mpsc::Sender<_>| async move {
|
||||
let mut interval =
|
||||
tokio::time::interval(Duration::from_millis(16)); // ~60fps
|
||||
loop {
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::SpinnerTick))
|
||||
.await
|
||||
.unwrap();
|
||||
interval.tick().await;
|
||||
}
|
||||
},
|
||||
))
|
||||
.abortable();
|
||||
self.spinner_handle = Some(handle);
|
||||
|
||||
return Task::batch([
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ async fn inhibit(manager: &ManagerProxy<'_>) -> zbus::Result<OwnedFd> {
|
|||
pub fn subscription() -> Subscription<Message> {
|
||||
struct LogindSubscription;
|
||||
|
||||
Subscription::run_with_id(
|
||||
TypeId::of::<LogindSubscription>(),
|
||||
Subscription::run_with(TypeId::of::<LogindSubscription>(), |_| {
|
||||
cosmic::iced_futures::stream::channel(16, |mut msg_tx| async move {
|
||||
match handler(&mut msg_tx).await {
|
||||
Ok(()) => {}
|
||||
|
|
@ -58,8 +57,8 @@ pub fn subscription() -> Subscription<Message> {
|
|||
}
|
||||
|
||||
std::process::exit(1);
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//TODO: use never type?
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ impl NetworkIcon {
|
|||
pub fn subscription() -> Subscription<Option<&'static str>> {
|
||||
struct NetworkSubscription;
|
||||
|
||||
Subscription::run_with_id(
|
||||
TypeId::of::<NetworkSubscription>(),
|
||||
Subscription::run_with(TypeId::of::<NetworkSubscription>(), |_| {
|
||||
cosmic::iced_futures::stream::channel(16, |mut msg_tx| async move {
|
||||
match handler(&mut msg_tx).await {
|
||||
Ok(()) => {}
|
||||
|
|
@ -52,8 +51,8 @@ pub fn subscription() -> Subscription<Option<&'static str>> {
|
|||
|
||||
//TODO: should we retry on error?
|
||||
futures_util::future::pending().await
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//TODO: use never type?
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ use zbus::{Connection, Result};
|
|||
pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
||||
struct PowerSubscription;
|
||||
|
||||
Subscription::run_with_id(
|
||||
TypeId::of::<PowerSubscription>(),
|
||||
Subscription::run_with(TypeId::of::<PowerSubscription>(), |_| {
|
||||
cosmic::iced_futures::stream::channel(16, |mut msg_tx| async move {
|
||||
match handler(&mut msg_tx).await {
|
||||
Ok(()) => {}
|
||||
|
|
@ -25,8 +24,8 @@ pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
|||
|
||||
//TODO: should we retry on error?
|
||||
futures_util::future::pending().await
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//TODO: use never type?
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use cosmic::iced::{
|
|||
futures::{self, SinkExt},
|
||||
stream,
|
||||
};
|
||||
use cosmic_settings_subscriptions::cosmic_a11y_manager::{
|
||||
use cosmic_settings_a11y_manager_subscription::{
|
||||
self as thread, AccessibilityEvent, AccessibilityRequest,
|
||||
};
|
||||
use std::sync::LazyLock;
|
||||
|
|
@ -24,16 +24,15 @@ pub enum WaylandUpdate {
|
|||
}
|
||||
|
||||
pub fn a11y_subscription() -> iced::Subscription<WaylandUpdate> {
|
||||
Subscription::run_with_id(
|
||||
std::any::TypeId::of::<WaylandUpdate>(),
|
||||
Subscription::run_with(std::any::TypeId::of::<WaylandUpdate>(), |_| {
|
||||
stream::channel(50, move |mut output| async move {
|
||||
let mut state = State::Waiting;
|
||||
|
||||
loop {
|
||||
state = start_listening(state, &mut output).await;
|
||||
}
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_listening(
|
||||
|
|
@ -42,7 +41,8 @@ async fn start_listening(
|
|||
) -> State {
|
||||
match state {
|
||||
State::Waiting => {
|
||||
let mut guard = WAYLAND_RX.lock().await;
|
||||
let mut guard: tokio::sync::MutexGuard<'_, Option<tokio::sync::mpsc::Receiver<_>>> =
|
||||
WAYLAND_RX.lock().await;
|
||||
let rx = {
|
||||
if guard.is_none() {
|
||||
if let Ok(WaylandWatcher { rx, tx }) = WaylandWatcher::new() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue