From f4523f3ab176f4a22738e4b11fb26fe500d0fd61 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Sun, 2 Aug 2026 00:34:11 +0900 Subject: [PATCH] persistent passthrus --- wayvr/src/gui/panel/overlay_list.rs | 11 ++++--- wayvr/src/overlays/passthrough.rs | 4 ++- wayvr/src/windowing/manager.rs | 47 +++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/wayvr/src/gui/panel/overlay_list.rs b/wayvr/src/gui/panel/overlay_list.rs index 575d1b03..1c06f323 100644 --- a/wayvr/src/gui/panel/overlay_list.rs +++ b/wayvr/src/gui/panel/overlay_list.rs @@ -60,10 +60,13 @@ impl OverlayList { ("Mirror", panels_root) } OverlayCategory::Passthru => { - params.insert_rc( - "display", - (*meta.name).chars().last().unwrap().to_string().into(), - ); + let display = meta + .name + .rsplit('-') + .next() + .unwrap_or(&meta.name) + .to_string(); + params.insert_rc("display", display.into()); ("Passthru", panels_root) } OverlayCategory::Panel | OverlayCategory::BuiltInPanel => { diff --git a/wayvr/src/overlays/passthrough.rs b/wayvr/src/overlays/passthrough.rs index a166b5dd..ef6cd4fe 100644 --- a/wayvr/src/overlays/passthrough.rs +++ b/wayvr/src/overlays/passthrough.rs @@ -27,10 +27,12 @@ use crate::{ }, }; +pub const PASSTHRU_PREFIX: &str = "__wvr_passthru-"; + static PASSTHRU_COUNTER: AtomicUsize = AtomicUsize::new(1); pub fn new_passtrhu_name() -> Arc { - format!("P-{}", PASSTHRU_COUNTER.fetch_add(1, Ordering::Relaxed)).into() + format!("{PASSTHRU_PREFIX}{}", PASSTHRU_COUNTER.fetch_add(1, Ordering::Relaxed)).into() } pub fn new_passthru(name: Arc, app: &AppState) -> OverlayWindowConfig { diff --git a/wayvr/src/windowing/manager.rs b/wayvr/src/windowing/manager.rs index 5d9bd316..314fe2ca 100644 --- a/wayvr/src/windowing/manager.rs +++ b/wayvr/src/windowing/manager.rs @@ -159,6 +159,27 @@ where me.restore_layout(app); me.overlays_changed(app)?; + // recreate saved passthru overlays + let saved_passthrus: Vec<_> = app + .session + .config + .global_set + .iter() + .filter(|(name, _)| name.starts_with(crate::overlays::passthrough::PASSTHRU_PREFIX)) + .map(|(name, state)| (name.clone(), state.clone())) + .collect(); + for (name, saved_state) in saved_passthrus { + if me.lookup(&name).is_none() { + let config = crate::overlays::passthrough::new_passthru(name.clone(), app); + let id = me.add(OverlayWindowData::from_config(config), app); + if let Some(o) = me.mut_by_id(id) { + o.config.active_state = Some(saved_state); + o.config.reset(app, false); + log::debug!("restored passthru {}", name); + } + } + } + for id in [me.watch_id, me.keyboard_id] { for ev in [ OverlayEventData::NumSetsChanged(me.sets.len()), @@ -376,11 +397,27 @@ where self.spawn_overlay(app, sel, spawn_pos, f)?; } OverlayTask::Drop(sel) => { + let (id, name) = match &sel { + OverlaySelector::Id(id) => { + let id = *id; + let name = self.overlays.get(id).map(|o| o.config.name.clone()); + (Some(id), name) + } + OverlaySelector::Name(name) => { + let id = self.lookup(name); + (id, Some(name.clone())) + } + _ => (None, None), + }; + if let Some(o) = self.mut_by_selector(&sel) && o.birthframe < FRAME_COUNTER.load(Ordering::Relaxed) && let Some(o) = self.remove_by_selector(&sel, app) { log::debug!("Dropping overlay {}", o.config.name); + if let (Some(id), Some(name)) = (id, name) { + self.remove_saved_state(id, &name); + } self.dropped_overlays.push_back(o); } } @@ -455,6 +492,16 @@ impl OverlayWindowManager { self.dropped_overlays.pop_front() } + fn remove_saved_state(&mut self, id: OverlayID, name: &str) { + for set in &mut self.sets { + set.overlays.retain(|k, _| k != id); + set.inactive_overlays.arc_rm(name); + set.hidden_overlays.arc_rm(name); + } + self.global_set.inactive_overlays.arc_rm(name); + self.global_set.hidden_overlays.arc_rm(name); + } + pub fn persist_layout(&mut self, app: &mut AppState) { app.session.config.global_set.clear(); app.session.config.sets.clear();