fix: set blur and corners on creation
This commit is contained in:
parent
5cc9f8d621
commit
46781102fe
2 changed files with 100 additions and 81 deletions
|
|
@ -401,6 +401,7 @@ impl SctkEventLoop {
|
||||||
preedit: None,
|
preedit: None,
|
||||||
pending_delete: None,
|
pending_delete: None,
|
||||||
pending_commit: None,
|
pending_commit: None,
|
||||||
|
pending_blur: HashMap::new(),
|
||||||
},
|
},
|
||||||
_features: Default::default(),
|
_features: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -39,15 +39,12 @@ use cctk::{
|
||||||
cosmic_protocols::{
|
cosmic_protocols::{
|
||||||
corner_radius::v1::client::{
|
corner_radius::v1::client::{
|
||||||
cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
|
cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1,
|
||||||
cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
|
|
||||||
},
|
},
|
||||||
overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1,
|
overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1,
|
||||||
},
|
}, sctk::{
|
||||||
sctk::{
|
|
||||||
activation::{ActivationState, RequestData},
|
activation::{ActivationState, RequestData},
|
||||||
compositor::CompositorState,
|
compositor::CompositorState,
|
||||||
error::GlobalError,
|
error::GlobalError,
|
||||||
globals::GlobalData,
|
|
||||||
output::OutputState,
|
output::OutputState,
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{LoopHandle, timer::TimeoutAction},
|
calloop::{LoopHandle, timer::TimeoutAction},
|
||||||
|
|
@ -87,9 +84,7 @@ use cctk::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shm::{Shm, multi::MultiPool},
|
shm::{Shm, multi::MultiPool},
|
||||||
},
|
}, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState
|
||||||
toplevel_info::ToplevelInfoState,
|
|
||||||
toplevel_management::ToplevelManagerState,
|
|
||||||
};
|
};
|
||||||
use iced_runtime::{
|
use iced_runtime::{
|
||||||
core::{self, Point, touch},
|
core::{self, Point, touch},
|
||||||
|
|
@ -104,7 +99,7 @@ use iced_runtime::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use wayland_protocols::{
|
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::{
|
wp::{
|
||||||
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||||
keyboard_shortcuts_inhibit::zv1::client::{
|
keyboard_shortcuts_inhibit::zv1::client::{
|
||||||
|
|
@ -486,6 +481,7 @@ pub struct SctkState {
|
||||||
|
|
||||||
pub(crate) corner_radius_manager: Option<CosmicCornerRadiusManagerV1>,
|
pub(crate) corner_radius_manager: Option<CosmicCornerRadiusManagerV1>,
|
||||||
pub(crate) pending_corner_radius: HashMap<core::window::Id, CornerRadius>,
|
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_manager: Option<TextInputManager>,
|
||||||
pub(crate) text_input: Option<Arc<ZwpTextInputV3>>,
|
pub(crate) text_input: Option<Arc<ZwpTextInputV3>>,
|
||||||
|
|
@ -836,6 +832,7 @@ impl SctkState {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let toplevel = toplevel.clone();
|
||||||
|
|
||||||
popup.xdg_surface().set_window_geometry(
|
popup.xdg_surface().set_window_geometry(
|
||||||
0,
|
0,
|
||||||
|
|
@ -868,6 +865,18 @@ impl SctkState {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = wl_surface.frame(&self.queue_handle, wl_surface.clone());
|
_ = 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();
|
wl_surface.commit();
|
||||||
|
|
||||||
let wp_viewport = self.viewporter_state.as_ref().map(|state| {
|
let wp_viewport = self.viewporter_state.as_ref().map(|state| {
|
||||||
|
|
@ -996,6 +1005,15 @@ impl SctkState {
|
||||||
layer_surface.set_input_region(Some(®ion));
|
layer_surface.set_input_region(Some(®ion));
|
||||||
region.destroy();
|
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();
|
layer_surface.commit();
|
||||||
|
|
||||||
let wp_viewport = self.viewporter_state.as_ref().map(|state| {
|
let wp_viewport = self.viewporter_state.as_ref().map(|state| {
|
||||||
|
|
@ -1099,12 +1117,6 @@ impl SctkState {
|
||||||
id: wl_surface.clone(),
|
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 {
|
platform_specific::wayland::layer_surface::Action::Size {
|
||||||
|
|
@ -1338,12 +1350,6 @@ impl SctkState {
|
||||||
SctkEvent::PopupEvent {
|
SctkEvent::PopupEvent {
|
||||||
variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(queue_handle.clone(), surface, id, common, state.connection.display()),
|
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 });
|
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) => {
|
Err(err) => {
|
||||||
log::error!("Failed to create popup. {err:?}");
|
log::error!("Failed to create popup. {err:?}");
|
||||||
|
|
@ -1362,12 +1368,6 @@ impl SctkState {
|
||||||
SctkEvent::PopupEvent {
|
SctkEvent::PopupEvent {
|
||||||
variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(self.queue_handle.clone(), surface, id, common, self.connection.display()),
|
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 });
|
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) => {
|
Err(err) => {
|
||||||
log::error!("Failed to create popup. {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) {
|
} else if let Some(subsurface) = self.subsurfaces.iter().find(|s| s.id == id) {
|
||||||
&subsurface.instance.wl_surface
|
&subsurface.instance.wl_surface
|
||||||
} else {
|
} 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(());
|
return Ok(());
|
||||||
};
|
}.clone();
|
||||||
let existing_blur = self.blur_surfaces.entry(id);
|
self.apply_blur(id, rectangles, &s)
|
||||||
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);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(())
|
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(®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(
|
pub fn get_subsurface(
|
||||||
&mut self,
|
&mut self,
|
||||||
settings: SctkSubsurfaceSettings,
|
settings: SctkSubsurfaceSettings,
|
||||||
|
|
@ -1849,7 +1857,7 @@ impl SctkState {
|
||||||
),
|
),
|
||||||
SubsurfaceCreationError,
|
SubsurfaceCreationError,
|
||||||
> {
|
> {
|
||||||
let Some(subsurface_state) = self.subsurface_state.as_ref() else {
|
let Some(subsurface_state) = self.subsurface_state.clone() else {
|
||||||
return Err(SubsurfaceCreationError::Unsupported);
|
return Err(SubsurfaceCreationError::Unsupported);
|
||||||
};
|
};
|
||||||
if self.layer_surfaces.iter().any(|s| s.id == settings.id)
|
if self.layer_surfaces.iter().any(|s| s.id == settings.id)
|
||||||
|
|
@ -1965,6 +1973,16 @@ impl SctkState {
|
||||||
region.destroy();
|
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();
|
wl_surface.commit();
|
||||||
|
|
||||||
let wp_viewport = subsurface_state.wp_viewporter.get_viewport(
|
let wp_viewport = subsurface_state.wp_viewporter.get_viewport(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue