refactor: improve and fix subscriptions and async logic
This commit is contained in:
parent
2d2543094e
commit
0600931abf
9 changed files with 290 additions and 269 deletions
107
Cargo.lock
generated
107
Cargo.lock
generated
|
|
@ -141,12 +141,6 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "almost"
|
||||
version = "0.2.0"
|
||||
|
|
@ -728,39 +722,6 @@ version = "1.10.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cached"
|
||||
version = "0.55.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0839c297f8783316fcca9d90344424e968395413f0662a5481f79c6648bbc14"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"cached_proc_macro",
|
||||
"cached_proc_macro_types",
|
||||
"hashbrown 0.14.5",
|
||||
"once_cell",
|
||||
"thiserror 2.0.12",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cached_proc_macro"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673992d934f0711b68ebb3e1b79cdc4be31634b37c98f26867ced0438ca5c603"
|
||||
dependencies = [
|
||||
"darling 0.20.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cached_proc_macro_types"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
|
||||
|
||||
[[package]]
|
||||
name = "calloop"
|
||||
version = "0.13.0"
|
||||
|
|
@ -1061,7 +1022,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-bg-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-bg#b6adf25075383c0e606658a7309919a9b092ee54"
|
||||
source = "git+https://github.com/pop-os/cosmic-bg#d41c8506ed5c44afd51f74bdb56f620e1dec1ffc"
|
||||
dependencies = [
|
||||
"colorgrad",
|
||||
"cosmic-config",
|
||||
|
|
@ -1087,7 +1048,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-comp-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp#29a649541d527021e98090f2ccd486cf21335dab"
|
||||
source = "git+https://github.com/pop-os/cosmic-comp#99bbd10168aed50a24db730cf20eb778e072c5e4"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"input",
|
||||
|
|
@ -1097,7 +1058,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0aa518984ec6bb29c368b879c20b971f04fbc0c7"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0ddde755ee922edcff1a3b11cc00753cb29fe3b0"
|
||||
dependencies = [
|
||||
"atomicwrites",
|
||||
"calloop 0.14.2",
|
||||
|
|
@ -1120,7 +1081,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0aa518984ec6bb29c368b879c20b971f04fbc0c7"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0ddde755ee922edcff1a3b11cc00753cb29fe3b0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
@ -1165,7 +1126,7 @@ dependencies = [
|
|||
"cosmic-dbus-networkmanager",
|
||||
"cosmic-greeter-config",
|
||||
"cosmic-greeter-daemon",
|
||||
"dirs 5.0.1",
|
||||
"dirs 6.0.0",
|
||||
"env_logger",
|
||||
"freedesktop_entry_parser",
|
||||
"futures-util",
|
||||
|
|
@ -1178,7 +1139,7 @@ dependencies = [
|
|||
"nix 0.29.0",
|
||||
"pam-client",
|
||||
"pwd",
|
||||
"ron 0.8.1",
|
||||
"ron 0.10.1",
|
||||
"rust-embed",
|
||||
"shlex",
|
||||
"tokio",
|
||||
|
|
@ -1212,7 +1173,7 @@ dependencies = [
|
|||
"log",
|
||||
"nix 0.29.0",
|
||||
"pwd",
|
||||
"ron 0.8.1",
|
||||
"ron 0.10.1",
|
||||
"serde",
|
||||
"tokio",
|
||||
"zbus 4.4.0",
|
||||
|
|
@ -1738,7 +1699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2017,16 +1978,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "freedesktop-desktop-entry"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e5e2bd2e383df08a8439c2e096be16d5355aa00f976b295cf8e077ea5953d5d"
|
||||
checksum = "2258b98a780699da05c858682498ceaf3942013d7d93ca7584e26fbacc58f2d9"
|
||||
dependencies = [
|
||||
"cached",
|
||||
"gettext-rs",
|
||||
"log",
|
||||
"memchr",
|
||||
"strsim 0.11.1",
|
||||
"thiserror 2.0.12",
|
||||
"unicase",
|
||||
"xdg",
|
||||
]
|
||||
|
||||
|
|
@ -2386,10 +2346,6 @@ name = "hashbrown"
|
|||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
|
|
@ -2580,7 +2536,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0aa518984ec6bb29c368b879c20b971f04fbc0c7"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0ddde755ee922edcff1a3b11cc00753cb29fe3b0"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bytes",
|
||||
|
|
@ -2604,7 +2560,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0aa518984ec6bb29c368b879c20b971f04fbc0c7"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0ddde755ee922edcff1a3b11cc00753cb29fe3b0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_core",
|
||||
|
|
@ -3049,7 +3005,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
|||
dependencies = [
|
||||
"hermit-abi 0.5.0",
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3258,7 +3214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3696,7 +3652,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||
dependencies = [
|
||||
"proc-macro-crate 3.3.0",
|
||||
"proc-macro-crate 1.3.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
|
|
@ -4648,6 +4604,19 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.9.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.20.0"
|
||||
|
|
@ -4742,7 +4711,7 @@ dependencies = [
|
|||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4755,7 +4724,7 @@ dependencies = [
|
|||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.9.3",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5220,7 +5189,7 @@ dependencies = [
|
|||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"rustix 1.0.3",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5371,9 +5340,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.44.1"
|
||||
version = "1.44.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
|
||||
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
@ -5554,6 +5523,12 @@ dependencies = [
|
|||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.18"
|
||||
|
|
@ -6106,7 +6081,7 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ cosmic-comp-config.workspace = true
|
|||
cosmic-config = { workspace = true, features = ["calloop", "macro"] }
|
||||
cosmic-greeter-config.workspace = true
|
||||
cosmic-greeter-daemon = { path = "daemon" }
|
||||
dirs = "5"
|
||||
dirs = "6"
|
||||
env_logger.workspace = true
|
||||
freedesktop_entry_parser = "1.3.0"
|
||||
libcosmic = { workspace = true, features = [
|
||||
|
|
@ -34,7 +34,7 @@ xkb-data = "0.2"
|
|||
xdg = "2.5.2"
|
||||
#TODO: reduce features
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
wayland-client = "0.31.5"
|
||||
wayland-client = "0.31.8"
|
||||
# For network status using networkmanager feature
|
||||
cosmic-dbus-networkmanager = { git = "https://github.com/pop-os/dbus-settings-bindings", rev = "badfc6a", optional = true }
|
||||
# For logind integration using logind feature
|
||||
|
|
@ -81,7 +81,7 @@ members = ["cosmic-greeter-config", "daemon"]
|
|||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
rust-version = "1.79.0"
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
env_logger = "0.10.2"
|
||||
|
|
@ -89,7 +89,7 @@ log = "0.4.22"
|
|||
# Fix zbus compilation by manually adding nix with user feature
|
||||
nix = { version = "0.29", features = ["user"] }
|
||||
pwd = "1.4.0"
|
||||
ron = "0.8"
|
||||
ron = "0.10.1"
|
||||
serde = "1"
|
||||
tokio = "1.39.1"
|
||||
zbus = "4"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ where
|
|||
Ok(handler) => {
|
||||
let config = C::get_entry(&handler)
|
||||
.inspect_err(|(errors, _)| {
|
||||
for err in errors {
|
||||
for err in errors.iter().filter(|err| err.is_err()) {
|
||||
log::error!("{err}")
|
||||
}
|
||||
})
|
||||
|
|
|
|||
120
src/greeter.rs
120
src/greeter.rs
|
|
@ -6,37 +6,37 @@ mod ipc;
|
|||
use cosmic::app::{Core, Settings, Task};
|
||||
use cosmic::cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity;
|
||||
use cosmic::iced::{Point, Size};
|
||||
use cosmic::iced_core::{image, window};
|
||||
use cosmic::iced_core::image;
|
||||
use cosmic::iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings;
|
||||
use cosmic::surface;
|
||||
use cosmic::widget::text;
|
||||
use cosmic::{
|
||||
Element,
|
||||
cosmic_config::{self, ConfigSet, CosmicConfigEntry},
|
||||
executor,
|
||||
iced::{
|
||||
self, alignment,
|
||||
self, Background, Border, Length, Subscription, alignment,
|
||||
event::{
|
||||
self,
|
||||
wayland::{Event as WaylandEvent, LayerEvent, OutputEvent},
|
||||
wayland::{Event as WaylandEvent, OutputEvent},
|
||||
},
|
||||
futures::SinkExt,
|
||||
platform_specific::{
|
||||
runtime::wayland::layer_surface::{IcedMargin, IcedOutput, SctkLayerSurfaceSettings},
|
||||
shell::wayland::commands::layer_surface::{
|
||||
destroy_layer_surface, get_layer_surface, Anchor, KeyboardInteractivity, Layer,
|
||||
Anchor, KeyboardInteractivity, Layer, destroy_layer_surface, get_layer_surface,
|
||||
},
|
||||
},
|
||||
Background, Border, Length, Subscription,
|
||||
},
|
||||
iced_runtime::core::window::Id as SurfaceId,
|
||||
style, theme, widget, Element,
|
||||
style, theme, widget,
|
||||
};
|
||||
use cosmic_comp_config::CosmicCompConfig;
|
||||
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
||||
use cosmic_greeter_daemon::{UserData, WallpaperData};
|
||||
use greetd_ipc::Request;
|
||||
use std::{
|
||||
collections::{hash_map, HashMap},
|
||||
collections::{HashMap, hash_map},
|
||||
error::Error,
|
||||
fs, io,
|
||||
num::NonZeroU32,
|
||||
|
|
@ -46,8 +46,8 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::time;
|
||||
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
|
||||
use zbus::{proxy, Connection};
|
||||
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||
use zbus::{Connection, proxy};
|
||||
|
||||
use crate::fl;
|
||||
|
||||
|
|
@ -407,7 +407,6 @@ pub enum Message {
|
|||
KeyboardLayout(usize),
|
||||
Login,
|
||||
NetworkIcon(Option<&'static str>),
|
||||
None,
|
||||
OutputEvent(OutputEvent, WlOutput),
|
||||
PowerInfo(Option<(String, f64)>),
|
||||
Prompt(String, bool, Option<String>),
|
||||
|
|
@ -444,10 +443,11 @@ pub struct App {
|
|||
dialog_page_opt: Option<DialogPage>,
|
||||
dropdown_opt: Option<Dropdown>,
|
||||
window_size: HashMap<SurfaceId, Size>,
|
||||
heartbeat_handle: Option<cosmic::iced::task::Handle>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn menu<'a>(&'a self, id: SurfaceId) -> Element<'a, Message> {
|
||||
fn menu(&self, id: SurfaceId) -> Element<Message> {
|
||||
let left_element = {
|
||||
let date_time_column = {
|
||||
let mut column = widget::column::with_capacity(2).padding(16.0).spacing(12.0);
|
||||
|
|
@ -666,7 +666,7 @@ impl App {
|
|||
}
|
||||
SocketState::Open => {
|
||||
for user_data in &self.flags.user_datas {
|
||||
if &user_data.name == &self.selected_username.username {
|
||||
if user_data.name == self.selected_username.username {
|
||||
match &user_data.icon_opt {
|
||||
Some(icon) => {
|
||||
column = column.push(
|
||||
|
|
@ -832,16 +832,13 @@ impl App {
|
|||
}
|
||||
}
|
||||
/// Send a [`Request`] to the greetd IPC subscription.
|
||||
fn send_request(&self, request: Request) -> Task<Message> {
|
||||
fn send_request(&self, request: Request) {
|
||||
if let Some(ref sender) = self.greetd_sender {
|
||||
let sender = sender.clone();
|
||||
return cosmic::task::future(async move {
|
||||
tokio::task::spawn(async move {
|
||||
_ = sender.send(request).await;
|
||||
cosmic::action::none()
|
||||
});
|
||||
}
|
||||
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn set_xkb_config(&self) {
|
||||
|
|
@ -1073,6 +1070,7 @@ impl cosmic::Application for App {
|
|||
dialog_page_opt: None,
|
||||
dropdown_opt: None,
|
||||
window_size: HashMap::new(),
|
||||
heartbeat_handle: None,
|
||||
};
|
||||
(app, Task::none())
|
||||
}
|
||||
|
|
@ -1080,7 +1078,6 @@ impl cosmic::Application for App {
|
|||
/// Handle application events here.
|
||||
fn update(&mut self, message: Self::Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::None => {}
|
||||
Message::OutputEvent(output_event, output) => {
|
||||
match output_event {
|
||||
OutputEvent::Created(output_info_opt) => {
|
||||
|
|
@ -1213,7 +1210,7 @@ impl cosmic::Application for App {
|
|||
match &self.socket_state {
|
||||
SocketState::Open => {
|
||||
// When socket is opened, send create session
|
||||
return self.send_request(Request::CreateSession {
|
||||
self.send_request(Request::CreateSession {
|
||||
username: self.selected_username.username.clone(),
|
||||
});
|
||||
}
|
||||
|
|
@ -1278,7 +1275,7 @@ impl cosmic::Application for App {
|
|||
match &self.socket_state {
|
||||
SocketState::Open => {
|
||||
self.prompt_opt = None;
|
||||
return self.send_request(Request::CancelSession);
|
||||
self.send_request(Request::CancelSession);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -1351,55 +1348,56 @@ impl cosmic::Application for App {
|
|||
Message::Auth(response) => {
|
||||
self.prompt_opt = None;
|
||||
self.error_opt = None;
|
||||
return self.send_request(Request::PostAuthMessageResponse { response });
|
||||
self.send_request(Request::PostAuthMessageResponse { response });
|
||||
}
|
||||
Message::Login => {
|
||||
self.prompt_opt = None;
|
||||
self.error_opt = None;
|
||||
match self.flags.sessions.get(&self.selected_session).cloned() {
|
||||
Some((cmd, env)) => {
|
||||
return Task::batch([
|
||||
self.update(Message::ConfigUpdateUser),
|
||||
self.send_request(Request::StartSession { cmd, env }),
|
||||
]);
|
||||
self.send_request(Request::StartSession { cmd, env });
|
||||
return self.update(Message::ConfigUpdateUser);
|
||||
}
|
||||
None => todo!("session {:?} not found", self.selected_session),
|
||||
}
|
||||
}
|
||||
Message::Error(error) => {
|
||||
self.error_opt = Some(error);
|
||||
return self.send_request(Request::CancelSession);
|
||||
self.send_request(Request::CancelSession);
|
||||
}
|
||||
Message::Reconnect => {
|
||||
return self.update_user_config();
|
||||
}
|
||||
Message::DialogCancel => {
|
||||
self.dialog_page_opt = None;
|
||||
if let Some(handle) = self.heartbeat_handle.take() {
|
||||
handle.abort();
|
||||
}
|
||||
}
|
||||
Message::DialogConfirm => match self.dialog_page_opt.take() {
|
||||
Some(DialogPage::Restart(_)) => {
|
||||
#[cfg(feature = "logind")]
|
||||
return cosmic::task::future(async move {
|
||||
return cosmic::task::future::<(), ()>(async move {
|
||||
match crate::logind::reboot().await {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
log::error!("failed to reboot: {:?}", err);
|
||||
}
|
||||
}
|
||||
cosmic::action::none()
|
||||
});
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
Some(DialogPage::Shutdown(_)) => {
|
||||
#[cfg(feature = "logind")]
|
||||
return cosmic::task::future(async move {
|
||||
return cosmic::task::future::<(), ()>(async move {
|
||||
match crate::logind::power_off().await {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
log::error!("failed to power off: {:?}", err);
|
||||
}
|
||||
}
|
||||
cosmic::action::none()
|
||||
});
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
|
|
@ -1421,21 +1419,46 @@ impl cosmic::Application for App {
|
|||
}
|
||||
Message::Suspend => {
|
||||
#[cfg(feature = "logind")]
|
||||
return cosmic::task::future(async move {
|
||||
return cosmic::task::future::<(), ()>(async move {
|
||||
match crate::logind::suspend().await {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
log::error!("failed to suspend: {:?}", err);
|
||||
}
|
||||
}
|
||||
cosmic::action::none()
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
Message::Restart | Message::Shutdown => {
|
||||
let instant = Instant::now();
|
||||
|
||||
self.dialog_page_opt = Some(if matches!(message, Message::Restart) {
|
||||
DialogPage::Restart(instant)
|
||||
} else {
|
||||
DialogPage::Shutdown(instant)
|
||||
});
|
||||
|
||||
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));
|
||||
|
||||
loop {
|
||||
// Send heartbeat once a second to update time
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Heartbeat))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
Message::Restart => {
|
||||
self.dialog_page_opt = Some(DialogPage::Restart(Instant::now()));
|
||||
}),
|
||||
)
|
||||
.abortable();
|
||||
|
||||
self.heartbeat_handle = Some(handle);
|
||||
return heartbeat;
|
||||
}
|
||||
Message::Shutdown => {
|
||||
self.dialog_page_opt = Some(DialogPage::Shutdown(Instant::now()));
|
||||
}
|
||||
Message::Heartbeat => match self.dialog_page_opt {
|
||||
Some(DialogPage::Restart(instant)) | Some(DialogPage::Shutdown(instant)) => {
|
||||
|
|
@ -1500,8 +1523,6 @@ impl cosmic::Application for App {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
struct HeartbeatSubscription;
|
||||
|
||||
let mut subscriptions = vec![
|
||||
event::listen_with(|event, _, id| match event {
|
||||
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(
|
||||
|
|
@ -1516,32 +1537,17 @@ impl cosmic::Application for App {
|
|||
iced::Event::Window(iced::window::Event::Focused) => Some(Message::Focus(id)),
|
||||
_ => None,
|
||||
}),
|
||||
Subscription::run_with_id(
|
||||
std::any::TypeId::of::<HeartbeatSubscription>(),
|
||||
cosmic::iced_futures::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::Heartbeat).await.unwrap();
|
||||
time::sleep(time::Duration::new(1, 0)).await;
|
||||
}
|
||||
}),
|
||||
),
|
||||
ipc::subscription(),
|
||||
];
|
||||
|
||||
#[cfg(feature = "networkmanager")]
|
||||
{
|
||||
subscriptions.push(
|
||||
crate::networkmanager::subscription()
|
||||
.map(|icon_opt| Message::NetworkIcon(icon_opt)),
|
||||
);
|
||||
subscriptions.push(crate::networkmanager::subscription().map(Message::NetworkIcon));
|
||||
}
|
||||
|
||||
#[cfg(feature = "upower")]
|
||||
{
|
||||
subscriptions
|
||||
.push(crate::upower::subscription().map(|info_opt| Message::PowerInfo(info_opt)));
|
||||
subscriptions.push(crate::upower::subscription().map(Message::PowerInfo));
|
||||
}
|
||||
|
||||
Subscription::batch(subscriptions)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use cosmic::iced::Subscription;
|
|||
use futures_util::SinkExt;
|
||||
use greetd_ipc::codec::TokioCodec;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::net::UnixStream;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
|
|
@ -20,12 +21,15 @@ pub fn subscription() -> Subscription<Message> {
|
|||
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));
|
||||
|
||||
loop {
|
||||
_ = sender.send(Message::Reconnect).await;
|
||||
|
||||
let mut stream = match UnixStream::connect(&socket_path).await {
|
||||
Ok(stream) => stream,
|
||||
Err(why) => {
|
||||
log::error!("greetd IPC socket connection failed: {why:?}");
|
||||
_ = sender.send(Message::Socket(SocketState::Error(Arc::new(why))));
|
||||
|
||||
break;
|
||||
|
|
@ -36,7 +40,7 @@ pub fn subscription() -> Subscription<Message> {
|
|||
|
||||
while let Some(request) = rx.recv().await {
|
||||
if let Err(why) = request.write_to(&mut stream).await {
|
||||
log::error!("error writing to GREETD_SOCK stream: {why}");
|
||||
log::error!("error writing to GREETD_SOCK stream: {why:?}");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -85,8 +89,9 @@ pub fn subscription() -> Subscription<Message> {
|
|||
"error while cancelling session: {}",
|
||||
description
|
||||
);
|
||||
|
||||
// Reconnect to socket
|
||||
_ = break
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
_ = sender.send(Message::Error(description)).await;
|
||||
|
|
@ -107,6 +112,7 @@ pub fn subscription() -> Subscription<Message> {
|
|||
_ = sender.send(Message::Exit).await;
|
||||
}
|
||||
greetd_ipc::Request::CancelSession => {
|
||||
log::info!("greetd IPC session canceled");
|
||||
// Reconnect to socket
|
||||
break;
|
||||
}
|
||||
|
|
@ -119,6 +125,9 @@ pub fn subscription() -> Subscription<Message> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("reconnecting to greetd IPC socket");
|
||||
interval.tick().await;
|
||||
}
|
||||
|
||||
futures_util::future::pending().await
|
||||
|
|
|
|||
224
src/locker.rs
224
src/locker.rs
|
|
@ -7,9 +7,9 @@ use cosmic::iced::{Point, Rectangle, Size};
|
|||
use cosmic::iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings;
|
||||
use cosmic::surface;
|
||||
use cosmic::{
|
||||
executor,
|
||||
Element, executor,
|
||||
iced::{
|
||||
self, alignment,
|
||||
self, Length, Subscription, alignment,
|
||||
event::{
|
||||
self,
|
||||
wayland::{Event as WaylandEvent, OutputEvent, SessionLockEvent},
|
||||
|
|
@ -18,12 +18,12 @@ use cosmic::{
|
|||
platform_specific::shell::wayland::commands::session_lock::{
|
||||
destroy_lock_surface, get_lock_surface, lock, unlock,
|
||||
},
|
||||
Length, Subscription,
|
||||
},
|
||||
iced_runtime::core::window::Id as SurfaceId,
|
||||
style, widget, Element,
|
||||
style, widget,
|
||||
};
|
||||
use cosmic_config::CosmicConfigEntry;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
any::TypeId,
|
||||
collections::HashMap,
|
||||
|
|
@ -35,8 +35,8 @@ use std::{
|
|||
process,
|
||||
sync::Arc,
|
||||
};
|
||||
use tokio::{sync::mpsc, task, time};
|
||||
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
|
||||
use tokio::{sync::mpsc, task};
|
||||
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||
|
||||
fn lockfile_opt() -> Option<PathBuf> {
|
||||
let runtime_dir = dirs::runtime_dir()?;
|
||||
|
|
@ -113,7 +113,7 @@ pub fn pam_thread(username: String, conversation: Conversation) -> Result<(), pa
|
|||
}
|
||||
|
||||
pub struct Conversation {
|
||||
msg_tx: futures::channel::mpsc::Sender<Message>,
|
||||
msg_tx: futures::channel::mpsc::Sender<cosmic::Action<Message>>,
|
||||
value_rx: mpsc::Receiver<String>,
|
||||
}
|
||||
|
||||
|
|
@ -127,18 +127,14 @@ impl Conversation {
|
|||
log::error!("failed to convert prompt to UTF-8: {:?}", err);
|
||||
pam_client::ErrorCode::CONV_ERR
|
||||
})?;
|
||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
runtime
|
||||
.block_on(async {
|
||||
|
||||
futures::executor::block_on(async {
|
||||
self.msg_tx
|
||||
.send(Message::Prompt(
|
||||
.send(cosmic::Action::App(Message::Prompt(
|
||||
prompt.to_string(),
|
||||
secret,
|
||||
Some(String::new()),
|
||||
))
|
||||
)))
|
||||
.await
|
||||
})
|
||||
.map_err(|err| {
|
||||
|
|
@ -165,7 +161,11 @@ impl Conversation {
|
|||
|
||||
futures::executor::block_on(async {
|
||||
self.msg_tx
|
||||
.send(Message::Prompt(prompt.to_string(), false, None))
|
||||
.send(cosmic::Action::App(Message::Prompt(
|
||||
prompt.to_string(),
|
||||
false,
|
||||
None,
|
||||
)))
|
||||
.await
|
||||
})
|
||||
.map_err(|err| {
|
||||
|
|
@ -238,11 +238,23 @@ pub enum Message {
|
|||
#[derive(Clone, Debug)]
|
||||
enum State {
|
||||
Locking,
|
||||
Locked,
|
||||
Locked {
|
||||
task_handle: cosmic::iced::task::Handle,
|
||||
},
|
||||
Unlocking,
|
||||
Unlocked,
|
||||
}
|
||||
|
||||
impl Drop for State {
|
||||
fn drop(&mut self) {
|
||||
// Abort the locked task when the state is changed.
|
||||
if let Self::Locked { task_handle } = self {
|
||||
log::info!("dropping lockscreen tasks");
|
||||
task_handle.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`App`] stores application-specific state.
|
||||
pub struct App {
|
||||
core: Core,
|
||||
|
|
@ -264,7 +276,7 @@ pub struct App {
|
|||
}
|
||||
|
||||
impl App {
|
||||
fn menu<'a>(&'a self, surface_id: SurfaceId) -> Element<'a, Message> {
|
||||
fn menu(&self, surface_id: SurfaceId) -> Element<Message> {
|
||||
let left_element = {
|
||||
let date_time_column = {
|
||||
let mut column = widget::column::with_capacity(2).padding(16.0);
|
||||
|
|
@ -389,7 +401,7 @@ impl App {
|
|||
)
|
||||
.id(text_input_id)
|
||||
.manage_value(true)
|
||||
.on_submit(|v| Message::Submit(v));
|
||||
.on_submit(Message::Submit);
|
||||
|
||||
if *secret {
|
||||
text_input = text_input.password()
|
||||
|
|
@ -577,8 +589,9 @@ impl cosmic::Application for App {
|
|||
let surface_id = SurfaceId::unique();
|
||||
let subsurface_id = SurfaceId::unique();
|
||||
|
||||
match self.surface_ids.insert(output.clone(), surface_id) {
|
||||
Some(old_surface_id) => {
|
||||
if let Some(old_surface_id) =
|
||||
self.surface_ids.insert(output.clone(), surface_id)
|
||||
{
|
||||
//TODO: remove old surface?
|
||||
log::warn!(
|
||||
"output {}: already had surface ID {:?}",
|
||||
|
|
@ -587,8 +600,7 @@ impl cosmic::Application for App {
|
|||
);
|
||||
return Task::none();
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let size = if let Some((w, h)) =
|
||||
output_info_opt.as_ref().and_then(|info| info.logical_size)
|
||||
{
|
||||
|
|
@ -654,7 +666,7 @@ impl cosmic::Application for App {
|
|||
})),
|
||||
);
|
||||
|
||||
if matches!(self.state, State::Locked) {
|
||||
if matches!(self.state, State::Locked { .. }) {
|
||||
return Task::batch([
|
||||
get_lock_surface(surface_id, output),
|
||||
cosmic::task::message(cosmic::Action::Cosmic(
|
||||
|
|
@ -672,7 +684,7 @@ impl cosmic::Application for App {
|
|||
if let Some(n) = self.surface_names.remove(&surface_id) {
|
||||
self.text_input_ids.remove(&n);
|
||||
}
|
||||
if matches!(self.state, State::Locked) {
|
||||
if matches!(self.state, State::Locked { .. }) {
|
||||
return destroy_lock_surface(surface_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -709,15 +721,89 @@ impl cosmic::Application for App {
|
|||
SessionLockEvent::Focused(..) => {}
|
||||
SessionLockEvent::Locked => {
|
||||
log::info!("session locked");
|
||||
if matches!(self.state, State::Locked) {
|
||||
if matches!(self.state, State::Locked { .. }) {
|
||||
return Task::none();
|
||||
}
|
||||
self.state = State::Locked;
|
||||
|
||||
let username = self.flags.current_user.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));
|
||||
|
||||
loop {
|
||||
output
|
||||
.send(cosmic::Action::App(Message::None))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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(()) => {
|
||||
log::info!("successfully authenticated");
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Unlock))
|
||||
.await
|
||||
.unwrap();
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("authentication error: {}", err);
|
||||
msg_tx
|
||||
.send(cosmic::Action::App(Message::Error(
|
||||
err.to_string(),
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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.surface_ids.len() + 1);
|
||||
commands.push(locked_task);
|
||||
|
||||
self.state = State::Locked {
|
||||
task_handle: locked_handle,
|
||||
};
|
||||
|
||||
// Allow suspend
|
||||
self.inhibit_opt = None;
|
||||
// Create lock surfaces
|
||||
|
||||
let mut commands = Vec::with_capacity(self.surface_ids.len());
|
||||
for (output, surface_id) in self.surface_ids.iter() {
|
||||
commands.push(get_lock_surface(*surface_id, output.clone()));
|
||||
|
||||
|
|
@ -836,14 +922,10 @@ impl cosmic::Application for App {
|
|||
},
|
||||
Message::Suspend => {
|
||||
#[cfg(feature = "logind")]
|
||||
return cosmic::task::future(async move {
|
||||
match crate::logind::suspend().await {
|
||||
Ok(()) => cosmic::action::none(),
|
||||
Err(err) => {
|
||||
return cosmic::Task::future(async move { crate::logind::suspend().await.err() })
|
||||
.and_then(|err| {
|
||||
log::error!("failed to suspend: {:?}", err);
|
||||
cosmic::Action::App(Message::Error(err.to_string()))
|
||||
}
|
||||
}
|
||||
cosmic::task::message(cosmic::Action::App(Message::Error(err.to_string())))
|
||||
});
|
||||
}
|
||||
Message::Error(error) => {
|
||||
|
|
@ -869,13 +951,13 @@ impl cosmic::Application for App {
|
|||
State::Unlocking => {
|
||||
log::info!("session still unlocking");
|
||||
}
|
||||
State::Locking | State::Locked => {
|
||||
State::Locking | State::Locked { .. } => {
|
||||
log::info!("session already locking or locked");
|
||||
}
|
||||
},
|
||||
Message::Unlock => {
|
||||
match self.state {
|
||||
State::Locked => {
|
||||
State::Locked { .. } => {
|
||||
log::info!("sessing unlocking");
|
||||
self.state = State::Unlocking;
|
||||
// Clear errors
|
||||
|
|
@ -891,6 +973,12 @@ impl cosmic::Application for App {
|
|||
|
||||
// Destroy lock surfaces
|
||||
let mut commands = Vec::with_capacity(self.surface_ids.len() + 1);
|
||||
|
||||
for (_output, surface_id) in self.surface_ids.iter() {
|
||||
self.surface_names.remove(surface_id);
|
||||
commands.push(destroy_lock_surface(*surface_id));
|
||||
}
|
||||
|
||||
// Tell compositor to unlock
|
||||
commands.push(unlock());
|
||||
|
||||
|
|
@ -964,60 +1052,6 @@ impl cosmic::Application for App {
|
|||
}),
|
||||
);
|
||||
|
||||
if matches!(self.state, State::Locked) {
|
||||
struct HeartbeatSubscription;
|
||||
subscriptions.push(Subscription::run_with_id(
|
||||
TypeId::of::<HeartbeatSubscription>(),
|
||||
cosmic::iced_futures::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::run_with_id(
|
||||
TypeId::of::<PamSubscription>(),
|
||||
cosmic::iced_futures::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();
|
||||
|
||||
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(()) => {
|
||||
log::info!("successfully authenticated");
|
||||
msg_tx.send(Message::Unlock).await.unwrap();
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("authentication error: {}", err);
|
||||
msg_tx.send(Message::Error(err.to_string())).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
time::sleep(time::Duration::new(60, 0)).await;
|
||||
}
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(feature = "logind")]
|
||||
{
|
||||
subscriptions.push(crate::logind::subscription());
|
||||
|
|
@ -1025,16 +1059,12 @@ impl cosmic::Application for App {
|
|||
|
||||
#[cfg(feature = "networkmanager")]
|
||||
{
|
||||
subscriptions.push(
|
||||
crate::networkmanager::subscription()
|
||||
.map(|icon_opt| Message::NetworkIcon(icon_opt)),
|
||||
);
|
||||
subscriptions.push(crate::networkmanager::subscription().map(Message::NetworkIcon));
|
||||
}
|
||||
|
||||
#[cfg(feature = "upower")]
|
||||
{
|
||||
subscriptions
|
||||
.push(crate::upower::subscription().map(|info_opt| Message::PowerInfo(info_opt)));
|
||||
subscriptions.push(crate::upower::subscription().map(Message::PowerInfo));
|
||||
}
|
||||
|
||||
Subscription::batch(subscriptions)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use cosmic::iced::{
|
||||
futures::{channel::mpsc, SinkExt, StreamExt},
|
||||
Subscription,
|
||||
futures::{SinkExt, StreamExt, channel::mpsc},
|
||||
};
|
||||
use logind_zbus::{
|
||||
manager::{InhibitType, ManagerProxy},
|
||||
session::SessionProxy,
|
||||
};
|
||||
use std::{any::TypeId, error::Error, os::fd::OwnedFd, sync::Arc};
|
||||
use std::{any::TypeId, error::Error, os::fd::OwnedFd, sync::Arc, time::Duration};
|
||||
use zbus::Connection;
|
||||
|
||||
use crate::locker::Message;
|
||||
|
|
@ -78,6 +78,9 @@ pub async fn handler(msg_tx: &mut mpsc::Sender<Message>) -> Result<(), Box<dyn E
|
|||
let mut prepare_for_sleep = manager.receive_prepare_for_sleep().await?;
|
||||
let mut lock = session.receive_lock().await?;
|
||||
let mut unlock = session.receive_unlock().await?;
|
||||
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
// Waits until a signal has been received
|
||||
tokio::select!(
|
||||
|
|
@ -114,5 +117,7 @@ pub async fn handler(msg_tx: &mut mpsc::Sender<Message>) -> Result<(), Box<dyn E
|
|||
log::info!("logind unlock");
|
||||
msg_tx.send(Message::Unlock).await?;
|
||||
});
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use cosmic::iced::{
|
||||
futures::{channel::mpsc, SinkExt, StreamExt},
|
||||
Subscription,
|
||||
futures::{SinkExt, StreamExt, channel::mpsc},
|
||||
};
|
||||
use cosmic_dbus_networkmanager::{device::SpecificDevice, nm::NetworkManager};
|
||||
use std::{any::TypeId, cmp};
|
||||
use tokio::time;
|
||||
use std::{any::TypeId, cmp, time::Duration};
|
||||
use zbus::{Connection, Result};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
|
@ -52,9 +51,7 @@ pub fn subscription() -> Subscription<Option<&'static str>> {
|
|||
msg_tx.send(None).await.unwrap();
|
||||
|
||||
//TODO: should we retry on error?
|
||||
loop {
|
||||
time::sleep(time::Duration::new(60, 0)).await;
|
||||
}
|
||||
futures_util::future::pending().await
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
@ -63,8 +60,9 @@ pub fn subscription() -> Subscription<Option<&'static str>> {
|
|||
pub async fn handler(msg_tx: &mut mpsc::Sender<Option<&'static str>>) -> Result<()> {
|
||||
let zbus = Connection::system().await?;
|
||||
let nm = NetworkManager::new(&zbus).await?;
|
||||
|
||||
let mut active_conns_changed = nm.receive_active_connections_changed().await;
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
let mut icon = NetworkIcon::None;
|
||||
|
||||
|
|
@ -100,9 +98,7 @@ pub async fn handler(msg_tx: &mut mpsc::Sender<Option<&'static str>>) -> Result<
|
|||
msg_tx.send(Some(icon.name())).await.unwrap();
|
||||
|
||||
// Waits until active connections have changed and at least one second has passed
|
||||
tokio::join!(
|
||||
active_conns_changed.next(),
|
||||
time::sleep(time::Duration::from_secs(1))
|
||||
);
|
||||
active_conns_changed.next().await;
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use cosmic::iced::{
|
||||
futures::{channel::mpsc, SinkExt, StreamExt},
|
||||
Subscription,
|
||||
futures::{SinkExt, StreamExt, channel::mpsc},
|
||||
};
|
||||
use std::any::TypeId;
|
||||
use tokio::time;
|
||||
use std::{any::TypeId, time::Duration};
|
||||
use upower_dbus::UPowerProxy;
|
||||
use zbus::{Connection, Result};
|
||||
|
||||
|
|
@ -25,9 +24,7 @@ pub fn subscription() -> Subscription<Option<(String, f64)>> {
|
|||
msg_tx.send(None).await.unwrap();
|
||||
|
||||
//TODO: should we retry on error?
|
||||
loop {
|
||||
time::sleep(time::Duration::new(60, 0)).await;
|
||||
}
|
||||
futures_util::future::pending().await
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
@ -40,6 +37,8 @@ pub async fn handler(msg_tx: &mut mpsc::Sender<Option<(String, f64)>>) -> Result
|
|||
|
||||
let mut icon_name_changed = dev.receive_icon_name_changed().await;
|
||||
let mut percentage_changed = dev.receive_percentage_changed().await;
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
let mut info_opt = None;
|
||||
|
||||
|
|
@ -53,7 +52,8 @@ pub async fn handler(msg_tx: &mut mpsc::Sender<Option<(String, f64)>>) -> Result
|
|||
|
||||
msg_tx.send(info_opt).await.unwrap();
|
||||
|
||||
// Waits until icon or percentage have changed
|
||||
tokio::select!(_ = icon_name_changed.next() => (), _ = percentage_changed.next() => ());
|
||||
// Waits until icon or percentage have changed, and at least one second has passed.
|
||||
futures_util::future::select(icon_name_changed.next(), percentage_changed.next()).await;
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue