refactor(workspaces list): use channel subscription

This commit is contained in:
Ashley Wulber 2023-07-11 15:23:27 -04:00 committed by Jeremy Soller
parent 7249b6af68
commit 322e13c80d
2 changed files with 39 additions and 34 deletions

View file

@ -1,6 +1,10 @@
use crate::wayland::{self, WorkspaceEvent, WorkspaceList};
use calloop::channel::SyncSender;
use futures::{channel::mpsc, StreamExt};
use cosmic::iced::{
self,
futures::{channel::mpsc, SinkExt, StreamExt},
subscription,
};
use std::hash::Hash;
#[derive(Debug, Clone)]
@ -12,42 +16,43 @@ pub enum WorkspacesUpdate {
pub fn workspaces<I: 'static + Hash + Copy + Send + Sync>(
id: I,
) -> cosmic::iced::Subscription<(I, WorkspacesUpdate)> {
use cosmic::iced::subscription;
) -> iced::Subscription<WorkspacesUpdate> {
subscription::channel(id, 50, move |mut output| async move {
let mut state = State::Ready;
subscription::unfold(id, State::Ready, move |state| _workspaces(id, state))
loop {
state = start_listening(state, &mut output).await;
}
})
}
async fn _workspaces<I: Copy>(id: I, mut state: State) -> ((I, WorkspacesUpdate), State) {
loop {
let (update, new_state) = match state {
State::Ready => {
if let Ok(watcher) = WorkspacesWatcher::new() {
(
Some((id, WorkspacesUpdate::Started(watcher.get_sender()))),
State::Waiting(watcher),
)
} else {
(Some((id, WorkspacesUpdate::Errored)), State::Error)
}
}
State::Waiting(mut t) => {
if let Some(w) = t.workspaces().await {
(
Some((id, WorkspacesUpdate::Workspaces(w))),
State::Waiting(t),
)
} else {
(Some((id, WorkspacesUpdate::Errored)), State::Error)
}
}
State::Error => cosmic::iced::futures::future::pending().await,
};
state = new_state;
async fn start_listening(
state: State,
output: &mut futures::channel::mpsc::Sender<WorkspacesUpdate>,
) -> State {
match state {
State::Ready => {
if let Ok(watcher) = WorkspacesWatcher::new() {
_ = output
.send(WorkspacesUpdate::Started(watcher.get_sender()))
.await;
State::Waiting(watcher)
} else {
_ = output.send(WorkspacesUpdate::Errored).await;
if let Some(update) = update {
return (update, state);
State::Error
}
}
State::Waiting(mut t) => {
if let Some(w) = t.workspaces().await {
_ = output.send(WorkspacesUpdate::Workspaces(w)).await;
State::Waiting(t)
} else {
_ = output.send(WorkspacesUpdate::Errored).await;
State::Error
}
}
State::Error => cosmic::iced::futures::future::pending().await,
}
}