From e64fb789c7c97b77910ebaf19537e446278612cc Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Sun, 2 Aug 2026 16:35:47 +0900 Subject: [PATCH] persist window sizes for wvr & passthru --- wayvr/src/overlays/passthrough.rs | 75 +++++++++++++++++-------------- wayvr/src/overlays/wayvr.rs | 10 +++++ wayvr/src/windowing/manager.rs | 26 +++++++---- wlx-common/src/overlays.rs | 12 +++++ 4 files changed, 82 insertions(+), 41 deletions(-) diff --git a/wayvr/src/overlays/passthrough.rs b/wayvr/src/overlays/passthrough.rs index 87f5b00e..80a49cba 100644 --- a/wayvr/src/overlays/passthrough.rs +++ b/wayvr/src/overlays/passthrough.rs @@ -91,6 +91,35 @@ impl PassthruBackend { overlay_id: OverlayID::null(), } } + fn resize(&mut self, app: &mut AppState, new_size: [u32; 2]) { + self.frame_meta.extent = [new_size[0].clamp(256, 1024), new_size[1].clamp(256, 1024)]; + self.interaction_transform = ui_transform(self.frame_meta.extent); + + let old_scale = self.scale; + let (new_scale, _) = overlay_scale_from_extent(self.frame_meta.extent); + self.scale = new_scale; + + if new_scale.abs() > f32::EPSILON { + let scale_delta = new_scale / old_scale; + + if (scale_delta - 1.0).abs() > f32::EPSILON { + app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify( + OverlaySelector::Id(self.overlay_id), + Box::new(move |_app, owc| { + if let Some(state) = owc.active_state.as_mut() { + if let Some(saved) = state.saved_transform.as_mut() { + saved.matrix3 = saved.matrix3.mul_scalar(scale_delta); + } + + state.transform.matrix3 = + state.transform.matrix3.mul_scalar(scale_delta); + } + }), + ))); + } + } + self.rendered = false; + } } impl OverlayBackend for PassthruBackend { @@ -177,36 +206,7 @@ impl OverlayBackend for PassthruBackend { fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> { match event_data { OverlayEventData::IdAssigned(id) => self.overlay_id = id, - OverlayEventData::ResizeRequest(new_size) => { - self.frame_meta.extent = - [new_size[0].clamp(256, 1024), new_size[1].clamp(256, 1024)]; - self.interaction_transform = ui_transform(self.frame_meta.extent); - - let old_scale = self.scale; - let (new_scale, _) = overlay_scale_from_extent(self.frame_meta.extent); - self.scale = new_scale; - - if new_scale.abs() > f32::EPSILON { - let scale_delta = new_scale / old_scale; - - if (scale_delta - 1.0).abs() > f32::EPSILON { - app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify( - OverlaySelector::Id(self.overlay_id), - Box::new(move |_app, owc| { - if let Some(state) = owc.active_state.as_mut() { - if let Some(saved) = state.saved_transform.as_mut() { - saved.matrix3 = saved.matrix3.mul_scalar(scale_delta); - } - - state.transform.matrix3 = - state.transform.matrix3.mul_scalar(scale_delta); - } - }), - ))); - } - } - self.rendered = false; - } + OverlayEventData::ResizeRequest(new_size) => self.resize(app, new_size), _ => {} } Ok(()) @@ -242,14 +242,23 @@ impl OverlayBackend for PassthruBackend { ) -> Option { match attrib { BackendAttrib::Resizable => Some(BackendAttribValue::Resizable(true)), + BackendAttrib::WindowSize => { + Some(BackendAttribValue::WindowSize(self.frame_meta.extent)) + } _ => None, } } fn set_attrib( &mut self, - _app: &mut AppState, - _value: wlx_common::overlays::BackendAttribValue, + app: &mut AppState, + value: wlx_common::overlays::BackendAttribValue, ) -> bool { - false + match value { + BackendAttribValue::WindowSize(new_size) => { + self.resize(app, new_size); + true + } + _ => false, + } } } diff --git a/wayvr/src/overlays/wayvr.rs b/wayvr/src/overlays/wayvr.rs index ab414991..15fa8638 100644 --- a/wayvr/src/overlays/wayvr.rs +++ b/wayvr/src/overlays/wayvr.rs @@ -1076,6 +1076,16 @@ impl OverlayBackend for WvrWindowBackend { } true } + BackendAttribValue::WindowSize(new_size) => { + let wvr_server = app.wvr_server.as_mut().unwrap(); + let Some(win) = wvr_server.wm.windows.get_mut(self.window) else { + log::warn!("Could not process resize request: window not found"); + return true; + }; + let size: Size = Size::new(new_size[0] as i32, new_size[1] as i32); + win.checked_configure_size(size); + true + } _ => false, } } diff --git a/wayvr/src/windowing/manager.rs b/wayvr/src/windowing/manager.rs index d26e553b..db63a903 100644 --- a/wayvr/src/windowing/manager.rs +++ b/wayvr/src/windowing/manager.rs @@ -587,14 +587,17 @@ impl OverlayWindowManager { // BackendAttrib for o in self.overlays.values() { - app.session.config.attribs.arc_set( - o.config.name.clone(), - SAVED_ATTRIBS - .iter() - .filter_map(|a| o.config.backend.get_attrib(*a)) - .filter(|val| !val.is_default()) - .collect(), - ); + let attrs: Vec<_> = SAVED_ATTRIBS + .iter() + .filter_map(|a| o.config.backend.get_attrib(*a)) + .filter(|val| !val.is_default()) + .collect(); + if !attrs.is_empty() { + app.session + .config + .attribs + .arc_set(o.config.name.clone(), attrs); + } } if restore_after { @@ -925,6 +928,13 @@ impl OverlayWindowManager { log::debug!("loaded state for {name} from global_set!"); } + let saved_attribs = app.session.config.attribs.arc_get(&name).cloned(); + if let Some(attribs) = saved_attribs { + for value in attribs { + self.overlays[oid].config.backend.set_attrib(app, value); + } + } + self.overlays[oid] .config .backend diff --git a/wlx-common/src/overlays.rs b/wlx-common/src/overlays.rs index d0598e3e..26a32cc6 100644 --- a/wlx-common/src/overlays.rs +++ b/wlx-common/src/overlays.rs @@ -40,8 +40,11 @@ pub enum BackendAttribValue { Icon(Arc), #[serde(skip_serializing, skip_deserializing)] Resizable(bool), + WindowSize([u32; 2]), } +const WELL_KNOWN_ASPECT_RATIOS: &[f32] = &[16. / 9., 3. / 2., 1., 2. / 3., 9. / 16.]; + impl BackendAttribValue { /// Used to determine if value should be saved pub fn is_default(&self) -> bool { @@ -52,6 +55,15 @@ impl BackendAttribValue { Self::MouseTransform(val) => *val == MouseTransform::default(), Self::Icon(_) => false, Self::Resizable(_) => false, + Self::WindowSize([w, h]) => { + let r = (*w as f32) / (*h as f32); + for a in WELL_KNOWN_ASPECT_RATIOS { + if (a - r).abs() < 0.01 { + return true; + } + } + false + } } } }