feat(servo-shell): sync WebView set on appd reconnect via SyncSessions

RUNNING_APPS response now produces a SyncSessions command instead of
individual Launch commands. The embedder retains only WebViews whose
session_id is in the active list (removes stale entries from sessions
that stopped during a disconnect), then creates WebViews for any
sessions not yet tracked. This is idempotent thanks to the existing
contains_key guard in create_app_webview.
This commit is contained in:
Marco Allegretti 2026-03-11 18:41:00 +01:00
parent 6f43490192
commit 099283bc4b
2 changed files with 24 additions and 9 deletions

View file

@ -5,6 +5,7 @@ use std::sync::mpsc;
pub enum AppdCmd {
Launch { session_id: u64, app_id: String },
Stop { session_id: u64 },
SyncSessions { active: Vec<(u64, String)> },
}
pub fn spawn_appd_listener(
@ -76,16 +77,17 @@ fn process_message(text: &str, tx: &mpsc::SyncSender<AppdCmd>, wake: &dyn Fn())
let Some(sessions) = v["sessions"].as_array() else {
return;
};
for s in sessions {
let Some(session_id) = s["session_id"].as_u64() else {
continue;
};
let Some(app_id) = s["app_id"].as_str().map(str::to_string) else {
continue;
};
let _ = tx.try_send(AppdCmd::Launch { session_id, app_id });
let active: Vec<(u64, String)> = sessions
.iter()
.filter_map(|s| {
let sid = s["session_id"].as_u64()?;
let aid = s["app_id"].as_str()?.to_string();
Some((sid, aid))
})
.collect();
if tx.try_send(AppdCmd::SyncSessions { active }).is_ok() {
wake();
}
wake();
}
Some("APP_STATE") if v["state"].as_str() == Some("stopped") => {
let Some(session_id) = v["session_id"].as_u64() else {

View file

@ -257,6 +257,19 @@ impl ApplicationHandler<ServoWake> for App {
self.active_session = None;
}
}
crate::appd_ws::AppdCmd::SyncSessions { active } => {
let active_ids: std::collections::HashSet<u64> =
active.iter().map(|(sid, _)| *sid).collect();
self.app_webviews.retain(|sid, _| active_ids.contains(sid));
if let Some(cur) = self.active_session {
if !active_ids.contains(&cur) {
self.active_session = None;
}
}
for (session_id, app_id) in active {
self.create_app_webview(session_id, &app_id);
}
}
}
}
if let Some(servo) = &self.servo {