blob: 5964d45b3d97eab16f71b6e1a9273003bcf17fa3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
use futures_util::StreamExt;
use zbus::fdo;
use zbus::names::InterfaceName;
pub enum Login1ToNiri {
LidClosedChanged(bool),
}
pub fn start(
to_niri: calloop::channel::Sender<Login1ToNiri>,
) -> anyhow::Result<zbus::blocking::Connection> {
let conn = zbus::blocking::Connection::system()?;
let async_conn = conn.inner().clone();
let future = async move {
let proxy = fdo::PropertiesProxy::new(
&async_conn,
"org.freedesktop.login1",
"/org/freedesktop/login1",
)
.await;
let proxy = match proxy {
Ok(x) => x,
Err(err) => {
warn!("error creating PropertiesProxy: {err:?}");
return;
}
};
let mut props_changed = match proxy.receive_properties_changed().await {
Ok(x) => x,
Err(err) => {
warn!("error subscribing to PropertiesChanged: {err:?}");
return;
}
};
let props = proxy
.get_all(InterfaceName::try_from("org.freedesktop.login1.Manager").unwrap())
.await;
let mut props = match props {
Ok(x) => x,
Err(err) => {
warn!("error receiving initial properties: {err:?}");
return;
}
};
trace!("initial properties: {props:?}");
let mut lid_closed = props
.remove("LidClosed")
.and_then(|value| bool::try_from(value).ok())
.unwrap_or_default();
if let Err(err) = to_niri.send(Login1ToNiri::LidClosedChanged(lid_closed)) {
warn!("error sending initial lid state to niri: {err:?}");
return;
};
while let Some(signal) = props_changed.next().await {
let args = match signal.args() {
Ok(args) => args,
Err(err) => {
warn!("error parsing PropertiesChanged args: {err:?}");
return;
}
};
let mut new_lid_closed = lid_closed;
let mut changed = false;
for (name, value) in args.changed_properties() {
trace!("changed property: {name} => {value:?}");
if *name != "LidClosed" {
continue;
}
new_lid_closed = bool::try_from(value).unwrap_or(new_lid_closed);
changed = true;
}
if !changed {
continue;
}
if new_lid_closed == lid_closed {
continue;
}
lid_closed = new_lid_closed;
if let Err(err) = to_niri.send(Login1ToNiri::LidClosedChanged(lid_closed)) {
warn!("error sending message to niri: {err:?}");
return;
};
}
};
let task = conn
.inner()
.executor()
.spawn(future, "monitor login1 property changes");
task.detach();
Ok(conn)
}
|