fix(corner-radius): post protocol errors
This commit is contained in:
parent
242e465d42
commit
819887e298
2 changed files with 79 additions and 21 deletions
|
|
@ -1,9 +1,12 @@
|
||||||
use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1;
|
use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v1;
|
||||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||||
use smithay::wayland::shell::xdg::ToplevelSurface;
|
use smithay::reexports::wayland_server::Resource;
|
||||||
|
use smithay::wayland::compositor::{add_pre_commit_hook, with_states};
|
||||||
|
use smithay::wayland::shell::xdg::{SurfaceCachedState, ToplevelSurface};
|
||||||
|
|
||||||
use crate::wayland::protocols::corner_radius::{
|
use crate::wayland::protocols::corner_radius::{
|
||||||
delegate_corner_radius, CornerRadiusData, CornerRadiusHandler, CornerRadiusState,
|
delegate_corner_radius, CacheableCorners, CornerRadiusData, CornerRadiusHandler,
|
||||||
|
CornerRadiusState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
|
|
@ -39,6 +42,45 @@ impl CornerRadiusHandler for State {
|
||||||
tracing::warn!("Failed to force redraw for corner radius reset.");
|
tracing::warn!("Failed to force redraw for corner radius reset.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_corners(
|
||||||
|
&mut self,
|
||||||
|
toplevel: &xdg_toplevel::XdgToplevel,
|
||||||
|
toplevel_obj: cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
|
||||||
|
) {
|
||||||
|
if let Some(surface) = self.toplevel_from_resource(&toplevel) {
|
||||||
|
add_pre_commit_hook::<Self, _>(surface.wl_surface(), move |_, _dh, surface| {
|
||||||
|
let corner_radii_too_big = with_states(surface, |surface_data| {
|
||||||
|
let corners = surface_data
|
||||||
|
.cached_state
|
||||||
|
.get::<CacheableCorners>()
|
||||||
|
.pending()
|
||||||
|
.clone();
|
||||||
|
surface_data
|
||||||
|
.cached_state
|
||||||
|
.get::<SurfaceCachedState>()
|
||||||
|
.pending()
|
||||||
|
.geometry
|
||||||
|
.zip(corners.0.as_ref())
|
||||||
|
.is_some_and(|(geo, corners)| {
|
||||||
|
let half_min_dim =
|
||||||
|
u8::try_from(geo.size.w.min(geo.size.h) / 2).unwrap_or(u8::MAX);
|
||||||
|
corners.top_right > half_min_dim
|
||||||
|
|| corners.top_left > half_min_dim
|
||||||
|
|| corners.bottom_right > half_min_dim
|
||||||
|
|| corners.bottom_left > half_min_dim
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if corner_radii_too_big {
|
||||||
|
toplevel_obj.post_error(
|
||||||
|
cosmic_corner_radius_toplevel_v1::Error::RadiusTooLarge as u32,
|
||||||
|
format!("{toplevel_obj:?} corner radius too large"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn force_redraw(state: &mut State, data: &CornerRadiusData) -> Option<()> {
|
fn force_redraw(state: &mut State, data: &CornerRadiusData) -> Option<()> {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,11 @@ impl CornerRadiusState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CornerRadiusHandler {
|
pub trait CornerRadiusHandler {
|
||||||
|
fn add_corners(
|
||||||
|
&mut self,
|
||||||
|
toplevel: &XdgToplevel,
|
||||||
|
toplevel_obj: cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1,
|
||||||
|
);
|
||||||
fn corner_radius_state(&mut self) -> &mut CornerRadiusState;
|
fn corner_radius_state(&mut self) -> &mut CornerRadiusState;
|
||||||
fn toplevel_from_resource(&mut self, toplevel: &XdgToplevel) -> Option<ToplevelSurface>;
|
fn toplevel_from_resource(&mut self, toplevel: &XdgToplevel) -> Option<ToplevelSurface>;
|
||||||
fn set_corner_radius(
|
fn set_corner_radius(
|
||||||
|
|
@ -111,7 +116,8 @@ where
|
||||||
toplevel: toplevel.downgrade(),
|
toplevel: toplevel.downgrade(),
|
||||||
corners: None,
|
corners: None,
|
||||||
});
|
});
|
||||||
let _ = data_init.init(id, data);
|
let obj = data_init.init(id, data);
|
||||||
|
state.add_corners(&toplevel, obj);
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
|
|
@ -151,12 +157,16 @@ where
|
||||||
cosmic_corner_radius_toplevel_v1::Request::Destroy => {
|
cosmic_corner_radius_toplevel_v1::Request::Destroy => {
|
||||||
let mut guard = data.lock().unwrap();
|
let mut guard = data.lock().unwrap();
|
||||||
guard.corners = None;
|
guard.corners = None;
|
||||||
if let Some(surface) = guard
|
|
||||||
.toplevel
|
let Ok(toplevel) = guard.toplevel.upgrade() else {
|
||||||
.upgrade()
|
resource.post_error(
|
||||||
.ok()
|
cosmic_corner_radius_toplevel_v1::Error::ToplevelDestroyed as u32,
|
||||||
.and_then(|toplevel| state.toplevel_from_resource(&toplevel))
|
format!("{:?} No toplevel found", resource),
|
||||||
{
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(surface) = state.toplevel_from_resource(&toplevel) {
|
||||||
with_states(surface.wl_surface(), |s| {
|
with_states(surface.wl_surface(), |s| {
|
||||||
let mut cached = s.cached_state.get::<CacheableCorners>();
|
let mut cached = s.cached_state.get::<CacheableCorners>();
|
||||||
let pending = cached.pending();
|
let pending = cached.pending();
|
||||||
|
|
@ -175,12 +185,15 @@ where
|
||||||
} => {
|
} => {
|
||||||
let mut guard = data.lock().unwrap();
|
let mut guard = data.lock().unwrap();
|
||||||
guard.set_corner_radius(top_left, top_right, bottom_right, bottom_left);
|
guard.set_corner_radius(top_left, top_right, bottom_right, bottom_left);
|
||||||
if let Some(surface) = guard
|
let Ok(toplevel) = guard.toplevel.upgrade() else {
|
||||||
.toplevel
|
resource.post_error(
|
||||||
.upgrade()
|
cosmic_corner_radius_toplevel_v1::Error::ToplevelDestroyed as u32,
|
||||||
.ok()
|
format!("{:?} No toplevel found", resource),
|
||||||
.and_then(|toplevel| state.toplevel_from_resource(&toplevel))
|
);
|
||||||
{
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(surface) = state.toplevel_from_resource(&toplevel) {
|
||||||
with_states(surface.wl_surface(), |s| {
|
with_states(surface.wl_surface(), |s| {
|
||||||
let mut cached = s.cached_state.get::<CacheableCorners>();
|
let mut cached = s.cached_state.get::<CacheableCorners>();
|
||||||
let pending = cached.pending();
|
let pending = cached.pending();
|
||||||
|
|
@ -194,12 +207,15 @@ where
|
||||||
cosmic_corner_radius_toplevel_v1::Request::UnsetRadius => {
|
cosmic_corner_radius_toplevel_v1::Request::UnsetRadius => {
|
||||||
let mut guard = data.lock().unwrap();
|
let mut guard = data.lock().unwrap();
|
||||||
guard.corners = None;
|
guard.corners = None;
|
||||||
if let Some(surface) = guard
|
let Ok(toplevel) = guard.toplevel.upgrade() else {
|
||||||
.toplevel
|
resource.post_error(
|
||||||
.upgrade()
|
cosmic_corner_radius_toplevel_v1::Error::ToplevelDestroyed as u32,
|
||||||
.ok()
|
format!("{:?} No toplevel found", resource),
|
||||||
.and_then(|toplevel| state.toplevel_from_resource(&toplevel))
|
);
|
||||||
{
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(surface) = state.toplevel_from_resource(&toplevel) {
|
||||||
with_states(surface.wl_surface(), |s| {
|
with_states(surface.wl_surface(), |s| {
|
||||||
let mut cached = s.cached_state.get::<CacheableCorners>();
|
let mut cached = s.cached_state.get::<CacheableCorners>();
|
||||||
let pending = cached.pending();
|
let pending = cached.pending();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue