fix: set blur and corners on creation

This commit is contained in:
Ashley Wulber 2026-05-28 19:21:54 -04:00 committed by Ashley Wulber
parent 5cc9f8d621
commit 46781102fe
2 changed files with 100 additions and 81 deletions

View file

@ -401,6 +401,7 @@ impl SctkEventLoop {
preedit: None,
pending_delete: None,
pending_commit: None,
pending_blur: HashMap::new(),
},
_features: Default::default(),
};

View file

@ -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<CosmicCornerRadiusManagerV1>,
pub(crate) pending_corner_radius: HashMap<core::window::Id, CornerRadius>,
pub(crate) pending_blur: HashMap<core::window::Id, Vec<Rectangle>>,
pub(crate) text_input_manager: Option<TextInputManager>,
pub(crate) text_input: Option<Arc<ZwpTextInputV3>>,
@ -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(&region));
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(&region));
},
(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(&region));
_ = vacant_entry.insert(blur_surface);
},
}
}.clone();
self.apply_blur(id, rectangles, &s)
},
};
Ok(())
}
fn apply_blur(&mut self, id: core::window::Id, rectangles: Option<Vec<Rectangle>>, 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(&region));
},
(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(&region));
_ = 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(