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/suspend_resume.rs
StratoSDK / crates / strato-ui-renderer / src / windowing / winit / linux / zbus / suspend_resume.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 PrepareForSleep signals from systemd-logind.
8#[proxy(
9 interface = "org.freedesktop.login1.Manager",
10 default_service = "org.freedesktop.login1",
11 default_path = "/org/freedesktop/login1",
12 gen_blocking = false
13)]
14trait LoginManager {
15 #[zbus(signal)]
16 fn prepare_for_sleep(&self, start: bool) -> zbus::Result<()>;
17}
18 
19/// Sets up a background task to listen to suspend/resume events sent over dbus
20/// and inject events into the winit EventLoop accordingly.
21pub fn watch_suspend_resume_changes(
22 event_proxy: EventLoopProxy<CustomEvent>,
23 background: &Background,
24) {
25 background
26 .spawn(async move {
27 if let Err(err) = watch_suspend_resume_changes_internal(event_proxy).await {
28 log::warn!(
29 "Encountered error while watching for system suspend/resume events: {err:#}"
30 );
31 }
32 })
33 .detach();
34}
35 
36async fn watch_suspend_resume_changes_internal(
37 event_proxy: EventLoopProxy<CustomEvent>,
38) -> zbus::Result<()> {
39 let connection = zbus::Connection::system().await?;
40 let login_manager_proxy = LoginManagerProxy::new(&connection).await?;
41 let mut stream = login_manager_proxy.receive_prepare_for_sleep().await?;
42 while let Some(msg) = stream.next().await {
43 if let Ok(args) = msg.args() {
44 if args.start {
45 let _ = event_proxy.send_event(CustomEvent::AboutToSleep);
46 } else {
47 let _ = event_proxy.send_event(CustomEvent::ResumedFromSleep);
48 }
49 }
50 }
51 Ok(())
52}
53