image-copy: Don't send 0x0 buffer params for cursor capture

Fixes panics in `xdg-desktop-portal-cosmic` when it tries to use cursor
capture, and an application hides the cursor.
This commit is contained in:
Ian Douglas Scott 2026-05-07 15:02:16 -07:00 committed by Ian Douglas Scott
parent 4a8931896f
commit 82dcd9a46a
2 changed files with 18 additions and 4 deletions

View file

@ -64,7 +64,7 @@ use smithay::{
protocol::{wl_shm::Format as ShmFormat, wl_surface::WlSurface}, protocol::{wl_shm::Format as ShmFormat, wl_surface::WlSurface},
}, },
}, },
utils::{Logical, Point, Rectangle, SERIAL_COUNTER, Serial}, utils::{Logical, Point, Rectangle, SERIAL_COUNTER, Serial, Size},
wayland::{ wayland::{
compositor::CompositorHandler, compositor::CompositorHandler,
image_copy_capture::{BufferConstraints, CursorSessionRef}, image_copy_capture::{BufferConstraints, CursorSessionRef},
@ -654,8 +654,13 @@ impl State {
.map(|constraint| constraint.size != geometry.size) .map(|constraint| constraint.size != geometry.size)
.unwrap_or(true) .unwrap_or(true)
{ {
let mut cursor_size = geometry.size;
// Client shouldn't try to allocate 0x0 buffer
if cursor_size == Size::new(0, 0) {
cursor_size = Size::new(1, 1);
}
session.update_constraints(BufferConstraints { session.update_constraints(BufferConstraints {
size: geometry.size, size: cursor_size,
shm: vec![ShmFormat::Argb8888], shm: vec![ShmFormat::Argb8888],
dma: None, dma: None,
}); });
@ -718,8 +723,13 @@ impl State {
.map(|constraint| constraint.size != geometry.size) .map(|constraint| constraint.size != geometry.size)
.unwrap_or(true) .unwrap_or(true)
{ {
let mut cursor_size = geometry.size;
// Client shouldn't try to allocate 0x0 buffer
if cursor_size == Size::new(0, 0) {
cursor_size = Size::new(1, 1);
}
session.update_constraints(BufferConstraints { session.update_constraints(BufferConstraints {
size: geometry.size, size: cursor_size,
shm: vec![ShmFormat::Argb8888], shm: vec![ShmFormat::Argb8888],
dma: None, dma: None,
}); });

View file

@ -753,11 +753,15 @@ pub fn render_cursor_to_buffer(
seat: &Seat<State>, seat: &Seat<State>,
) { ) {
let buffer = frame.buffer(); let buffer = frame.buffer();
let cursor_size = seat let mut cursor_size = seat
.cursor_geometry((0.0, 0.0), state.common.clock.now()) .cursor_geometry((0.0, 0.0), state.common.clock.now())
.map(|(geo, _hotspot)| geo.size) .map(|(geo, _hotspot)| geo.size)
.unwrap_or_else(|| Size::from((64, 64))); .unwrap_or_else(|| Size::from((64, 64)));
let buffer_size = buffer_dimensions(&buffer).unwrap(); let buffer_size = buffer_dimensions(&buffer).unwrap();
// Client shouldn't try to allocate 0x0 buffer
if cursor_size == Size::new(0, 0) {
cursor_size = Size::new(1, 1);
}
if buffer_size != cursor_size { if buffer_size != cursor_size {
let constraints = BufferConstraints { let constraints = BufferConstraints {
size: cursor_size, size: cursor_size,