diff --git a/src/server/mod.rs b/src/server/mod.rs index f695639..c57f19c 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -851,8 +851,8 @@ impl ServerState { ((event.y() as i32 - win.output_offset.y) as f64 / data.scale_factor) as i32, ); popup.positioner.set_size( - (event.width() as f64 / data.scale_factor) as i32, - (event.height() as f64 / data.scale_factor) as i32, + 1.max((event.width() as f64 / data.scale_factor) as i32), + 1.max((event.height() as f64 / data.scale_factor) as i32), ); popup.popup.reposition(&popup.positioner, 0); } diff --git a/src/server/tests.rs b/src/server/tests.rs index 0269cea..fa3fad2 100644 --- a/src/server/tests.rs +++ b/src/server/tests.rs @@ -2073,6 +2073,31 @@ fn fractional_scale_small_popup() { .expect("Missing popup data"); let pos = &data.popup().positioner_state; 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] diff --git a/testwl/src/lib.rs b/testwl/src/lib.rs index b71c43d..f5ad426 100644 --- a/testwl/src/lib.rs +++ b/testwl/src/lib.rs @@ -1285,9 +1285,9 @@ impl Dispatch for State { client.kill( dh, ProtocolError { - code: xdg_surface::Error::InvalidSize.into(), - object_id: resource.id().protocol_id(), - object_interface: XdgSurface::interface().name.to_string(), + code: xdg_positioner::Error::InvalidInput.into(), + object_id: positioner.id().protocol_id(), + object_interface: XdgPositioner::interface().name.to_string(), message, }, ); @@ -1362,11 +1362,11 @@ impl Default for PositionerState { impl Dispatch for State { fn request( state: &mut Self, - _: &Client, + client: &Client, resource: &XdgPositioner, request: ::Request, _: &(), - _: &DisplayHandle, + handle: &DisplayHandle, _: &mut wayland_server::DataInit<'_, Self>, ) { let hash_map::Entry::Occupied(mut data) = state @@ -1377,6 +1377,22 @@ impl Dispatch for State { }; match request { 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 { x: width, y: height,