From 4ea1f1f222fd5e5e6922785c24a09d9e58ca0113 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 1 Oct 2026 12:09:14 +0100 Subject: [PATCH] Prepare menu surfaces before animating popovers --- shell/ferese-shell/src/main.rs | 51 ++--------------------- shell/ferese-shell/src/notification_ui.rs | 9 +--- shell/ferese-shell/src/status_ui.rs | 23 +++++++--- 3 files changed, 22 insertions(+), 61 deletions(-) diff --git a/shell/ferese-shell/src/main.rs b/shell/ferese-shell/src/main.rs index 3dcd0f4..8250176 100644 --- a/shell/ferese-shell/src/main.rs +++ b/shell/ferese-shell/src/main.rs @@ -532,18 +532,8 @@ impl cosmic::Application for FereseShell { if let Some(menu) = &mut self.menu && menu.id == id - && menu.effects.is_none() { - match EffectsBinding::attach_role(&surface, menu.kind.material_role(), menu.progress()) { - Ok(binding) => menu.effects = Some(binding), - Err(error) => { - eprintln!("ferese-shell: popover material unavailable: {error}") - } - } - - if let Some(effects) = &menu.effects { - let _ = effects.set_opacity(menu.progress()); - } + menu.prepare_surface(&surface); } } Err(error) => eprintln!("ferese-shell: native surface unavailable: {error}"), @@ -1841,17 +1831,6 @@ impl FereseShell { .as_ref() .is_some_and(|surface| surface.id == id) => { - // Iced emits the first xdg_popup configure as Window::Opened, - // not Popup::Configured. This is the popup's ready signal. - if let Some(menu) = &mut self.menu - && menu.id == id - { - menu.motion.begin(Instant::now()); - if let Some(effects) = &menu.effects { - let _ = effects.set_opacity(menu.progress()); - } - } - Task::batch([ self.focus_system_modal(id), window::run(id, native_wayland_surface) @@ -1876,26 +1855,8 @@ impl FereseShell { EFFECT_FRAME_PENDING.store(false, Ordering::Relaxed); return self.sync_notification_surface(); } - wayland::PopupEvent::Focused => { - if menu.effects.is_none() { - match EffectsBinding::attach_role(&surface, menu.kind.material_role(), menu.progress()) - { - Ok(binding) => menu.effects = Some(binding), - Err(error) => eprintln!("ferese-shell: popover material unavailable: {error}"), - } - EFFECT_FRAME_PENDING.store(false, Ordering::Relaxed); - } - } wayland::PopupEvent::Configured { .. } => { - menu.motion.begin(Instant::now()); - if menu.effects.is_none() { - match EffectsBinding::attach_role(&surface, menu.kind.material_role(), menu.progress()) - { - Ok(binding) => menu.effects = Some(binding), - Err(error) => eprintln!("ferese-shell: popover material unavailable: {error}"), - } - EFFECT_FRAME_PENDING.store(false, Ordering::Relaxed); - } + menu.prepare_surface(&surface); } _ => {} } @@ -1922,13 +1883,7 @@ impl FereseShell { if let Some(menu) = &mut self.menu && menu.effects.is_none() { - match EffectsBinding::attach_role(&surface, menu.kind.material_role(), menu.progress()) { - Ok(binding) => menu.effects = Some(binding), - Err(error) => { - eprintln!("ferese-shell: popover material unavailable: {error}") - } - } - EFFECT_FRAME_PENDING.store(false, Ordering::Relaxed); + menu.prepare_surface(&surface); } Task::none() } diff --git a/shell/ferese-shell/src/notification_ui.rs b/shell/ferese-shell/src/notification_ui.rs index 10135b8..48ad184 100644 --- a/shell/ferese-shell/src/notification_ui.rs +++ b/shell/ferese-shell/src/notification_ui.rs @@ -536,14 +536,7 @@ impl FereseShell { let palette = self.config.theme; let surface = self.menu.as_ref(); let progress = surface.map_or(1.0, status_ui::OpenMenu::progress); - let opacity = if surface - .and_then(|surface| surface.effects.as_ref()) - .is_some_and(|effects| effects.surface.version() >= 3) - { - 1.0 - } else { - progress - }; + let opacity = 1.0; let color = move |rgba| color_with_opacity(rgba, opacity); let primary = color(palette.text_primary); let muted = color(palette.text_muted); diff --git a/shell/ferese-shell/src/status_ui.rs b/shell/ferese-shell/src/status_ui.rs index d44c479..a05867a 100644 --- a/shell/ferese-shell/src/status_ui.rs +++ b/shell/ferese-shell/src/status_ui.rs @@ -51,10 +51,6 @@ impl Menu { if self == Self::Calendar { 270.0 } else { 720.0 } } - pub(super) fn material_role(self) -> Option { - Some(ferese_surface_effects_v1::Role::Popover) - } - fn title(self) -> &'static str { match self { Self::System => "Control Center", @@ -90,6 +86,23 @@ pub struct OpenMenu { } impl OpenMenu { + pub(super) fn prepare_surface(&mut self, surface: &wl_surface::WlSurface) { + if self.effects.is_none() { + match EffectsBinding::attach_role(surface, None, 0.0) { + Ok(binding) => self.effects = Some(binding), + Err(error) => eprintln!("ferese-shell: popover material unavailable: {error}"), + } + } + if let Some(effects) = &self.effects { + let regions = self.regions.lock().unwrap(); + if let Err(error) = effects.set_regions(®ions) { + eprintln!("ferese-shell: could not prepare popover material: {error}"); + } + } + self.motion.begin(Instant::now()); + super::EFFECT_FRAME_PENDING.store(false, Ordering::Relaxed); + } + pub fn progress(&self) -> f32 { self.motion.progress() } @@ -406,7 +419,7 @@ impl FereseShell { .into(); } let theme = self.config.theme; - let p = if menu.effects.is_some() { 1.0 } else { menu.progress() }; + let p = 1.0; let kind = menu.kind; let primary = color_with_opacity(theme.text_primary, p); let muted = color_with_opacity(theme.text_muted, p);