Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/windowing/winit/linux/zbus/network_status.rs
StratoSDK / crates / strato-ui-renderer / src / windowing / winit / linux / zbus / network_status.rs
1use futures_lite::StreamExt;
2use winit::event_loop::EventLoopProxy;
3use zbus::proxy;
4 
5use crate::{r#async::executor::Background, windowing::winit::app::CustomEvent};
6 
7/// A zbus proxy for receiving network status signals from `NetworkManager`.
8#[proxy(
9 interface = "org.freedesktop.NetworkManager",
10 default_service = "org.freedesktop.NetworkManager",
11 default_path = "/org/freedesktop/NetworkManager",
12 gen_blocking = false
13)]
14trait NetworkManager {
15 #[zbus(signal)]
16 fn state_changed(&self, state: u32) -> zbus::Result<()>;
17}
18 
19/// Sets up a background task to listen to changes to network status.
20pub fn watch_network_status_changed(
21 event_proxy: EventLoopProxy<CustomEvent>,
22 background: &Background,
23) {
24 background
25 .spawn(async move {
26 if let Err(err) = watch_network_status_changed_internal(event_proxy).await {
27 log::warn!("Encountered error while watching for network status events: {err:#}");
28 }
29 })
30 .detach();
31}
32 
33async fn watch_network_status_changed_internal(
34 event_proxy: EventLoopProxy<CustomEvent>,
35) -> zbus::Result<()> {
36 let connection = zbus::Connection::system().await?;
37 let network_manager_proxy = NetworkManagerProxy::new(&connection).await?;
38 let mut state_changed_stream = network_manager_proxy.receive_state_changed().await?;
39 while let Some(msg) = state_changed_stream.next().await {
40 if let Ok(args) = msg.args() {
41 // Only consider the internet as connected if it is equivalent to
42 // `NM_STATE_CONNECTED_GLOBAL`, indicating there is "full network connectivity". See
43 // https://developer-old.gnome.org/NetworkManager/stable/nm-dbus-types.html for more
44 // information.
45 if args.state == 70 {
46 let _ = event_proxy.send_event(CustomEvent::InternetConnected);
47 } else {
48 let _ = event_proxy.send_event(CustomEvent::InternetDisconnected);
49 }
50 }
51 }
52 Ok(())
53}
54