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

@ -2,7 +2,7 @@ use calloop::channel::SyncSender;
use cosmic::iced::alignment::{Horizontal, Vertical};
use cosmic::iced::mouse::{self, ScrollDelta};
use cosmic::iced::wayland::actions::window::SctkWindowSettings;
use cosmic::iced::wayland::{window::resize_window, InitialSurface};
use cosmic::iced::wayland::InitialSurface;
use cosmic::iced::widget::{column, container, row, text};
use cosmic::iced::Color;
use cosmic::iced::{
@ -181,7 +181,7 @@ impl Application for IcedWorkspacesApplet {
Subscription::batch(
vec![
self.helper.theme_subscription(0).map(Message::Theme),
workspaces(0).map(|e| Message::WorkspaceUpdate(e.1)),
workspaces(0).map(Message::WorkspaceUpdate),
subscription::events_with(|e, _| match e {
Mouse(mouse::Event::WheelScrolled { delta }) => {
Some(Message::WheelScrolled(delta))

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 {
async fn start_listening(
state: State,
output: &mut futures::channel::mpsc::Sender<WorkspacesUpdate>,
) -> State {
match state {
State::Ready => {
if let Ok(watcher) = WorkspacesWatcher::new() {
(
Some((id, WorkspacesUpdate::Started(watcher.get_sender()))),
State::Waiting(watcher),
)
_ = output
.send(WorkspacesUpdate::Started(watcher.get_sender()))
.await;
State::Waiting(watcher)
} else {
(Some((id, WorkspacesUpdate::Errored)), State::Error)
_ = output.send(WorkspacesUpdate::Errored).await;
State::Error
}
}
State::Waiting(mut t) => {
if let Some(w) = t.workspaces().await {
(
Some((id, WorkspacesUpdate::Workspaces(w))),
State::Waiting(t),
)
_ = output.send(WorkspacesUpdate::Workspaces(w)).await;
State::Waiting(t)
} else {
(Some((id, WorkspacesUpdate::Errored)), State::Error)
_ = output.send(WorkspacesUpdate::Errored).await;
State::Error
}
}
State::Error => cosmic::iced::futures::future::pending().await,
};
state = new_state;
if let Some(update) = update {
return (update, state);
}
}
}