fix: make all subscriptions resistant to being restarted
many of the errors we've been seeing the last few days are because of subscriptions which are restarting
This commit is contained in:
parent
ebe688c747
commit
d4e0dd8fb8
12 changed files with 184 additions and 138 deletions
|
|
@ -16,6 +16,7 @@ once_cell = "1.9"
|
|||
futures = "0.3.21"
|
||||
xdg = "2.4.0"
|
||||
anyhow = "1.0"
|
||||
tokio = "1.35"
|
||||
# Application i18n
|
||||
i18n-embed = { version = "0.13.4", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.6.4"
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ impl cosmic::Application for IcedWorkspacesApplet {
|
|||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
Subscription::batch(vec![
|
||||
workspaces(0).map(Message::WorkspaceUpdate),
|
||||
workspaces().map(Message::WorkspaceUpdate),
|
||||
event::listen_with(|e, _| match e {
|
||||
Mouse(mouse::Event::WheelScrolled { delta }) => Some(Message::WheelScrolled(delta)),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ use cosmic::iced::{
|
|||
futures::{channel::mpsc, SinkExt, StreamExt},
|
||||
subscription,
|
||||
};
|
||||
use std::hash::Hash;
|
||||
use once_cell::sync::Lazy;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub static WAYLAND_RX: Lazy<Mutex<Option<mpsc::Receiver<WorkspaceList>>>> =
|
||||
Lazy::new(|| Mutex::new(None));
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WorkspacesUpdate {
|
||||
|
|
@ -14,16 +18,18 @@ pub enum WorkspacesUpdate {
|
|||
Errored,
|
||||
}
|
||||
|
||||
pub fn workspaces<I: 'static + Hash + Copy + Send + Sync>(
|
||||
id: I,
|
||||
) -> iced::Subscription<WorkspacesUpdate> {
|
||||
subscription::channel(id, 50, move |mut output| async move {
|
||||
let mut state = State::Ready;
|
||||
pub fn workspaces() -> iced::Subscription<WorkspacesUpdate> {
|
||||
subscription::channel(
|
||||
std::any::TypeId::of::<WorkspacesUpdate>(),
|
||||
50,
|
||||
move |mut output| async move {
|
||||
let mut state = State::Waiting;
|
||||
|
||||
loop {
|
||||
state = start_listening(state, &mut output).await;
|
||||
}
|
||||
})
|
||||
loop {
|
||||
state = start_listening(state, &mut output).await;
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
async fn start_listening(
|
||||
|
|
@ -31,22 +37,23 @@ async fn start_listening(
|
|||
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;
|
||||
|
||||
State::Error
|
||||
}
|
||||
}
|
||||
State::Waiting(mut t) => {
|
||||
if let Some(w) = t.workspaces().await {
|
||||
State::Waiting => {
|
||||
let mut guard = WAYLAND_RX.lock().await;
|
||||
let rx = {
|
||||
if guard.is_none() {
|
||||
if let Ok(WorkspacesWatcher { rx, tx }) = WorkspacesWatcher::new() {
|
||||
*guard = Some(rx);
|
||||
_ = output.send(WorkspacesUpdate::Started(tx)).await;
|
||||
} else {
|
||||
_ = output.send(WorkspacesUpdate::Errored).await;
|
||||
return State::Error;
|
||||
}
|
||||
}
|
||||
guard.as_mut().unwrap()
|
||||
};
|
||||
if let Some(w) = rx.next().await {
|
||||
_ = output.send(WorkspacesUpdate::Workspaces(w)).await;
|
||||
State::Waiting(t)
|
||||
State::Waiting
|
||||
} else {
|
||||
_ = output.send(WorkspacesUpdate::Errored).await;
|
||||
State::Error
|
||||
|
|
@ -57,8 +64,7 @@ async fn start_listening(
|
|||
}
|
||||
|
||||
pub enum State {
|
||||
Ready,
|
||||
Waiting(WorkspacesWatcher),
|
||||
Waiting,
|
||||
Error,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue