// Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only //! # DBus interface proxy for: `org.freedesktop.UPower.KbdBacklight` //! //! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data. //! Source: `Interface '/org/freedesktop/UPower/KbdBacklight' from service 'org.freedesktop.UPower' on system bus`. use cctk::sctk::reexports::calloop; use cctk::toplevel_info::ToplevelInfo; use cosmic::cctk::cosmic_protocols; use cosmic::iced::subscription; use cosmic::iced_futures::futures; use cosmic::{cctk, iced}; use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1; use futures::{ channel::mpsc::{unbounded, UnboundedReceiver}, SinkExt, StreamExt, }; use image::EncodableLayout; use once_cell::sync::Lazy; use std::fmt::Debug; use std::sync::Arc; use tokio::sync::Mutex; use crate::wayland_handler::wayland_handler; pub static WAYLAND_RX: Lazy>>> = Lazy::new(|| Mutex::new(None)); pub fn wayland_subscription() -> iced::Subscription { subscription::channel( std::any::TypeId::of::(), 50, move |mut output| async move { let mut state = State::Waiting; loop { state = start_listening(state, &mut output).await; } }, ) } pub enum State { Waiting, Finished, } async fn start_listening( state: State, output: &mut futures::channel::mpsc::Sender, ) -> State { match state { State::Waiting => { let mut guard = WAYLAND_RX.lock().await; let rx = { if guard.is_none() { let (calloop_tx, calloop_rx) = calloop::channel::channel(); let (toplevel_tx, toplevel_rx) = unbounded(); let _ = std::thread::spawn(move || { wayland_handler(toplevel_tx, calloop_rx); }); *guard = Some(toplevel_rx); _ = output.send(WaylandUpdate::Init(calloop_tx)).await; } guard.as_mut().unwrap() }; match rx.next().await { Some(u) => { _ = output.send(u).await; State::Waiting } None => { _ = output.send(WaylandUpdate::Finished).await; tracing::error!("Wayland handler thread died"); State::Finished } } } State::Finished => iced::futures::future::pending().await, } } #[derive(Clone, Debug)] pub enum WaylandUpdate { Init(calloop::channel::Sender), Finished, Toplevel(ToplevelUpdate), Image(ZcosmicToplevelHandleV1, WaylandImage), } #[derive(Debug, Clone)] pub struct WaylandImage { pub img: Arc, } impl WaylandImage { pub fn new(img: image::RgbaImage) -> Self { Self { img: Arc::new(img) } } } impl AsRef<[u8]> for WaylandImage { fn as_ref(&self) -> &[u8] { self.img.as_bytes() } } #[derive(Clone, Debug)] pub enum ToplevelUpdate { Add(ZcosmicToplevelHandleV1, ToplevelInfo), Update(ZcosmicToplevelHandleV1, ToplevelInfo), Remove(ZcosmicToplevelHandleV1), } #[derive(Clone, Debug)] pub enum WaylandRequest { Toplevel(ToplevelRequest), } #[derive(Debug, Clone)] pub enum ToplevelRequest { Activate(ZcosmicToplevelHandleV1), }