From 46781102fe38b1bc26e6486085ea5446230293f3 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 28 May 2026 19:21:54 -0400 Subject: [PATCH] fix: set blur and corners on creation --- .../wayland/event_loop/mod.rs | 1 + .../wayland/event_loop/state.rs | 180 ++++++++++-------- 2 files changed, 100 insertions(+), 81 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index fea1c28c..b4589840 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -401,6 +401,7 @@ impl SctkEventLoop { preedit: None, pending_delete: None, pending_commit: None, + pending_blur: HashMap::new(), }, _features: Default::default(), }; diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 0fb1a132..d66f99c5 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -39,15 +39,12 @@ use cctk::{ cosmic_protocols::{ corner_radius::v1::client::{ cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, - cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, }, overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, - }, - sctk::{ + }, sctk::{ activation::{ActivationState, RequestData}, compositor::CompositorState, error::GlobalError, - globals::GlobalData, output::OutputState, reexports::{ calloop::{LoopHandle, timer::TimeoutAction}, @@ -87,9 +84,7 @@ use cctk::{ }, }, shm::{Shm, multi::MultiPool}, - }, - toplevel_info::ToplevelInfoState, - toplevel_management::ToplevelManagerState, + }, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState }; use iced_runtime::{ core::{self, Point, touch}, @@ -104,7 +99,7 @@ use iced_runtime::{ }, }; use wayland_protocols::{ - ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1, + ext::background_effect::v1::client::{ext_background_effect_manager_v1, ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1}, wp::{ fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1, keyboard_shortcuts_inhibit::zv1::client::{ @@ -486,6 +481,7 @@ pub struct SctkState { pub(crate) corner_radius_manager: Option, pub(crate) pending_corner_radius: HashMap, + pub(crate) pending_blur: HashMap>, pub(crate) text_input_manager: Option, pub(crate) text_input: Option>, @@ -836,6 +832,7 @@ impl SctkState { ) } }; + let toplevel = toplevel.clone(); popup.xdg_surface().set_window_geometry( 0, @@ -868,6 +865,18 @@ impl SctkState { } _ = wl_surface.frame(&self.queue_handle, wl_surface.clone()); + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { + self.handle_action(Action::RoundedCorners ( + settings.id, + Some(corners), + )); + } + if let Some(blur) = self.pending_blur.remove(&settings.id) { + self.apply_blur(settings.id, Some(blur), &wl_surface); + } + + + wl_surface.commit(); let wp_viewport = self.viewporter_state.as_ref().map(|state| { @@ -996,6 +1005,15 @@ impl SctkState { layer_surface.set_input_region(Some(®ion)); region.destroy(); } + if let Some(blur) = self.pending_blur.remove(&id) { + self.apply_blur(id, Some(blur), &wl_surface); + } + if let Some(corners) = self.pending_corner_radius.remove(&id) { + _ = self.handle_action(Action::RoundedCorners( + id, + Some(corners), + )); + } layer_surface.commit(); let wp_viewport = self.viewporter_state.as_ref().map(|state| { @@ -1099,12 +1117,6 @@ impl SctkState { id: wl_surface.clone(), } ); - if let Some(corners) = self.pending_corner_radius.remove(&id) { - self.handle_action(Action::RoundedCorners( - id, - Some(corners), - ))?; - } } } platform_specific::wayland::layer_surface::Action::Size { @@ -1338,12 +1350,6 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(queue_handle.clone(), surface, id, common, state.connection.display()), toplevel_id, parent_id, id: wl_surface }); - if let Some(corners) = state.pending_corner_radius.remove(&id) { - state.handle_action(Action::RoundedCorners ( - id, - Some(corners), - )); - } } Err(err) => { log::error!("Failed to create popup. {err:?}"); @@ -1362,12 +1368,6 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(self.queue_handle.clone(), surface, id, common, self.connection.display()), toplevel_id, parent_id, id: wl_surface }); - if let Some(corners) = self.pending_corner_radius.remove(&id) { - self.handle_action(Action::RoundedCorners ( - id, - Some(corners), - )); - } } Err(err) => { log::error!("Failed to create popup. {err:?}"); @@ -1776,66 +1776,74 @@ impl SctkState { } else if let Some(subsurface) = self.subsurfaces.iter().find(|s| s.id == id) { &subsurface.instance.wl_surface } else { - log::error!("Failed to find surface for blur action"); + log::info!("Failed to find surface for blur action"); + if let Some(rectangles) = rectangles { + _ = self.pending_blur.insert(id, rectangles.clone()); + } return Ok(()); - }; - let existing_blur = self.blur_surfaces.entry(id); - match (existing_blur, rectangles) { - (Entry::Occupied(occupied_entry), None) => { - let blur_surface = occupied_entry.remove(); - blur_surface.destroy(); - }, - (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { - let blur_surface = occupied_entry.get_mut(); - let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); - for rect in rectangles.into_iter() { - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); - } - - // update existing blur surfaces - blur_surface.set_blur_region(Some(®ion)); - - }, - (Entry::Vacant(..), None) => { - // nothing to remove - }, - (Entry::Vacant(vacant_entry), Some(rectangles)) => { - if self.ext_background_effect_manager.is_none() { - log::error!("Blur effect is not supported."); - return Ok(()); - } - let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); - for rect in rectangles { - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); - } - - let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); - let blur_surface = blur_manager.blur(s, &self.queue_handle); - blur_surface.set_blur_region(Some(®ion)); - _ = vacant_entry.insert(blur_surface); - }, - } + }.clone(); + self.apply_blur(id, rectangles, &s) }, }; Ok(()) } + fn apply_blur(&mut self, id: core::window::Id, rectangles: Option>, s: &WlSurface) { + let existing_blur = self.blur_surfaces.entry(id); + match (existing_blur, rectangles) { + (Entry::Occupied(occupied_entry), None) => { + let blur_surface = occupied_entry.remove(); + blur_surface.destroy(); + }, + (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { + let blur_surface = occupied_entry.get_mut(); + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + for rect in rectangles.into_iter() { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + + // update existing blur surfaces + blur_surface.set_blur_region(Some(®ion)); + + }, + (Entry::Vacant(..), None) => { + // nothing to remove + }, + (Entry::Vacant(vacant_entry), Some(rectangles)) => { + if self.ext_background_effect_manager.is_none() { + log::error!("Blur effect is not supported."); + return; + } + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + for rect in rectangles { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + + let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); + let blur_surface = blur_manager.blur(s, &self.queue_handle); + blur_surface.set_blur_region(Some(®ion)); + _ = vacant_entry.insert(blur_surface); + }, + } + + } + pub fn get_subsurface( &mut self, settings: SctkSubsurfaceSettings, @@ -1849,7 +1857,7 @@ impl SctkState { ), SubsurfaceCreationError, > { - let Some(subsurface_state) = self.subsurface_state.as_ref() else { + let Some(subsurface_state) = self.subsurface_state.clone() else { return Err(SubsurfaceCreationError::Unsupported); }; if self.layer_surfaces.iter().any(|s| s.id == settings.id) @@ -1965,6 +1973,16 @@ impl SctkState { region.destroy(); } + if let Some(blur) = self.pending_blur.remove(&settings.id) { + _ = self.apply_blur(settings.id, Some(blur), &wl_surface); + } + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { + self.handle_action(Action::RoundedCorners ( + settings.id, + Some(corners), + )); + } + wl_surface.commit(); let wp_viewport = subsurface_state.wp_viewporter.get_viewport(