Don't pass invalid positioner size on popup reconfigure

Mentioned in #144
This commit is contained in:
Shawn Wallace 2025-05-28 22:24:54 -04:00
parent 76ace3c656
commit ae1759077e
3 changed files with 48 additions and 7 deletions

View file

@ -851,8 +851,8 @@ impl<C: XConnection> ServerState<C> {
((event.y() as i32 - win.output_offset.y) as f64 / data.scale_factor) as i32, ((event.y() as i32 - win.output_offset.y) as f64 / data.scale_factor) as i32,
); );
popup.positioner.set_size( popup.positioner.set_size(
(event.width() as f64 / data.scale_factor) as i32, 1.max((event.width() as f64 / data.scale_factor) as i32),
(event.height() as f64 / data.scale_factor) as i32, 1.max((event.height() as f64 / data.scale_factor) as i32),
); );
popup.popup.reposition(&popup.positioner, 0); popup.popup.reposition(&popup.positioner, 0);
} }

View file

@ -2073,6 +2073,31 @@ fn fractional_scale_small_popup() {
.expect("Missing popup data"); .expect("Missing popup data");
let pos = &data.popup().positioner_state; let pos = &data.popup().positioner_state;
assert_eq!(pos.size.unwrap(), testwl::Vec2 { x: 1, y: 1 }); assert_eq!(pos.size.unwrap(), testwl::Vec2 { x: 1, y: 1 });
f.satellite.reconfigure_window(x::ConfigureNotifyEvent::new(
popup,
popup,
x::WINDOW_NONE,
0,
0,
2,
1,
0,
true,
));
f.run();
f.run();
let dims = f.connection().window(popup).dims;
assert!(dims.width > 0);
assert!(dims.height > 0);
let data = f
.testwl
.get_surface_data(popup_id)
.expect("Missing popup data");
let pos = &data.popup().positioner_state;
assert_eq!(pos.size.unwrap(), testwl::Vec2 { x: 1, y: 1 });
} }
#[test] #[test]

View file

@ -1285,9 +1285,9 @@ impl Dispatch<XdgSurface, SurfaceId> for State {
client.kill( client.kill(
dh, dh,
ProtocolError { ProtocolError {
code: xdg_surface::Error::InvalidSize.into(), code: xdg_positioner::Error::InvalidInput.into(),
object_id: resource.id().protocol_id(), object_id: positioner.id().protocol_id(),
object_interface: XdgSurface::interface().name.to_string(), object_interface: XdgPositioner::interface().name.to_string(),
message, message,
}, },
); );
@ -1362,11 +1362,11 @@ impl Default for PositionerState {
impl Dispatch<XdgPositioner, ()> for State { impl Dispatch<XdgPositioner, ()> for State {
fn request( fn request(
state: &mut Self, state: &mut Self,
_: &Client, client: &Client,
resource: &XdgPositioner, resource: &XdgPositioner,
request: <XdgPositioner as Resource>::Request, request: <XdgPositioner as Resource>::Request,
_: &(), _: &(),
_: &DisplayHandle, handle: &DisplayHandle,
_: &mut wayland_server::DataInit<'_, Self>, _: &mut wayland_server::DataInit<'_, Self>,
) { ) {
let hash_map::Entry::Occupied(mut data) = state let hash_map::Entry::Occupied(mut data) = state
@ -1377,6 +1377,22 @@ impl Dispatch<XdgPositioner, ()> for State {
}; };
match request { match request {
xdg_positioner::Request::SetSize { width, height } => { xdg_positioner::Request::SetSize { width, height } => {
if width <= 0 || height <= 0 {
// TODO: figure out why the client.kill here doesn't make satellite print the error message
let message = format!("positioner had an invalid size {width}x{height}");
eprintln!("{message}");
client.kill(
handle,
ProtocolError {
code: xdg_positioner::Error::InvalidInput.into(),
object_id: resource.id().protocol_id(),
object_interface: XdgPositioner::interface().name.to_string(),
message,
},
);
return;
}
data.get_mut().size = Some(Vec2 { data.get_mut().size = Some(Vec2 {
x: width, x: width,
y: height, y: height,