fix: validate layer radius against the pending surface size

This commit is contained in:
Hojjat 2026-09-02 13:45:28 -06:00 • committed by Jacob Kauffmann
parent 9059873c84
commit 8691956644

View file

@ -5,16 +5,19 @@ use cosmic_protocols::corner_radius::v1::server::cosmic_corner_radius_toplevel_v
use cosmic_protocols::corner_radius::v1::server::{ use cosmic_protocols::corner_radius::v1::server::{
cosmic_corner_radius_manager_v1, cosmic_corner_radius_toplevel_v1, cosmic_corner_radius_manager_v1, cosmic_corner_radius_toplevel_v1,
}; };
use smithay::backend::renderer::buffer_dimensions;
use smithay::backend::renderer::utils::RendererSurfaceStateUserData;
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_popup::XdgPopup; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_popup::XdgPopup;
use smithay::reexports::wayland_protocols_wlr::layer_shell::v1::server::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use smithay::reexports::wayland_protocols_wlr::layer_shell::v1::server::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
use smithay::reexports::wayland_server::New; use smithay::reexports::wayland_server::New;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{HookId, Logical, Rectangle}; use smithay::utils::{HookId, Logical, Rectangle};
use smithay::wayland::compositor::Cacheable;
use smithay::wayland::compositor::add_pre_commit_hook; use smithay::wayland::compositor::add_pre_commit_hook;
use smithay::wayland::compositor::with_states; use smithay::wayland::compositor::with_states;
use smithay::wayland::shell::wlr_layer::{LayerSurfaceAttributes, WlrLayerShellHandler}; use smithay::wayland::compositor::{BufferAssignment, Cacheable, SurfaceAttributes};
use smithay::wayland::shell::wlr_layer::WlrLayerShellHandler;
use smithay::wayland::shell::xdg::{SurfaceCachedState, XdgShellSurfaceUserData}; use smithay::wayland::shell::xdg::{SurfaceCachedState, XdgShellSurfaceUserData};
use smithay::wayland::viewporter::ViewportCachedState;
use smithay::{ use smithay::{
reexports::{ reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::XdgToplevel, wayland_protocols::xdg::shell::server::xdg_toplevel::XdgToplevel,
@ -664,25 +667,31 @@ fn layer_radius_hook<D: 'static>(_state: &mut D, _dh: &DisplayHandle, surface: &
.get::<CacheablePadding>() .get::<CacheablePadding>()
.pending(); .pending();
// The radius and padding is relative to the size of `zwlr_layer_surface_v1` (according to // The wl_surface size after this commit is:
// the protocol). That is the configure the client acked. // - viewport destination if set
// // - else the logical size of the buffer that will be current attached now
// `last_acked` is the becomes current as part of this commit, // - else existing
// so it is staged consistently with the pending radius/padding above. let size = surface_data
// .cached_state
// Until the client acks a configure there is no defined size, and nothing to check. .get::<ViewportCachedState>()
let Some(size) = surface_data .pending()
.data_map .size()
.get::<Mutex<LayerSurfaceAttributes>>() .or_else(|| {
.and_then(|attrs| { let mut guard = surface_data.cached_state.get::<SurfaceAttributes>();
attrs let attrs = guard.pending();
.lock() match &attrs.buffer {
.unwrap() Some(BufferAssignment::NewBuffer(buffer)) => buffer_dimensions(buffer)
.last_acked .map(|d| d.to_logical(attrs.buffer_scale, attrs.buffer_transform.into())),
.as_ref() _ => None,
.and_then(|configure| configure.state.size) }
}) })
else { .or_else(|| {
surface_data
.data_map
.get::<RendererSurfaceStateUserData>()
.and_then(|state| state.lock().unwrap().surface_size())
});
let Some(size) = size else {
return; return;
}; };