i3status_rs/blocks/keyboard_layout/
locale_bus.rs

1use super::*;
2
3pub(super) struct LocaleBus {
4    proxy: LocaleBusInterfaceProxy<'static>,
5    stream1: zbus::proxy::PropertyStream<'static, String>,
6    stream2: zbus::proxy::PropertyStream<'static, String>,
7}
8
9impl LocaleBus {
10    pub(super) async fn new() -> Result<Self> {
11        let conn = new_system_dbus_connection().await?;
12        let proxy = LocaleBusInterfaceProxy::new(&conn)
13            .await
14            .error("Failed to create LocaleBusProxy")?;
15        let layout_updates = proxy.receive_layout_changed().await;
16        let variant_updates = proxy.receive_layout_changed().await;
17        Ok(Self {
18            proxy,
19            stream1: layout_updates,
20            stream2: variant_updates,
21        })
22    }
23}
24
25#[async_trait]
26impl Backend for LocaleBus {
27    async fn get_info(&mut self) -> Result<Info> {
28        // zbus does internal caching
29        let layout = self.proxy.layout().await.error("Failed to get layout")?;
30        let variant = self.proxy.variant().await.error("Failed to get variant")?;
31        Ok(Info {
32            layout,
33            variant: Some(variant),
34        })
35    }
36
37    async fn wait_for_change(&mut self) -> Result<()> {
38        select! {
39            _ = self.stream1.next() => (),
40            _ = self.stream2.next() => (),
41        }
42        Ok(())
43    }
44}
45
46#[zbus::proxy(
47    interface = "org.freedesktop.locale1",
48    default_service = "org.freedesktop.locale1",
49    default_path = "/org/freedesktop/locale1"
50)]
51trait LocaleBusInterface {
52    #[zbus(property, name = "X11Layout")]
53    fn layout(&self) -> zbus::Result<String>;
54
55    #[zbus(property, name = "X11Variant")]
56    fn variant(&self) -> zbus::Result<String>;
57}