Synchronize shell material presentation with surface commits

Queue popup, modal and notification material geometry and opacity until the matching content buffer commits. Remove event-handler opacity writes that could present material state ahead of content, while preserving compositor dismissal ownership.

Add pending-presentation regression coverage and update the nested shell lifecycle check.
This commit is contained in:
Samuel Onoja committed 2026-10-03 04:45:12 +01:00
1 parent e6e1a2a8cf
commit bffd538dd4
9 files changed
+159 -50

No files matched your search

+19 -13
View File
@@ -333,9 +333,6 @@ impl FereseShell {
}
_ => {}
}
if let Some(effects) = &menu.effects {
let _ = effects.set_opacity(menu.progress());
}
}
Task::none()
}
@@ -488,7 +485,7 @@ pub(super) struct EffectsBinding {
_queue: EventQueue<EffectsState>,
regions: std::cell::RefCell<Option<Vec<[f32; 5]>>>,
opacity: std::cell::Cell<Option<u32>>,
region_opacities: std::cell::RefCell<Vec<u32>>,
presentation: std::cell::RefCell<Option<(Vec<[f32; 5]>, u32, Vec<u32>, ferese_surface_effects_v1::Role)>>,
}
impl EffectsBinding {
@@ -512,7 +509,7 @@ impl EffectsBinding {
let connection = Connection::from_backend(backend);
let (globals, queue) = registry_queue_init::<EffectsState>(&connection)?;
let qh = queue.handle();
let manager = globals.bind::<FereseEffectsManagerV1, _, _>(&qh, 4..=4, ())?;
let manager = globals.bind::<FereseEffectsManagerV1, _, _>(&qh, 5..=5, ())?;
let effects = manager.get_surface_effects(surface, &qh, ());
let opacity = (opacity.clamp(0.0, 1.0) * 1000.0).round() as u32;
@@ -531,24 +528,33 @@ impl EffectsBinding {
_queue: queue,
regions: Default::default(),
opacity: std::cell::Cell::new(Some(opacity)),
region_opacities: Default::default(),
presentation: Default::default(),
})
}
pub(super) fn set_region_opacities(
pub(super) fn set_presentation(
&self,
values: impl IntoIterator<Item = f32>,
regions: &[[f32; 5]],
opacity: f32,
region_opacities: impl IntoIterator<Item = f32>,
role: ferese_surface_effects_v1::Role,
) -> Result<(), Box<dyn std::error::Error>> {
let values: Vec<u32> = values
let opacity = (opacity.clamp(0.0, 1.0) * 1000.0).round() as u32;
let values: Vec<u32> = region_opacities
.into_iter()
.take(32)
.map(|value| (value.clamp(0.0, 1.0) * 1000.0).round() as u32)
.collect();
if *self.region_opacities.borrow() != values {
self.surface
.set_region_opacities(values.iter().flat_map(|value| value.to_ne_bytes()).collect());
let next = (regions.to_vec(), opacity, values, role);
if self.presentation.borrow().as_ref() != Some(&next) {
self.surface.set_presentation(
role,
encode_regions(regions),
opacity,
next.2.iter().flat_map(|value| value.to_ne_bytes()).collect(),
);
self.connection.flush()?;
*self.region_opacities.borrow_mut() = values;
*self.presentation.borrow_mut() = Some(next);
}
Ok(())
}