diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 889e6fad1fc..e71ae1080db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -224,7 +224,7 @@ jobs: env: PKG_CONFIG_PATH: "${{ github.workspace }}/wayland-install/lib/x86_64-linux-gnu/pkgconfig" LD_LIBRARY_PATH: "${{ github.workspace }}/wayland-install/lib/x86_64-linux-gnu" - run: cargo test -p wayland-tests --features client_system,libwayland_client_1_23 + run: cargo test -p wayland-tests --features client_system,libwayland_client_1_23,libwayland_server_1_23 check-redox: needs: @@ -338,7 +338,7 @@ jobs: fail-fast: false matrix: client_feature: ["libwayland_client_1_23", "client_system"] - server_feature: ["libwayland_server_1_22", "server_system", "server_system,libwayland_server_1_22"] + server_feature: ["libwayland_server_1_23", "server_system", "server_system,libwayland_server_1_22"] steps: - name: Checkout sources diff --git a/wayland-backend/CHANGELOG.md b/wayland-backend/CHANGELOG.md index fcafe37a9b4..6de0ebbff5e 100644 --- a/wayland-backend/CHANGELOG.md +++ b/wayland-backend/CHANGELOG.md @@ -6,6 +6,8 @@ - client: Added `display_ptr` method to `ObjectId` - server: Addded `Handle::global_name` * Requires `libwayland_server_1_22` feature +- client: Added `set_max_buffer_size` method +- server: Added `set_default_max_buffer_size` and `set_max_buffer_size` methods ## 0.3.12 -- 2025-12-30 diff --git a/wayland-backend/Cargo.toml b/wayland-backend/Cargo.toml index ae004b01fdb..d1a4c74b3c1 100644 --- a/wayland-backend/Cargo.toml +++ b/wayland-backend/Cargo.toml @@ -53,7 +53,9 @@ scoped-tls = "1.0" client_system = ["wayland-sys/client", "dep:scoped-tls"] server_system = ["wayland-sys/server", "dep:scoped-tls"] dlopen = ["wayland-sys/dlopen"] +libwayland_client_1_23 = ["wayland-sys/libwayland_client_1_23"] libwayland_server_1_22 = ["wayland-sys/libwayland_server_1_22"] +libwayland_server_1_23 = ["wayland-sys/libwayland_server_1_23", "libwayland_server_1_22"] [package.metadata.docs.rs] all-features = true diff --git a/wayland-backend/src/client_api.rs b/wayland-backend/src/client_api.rs index 5c817595e04..52167d413da 100644 --- a/wayland-backend/src/client_api.rs +++ b/wayland-backend/src/client_api.rs @@ -297,6 +297,12 @@ impl Backend { pub fn dispatch_inner_queue(&self) -> Result { self.backend.dispatch_inner_queue() } + + /// Set maximum buffer size for connection + #[cfg(feature = "libwayland_client_1_23")] + pub fn set_max_buffer_size(&self, max_buffer_size: Option) { + self.backend.set_max_buffer_size(max_buffer_size); + } } /// Guard for synchronizing event reading across multiple threads diff --git a/wayland-backend/src/rs/client_impl/mod.rs b/wayland-backend/src/rs/client_impl/mod.rs index 0bed8ebbf9d..90f3f964662 100644 --- a/wayland-backend/src/rs/client_impl/mod.rs +++ b/wayland-backend/src/rs/client_impl/mod.rs @@ -150,7 +150,7 @@ impl InnerBackend { } pub fn connect(stream: UnixStream) -> Result { - let socket = BufferedSocket::new(Socket::from(stream), true); + let socket = BufferedSocket::new(Socket::from(stream), None); let mut map = ObjectMap::new(); map.insert_at( 1, @@ -527,6 +527,12 @@ impl InnerBackend { pub fn dispatch_inner_queue(&self) -> Result { Ok(0) } + + #[allow(dead_code)] + pub fn set_max_buffer_size(&self, max_buffer_size: Option) { + let mut guard = self.state.lock_protocol(); + guard.socket.set_max_buffer_size(max_buffer_size); + } } impl ProtocolState { diff --git a/wayland-backend/src/rs/mod.rs b/wayland-backend/src/rs/mod.rs index da6d0b68953..77ca03035df 100644 --- a/wayland-backend/src/rs/mod.rs +++ b/wayland-backend/src/rs/mod.rs @@ -7,6 +7,9 @@ mod map; pub(crate) mod socket; mod wire; +// Matches `WL_BUFFER_DEFAULT_MAX_SIZE` in `libwayland` +pub(crate) const DEFAULT_MAX_BUFFER_SIZE: usize = 4096; + /// Client-side rust implementation of a Wayland protocol backend /// /// The main entrypoint is the [`Backend::connect()`][client::Backend::connect()] method. diff --git a/wayland-backend/src/rs/server_impl/client.rs b/wayland-backend/src/rs/server_impl/client.rs index 9f6b232bb29..d3ec7b00321 100644 --- a/wayland-backend/src/rs/server_impl/client.rs +++ b/wayland-backend/src/rs/server_impl/client.rs @@ -46,7 +46,7 @@ pub(crate) enum DisplayError { #[derive(Debug)] pub(crate) struct Client { - socket: BufferedSocket, + pub(crate) socket: BufferedSocket, pub(crate) map: ObjectMap>, debug: bool, last_serial: u32, @@ -68,8 +68,9 @@ impl Client { id: InnerClientId, debug: bool, data: Arc, + buffer_size: usize, ) -> Self { - let socket = BufferedSocket::new(Socket::from(stream), false); + let socket = BufferedSocket::new(Socket::from(stream), Some(buffer_size)); let mut map = ObjectMap::new(); map.insert_at( 1, @@ -709,6 +710,7 @@ impl ClientStore { &mut self, stream: UnixStream, data: Arc, + buffer_size: usize, ) -> InnerClientId { let serial = self.next_serial(); // Find the next free place @@ -722,7 +724,7 @@ impl ClientStore { let id = InnerClientId { id: id as u32, serial }; - *place = Some(Client::new(stream, id.clone(), self.debug, data)); + *place = Some(Client::new(stream, id.clone(), self.debug, data, buffer_size)); id } diff --git a/wayland-backend/src/rs/server_impl/common_poll.rs b/wayland-backend/src/rs/server_impl/common_poll.rs index 83b279a9df7..c234b67f053 100644 --- a/wayland-backend/src/rs/server_impl/common_poll.rs +++ b/wayland-backend/src/rs/server_impl/common_poll.rs @@ -10,7 +10,7 @@ use super::{ use crate::{ core_interfaces::{WL_DISPLAY_INTERFACE, WL_REGISTRY_INTERFACE}, protocol::{same_interface, Argument, Message}, - rs::map::Object, + rs::{map::Object, DEFAULT_MAX_BUFFER_SIZE}, types::server::InitError, }; @@ -326,6 +326,13 @@ impl InnerBackend { } Ok(dispatched) } + + #[allow(dead_code)] + pub fn set_default_max_buffer_size(&self, size: usize) { + let size = + size.checked_next_power_of_two().unwrap_or(usize::MAX).max(DEFAULT_MAX_BUFFER_SIZE); + self.state.lock().unwrap().default_max_buffer_size = size; + } } enum DispatchAction { diff --git a/wayland-backend/src/rs/server_impl/handle.rs b/wayland-backend/src/rs/server_impl/handle.rs index 73c05ed68a7..6b0566c8a02 100644 --- a/wayland-backend/src/rs/server_impl/handle.rs +++ b/wayland-backend/src/rs/server_impl/handle.rs @@ -9,6 +9,7 @@ use std::{ use crate::{ protocol::{same_interface, Interface, Message, ObjectInfo, ANONYMOUS_INTERFACE}, + rs::DEFAULT_MAX_BUFFER_SIZE, types::server::{DisconnectReason, GlobalInfo, InvalidId}, }; @@ -25,6 +26,7 @@ pub struct State { pub(crate) registry: Registry, pub(crate) pending_destructors: Vec>, pub(crate) poll_fd: OwnedFd, + pub(crate) default_max_buffer_size: usize, } impl State { @@ -36,6 +38,7 @@ impl State { registry: Registry::new(), pending_destructors: Vec::new(), poll_fd, + default_max_buffer_size: DEFAULT_MAX_BUFFER_SIZE, } } @@ -70,6 +73,12 @@ impl State { Ok(()) } } + + fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize) { + if let Ok(client) = self.clients.get_client_mut(client) { + client.socket.set_max_buffer_size(Some(max_buffer_size)); + } + } } #[derive(Clone)] @@ -281,6 +290,11 @@ impl InnerHandle { pub fn flush(&mut self, client: Option) -> std::io::Result<()> { self.state.lock().unwrap().flush(client) } + + #[allow(dead_code)] + pub fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize) { + self.state.lock().unwrap().set_max_buffer_size(client, max_buffer_size) + } } pub(crate) trait ErasedState: downcast_rs::Downcast { @@ -315,6 +329,7 @@ pub(crate) trait ErasedState: downcast_rs::Downcast { fn global_info(&self, id: InnerGlobalId) -> Result; fn global_name(&self, global: InnerGlobalId, client: InnerClientId) -> Option; fn flush(&mut self, client: Option) -> std::io::Result<()>; + fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize); } downcast_rs::impl_downcast!(ErasedState); @@ -329,7 +344,7 @@ impl ErasedState for State { stream: UnixStream, data: Arc, ) -> std::io::Result { - let id = self.clients.create_client(stream, data); + let id = self.clients.create_client(stream, data, self.default_max_buffer_size); let client = self.clients.get_client(id.clone()).unwrap(); // register the client to the internal epoll @@ -474,4 +489,8 @@ impl ErasedState for State { fn flush(&mut self, client: Option) -> std::io::Result<()> { self.flush(client) } + + fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize) { + self.set_max_buffer_size(client, max_buffer_size) + } } diff --git a/wayland-backend/src/rs/socket.rs b/wayland-backend/src/rs/socket.rs index 3b19a312bae..65d84ee780e 100644 --- a/wayland-backend/src/rs/socket.rs +++ b/wayland-backend/src/rs/socket.rs @@ -14,6 +14,7 @@ use rustix::net::{ }; use crate::protocol::{ArgumentType, Message}; +use crate::rs::DEFAULT_MAX_BUFFER_SIZE; use super::wire::{parse_message, write_to_buffers, MessageParseError, MessageWriteError}; @@ -134,19 +135,19 @@ pub struct BufferedSocket { in_fds: VecDeque, out_data: Buffer, out_fds: Vec, - unbounded: bool, + max_buffer_size: Option, } impl BufferedSocket { /// Wrap a Socket into a Buffered Socket - pub fn new(socket: Socket, unbounded: bool) -> Self { + pub fn new(socket: Socket, max_buffer_size: Option) -> Self { Self { socket, - in_data: Buffer::new(2 * MAX_BYTES_OUT), // Incoming buffers are twice as big in order to be - in_fds: VecDeque::new(), // able to store leftover data if needed - out_data: Buffer::new(MAX_BYTES_OUT), + in_data: Buffer::new(DEFAULT_MAX_BUFFER_SIZE), + in_fds: VecDeque::new(), + out_data: Buffer::new(DEFAULT_MAX_BUFFER_SIZE), out_fds: Vec::new(), - unbounded, + max_buffer_size, } } @@ -217,7 +218,7 @@ impl BufferedSocket { } Err(MessageWriteError::BufferTooSmall) => { self.out_fds.truncate(fds_len); - if !self.unbounded { + if self.max_buffer_size.is_some_and(|s| s <= self.out_data.storage.len()) { return Ok(false); } self.out_data.increase_capacity(); @@ -307,6 +308,11 @@ impl BufferedSocket { Ok(msg) } + + pub fn set_max_buffer_size(&mut self, max_buffer_size: Option) { + // TODO: what if it decreases? + self.max_buffer_size = max_buffer_size; + } } impl AsRawFd for BufferedSocket { @@ -437,8 +443,8 @@ mod tests { }; let (client, server) = ::std::os::unix::net::UnixStream::pair().unwrap(); - let mut client = BufferedSocket::new(Socket::from(client), false); - let mut server = BufferedSocket::new(Socket::from(server), false); + let mut client = BufferedSocket::new(Socket::from(client), Some(DEFAULT_MAX_BUFFER_SIZE)); + let mut server = BufferedSocket::new(Socket::from(server), Some(DEFAULT_MAX_BUFFER_SIZE)); client.write_message(&msg).unwrap(); client.flush().unwrap(); @@ -481,8 +487,8 @@ mod tests { }; let (client, server) = ::std::os::unix::net::UnixStream::pair().unwrap(); - let mut client = BufferedSocket::new(Socket::from(client), false); - let mut server = BufferedSocket::new(Socket::from(server), false); + let mut client = BufferedSocket::new(Socket::from(client), Some(DEFAULT_MAX_BUFFER_SIZE)); + let mut server = BufferedSocket::new(Socket::from(server), Some(DEFAULT_MAX_BUFFER_SIZE)); client.write_message(&msg).unwrap(); client.flush().unwrap(); @@ -540,8 +546,8 @@ mod tests { ]; let (client, server) = ::std::os::unix::net::UnixStream::pair().unwrap(); - let mut client = BufferedSocket::new(Socket::from(client), false); - let mut server = BufferedSocket::new(Socket::from(server), false); + let mut client = BufferedSocket::new(Socket::from(client), Some(DEFAULT_MAX_BUFFER_SIZE)); + let mut server = BufferedSocket::new(Socket::from(server), Some(DEFAULT_MAX_BUFFER_SIZE)); for msg in &messages { client.write_message(msg).unwrap(); @@ -579,8 +585,8 @@ mod tests { }; let (client, server) = ::std::os::unix::net::UnixStream::pair().unwrap(); - let mut client = BufferedSocket::new(Socket::from(client), false); - let mut server = BufferedSocket::new(Socket::from(server), false); + let mut client = BufferedSocket::new(Socket::from(client), Some(DEFAULT_MAX_BUFFER_SIZE)); + let mut server = BufferedSocket::new(Socket::from(server), Some(DEFAULT_MAX_BUFFER_SIZE)); client.write_message(&msg).unwrap(); client.flush().unwrap(); diff --git a/wayland-backend/src/server_api.rs b/wayland-backend/src/server_api.rs index b7b60b65796..97734dc9192 100644 --- a/wayland-backend/src/server_api.rs +++ b/wayland-backend/src/server_api.rs @@ -521,6 +521,12 @@ impl Handle { pub fn flush(&mut self, client: Option) -> std::io::Result<()> { self.handle.flush(client) } + + /// Set maximum buffer size for client. + #[cfg(feature = "libwayland_server_1_23")] + pub fn set_max_buffer_size(&mut self, client: ClientId, max_buffer_size: usize) { + self.handle.set_max_buffer_size(client.id, max_buffer_size); + } } /// A backend object that represents the state of a wayland server. @@ -603,6 +609,14 @@ impl Backend { pub fn dispatch_all_clients(&mut self, data: &mut D) -> std::io::Result { self.backend.dispatch_all_clients(data) } + + /// Set default client max buffer size. + /// + /// This method will only affect connections created after the method call. + #[cfg(feature = "libwayland_server_1_23")] + pub fn set_default_max_buffer_size(&mut self, max_buffer_size: usize) { + self.backend.set_default_max_buffer_size(max_buffer_size); + } } // Workaround: Some versions of rustc throw a `struct is never constructed`-warning here, diff --git a/wayland-backend/src/sys/client_impl/mod.rs b/wayland-backend/src/sys/client_impl/mod.rs index afeb77b052a..72f70b8cd77 100644 --- a/wayland-backend/src/sys/client_impl/mod.rs +++ b/wayland-backend/src/sys/client_impl/mod.rs @@ -319,6 +319,19 @@ impl InnerBackend { pub fn dispatch_inner_queue(&self) -> Result { self.inner.dispatch_lock.lock().unwrap().dispatch_pending(self.inner.clone()) } + + #[cfg(feature = "libwayland_client_1_23")] + pub fn set_max_buffer_size(&self, max_buffer_size: Option) { + let guard = self.lock_state(); + unsafe { + ffi_dispatch!( + wayland_client_handle(), + wl_display_set_max_buffer_size, + guard.display, + max_buffer_size.unwrap_or(0) + ) + } + } } impl ConnectionState { diff --git a/wayland-backend/src/sys/server_impl/mod.rs b/wayland-backend/src/sys/server_impl/mod.rs index b8240af5147..0187164ac68 100644 --- a/wayland-backend/src/sys/server_impl/mod.rs +++ b/wayland-backend/src/sys/server_impl/mod.rs @@ -424,6 +424,18 @@ impl InnerBackend { Ok(ret as usize) } } + + #[cfg(feature = "libwayland_server_1_23")] + pub fn set_default_max_buffer_size(&mut self, max_buffer_size: usize) { + unsafe { + ffi_dispatch!( + wayland_server_handle(), + wl_display_set_default_max_buffer_size, + self.display_ptr, + max_buffer_size + ); + } + } } impl Drop for State { @@ -841,6 +853,11 @@ impl InnerHandle { self.state.lock().unwrap().flush(client) } + #[cfg(feature = "libwayland_server_1_23")] + pub fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize) { + self.state.lock().unwrap().set_max_buffer_size(client, max_buffer_size) + } + pub fn display_ptr(&self) -> *mut wl_display { self.state.lock().unwrap().display_ptr() } @@ -880,6 +897,8 @@ pub(crate) trait ErasedState: downcast_rs::Downcast { fn global_name(&self, global: InnerGlobalId, client: InnerClientId) -> Option; fn is_known_global(&self, global_ptr: *const wl_global) -> bool; fn flush(&mut self, client: Option) -> std::io::Result<()>; + #[cfg(feature = "libwayland_server_1_23")] + fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize); fn display_ptr(&self) -> *mut wl_display; } @@ -1305,6 +1324,20 @@ impl ErasedState for State { Ok(()) } + #[cfg(feature = "libwayland_server_1_23")] + fn set_max_buffer_size(&mut self, client: InnerClientId, max_buffer_size: usize) { + if client.alive.load(Ordering::Acquire) { + unsafe { + ffi_dispatch!( + wayland_server_handle(), + wl_client_set_max_buffer_size, + client.ptr, + max_buffer_size + ) + } + } + } + fn display_ptr(&self) -> *mut wl_display { self.display } diff --git a/wayland-backend/src/test/protocol_error.rs b/wayland-backend/src/test/protocol_error.rs index af0a5859753..992e975248a 100644 --- a/wayland-backend/src/test/protocol_error.rs +++ b/wayland-backend/src/test/protocol_error.rs @@ -3,7 +3,10 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::rs::socket::{BufferedSocket, Socket}; +use crate::rs::{ + socket::{BufferedSocket, Socket}, + DEFAULT_MAX_BUFFER_SIZE, +}; use super::*; @@ -114,7 +117,7 @@ expand_test!(client_wrong_id, { let mut server = server_backend::Backend::<()>::new().unwrap(); let _client_id = server.handle().insert_client(rx, Arc::new(())).unwrap(); - let mut socket = BufferedSocket::new(Socket::from(tx), false); + let mut socket = BufferedSocket::new(Socket::from(tx), Some(DEFAULT_MAX_BUFFER_SIZE)); socket .write_message(&Message { @@ -140,7 +143,7 @@ expand_test!(client_wrong_opcode, { let mut server = server_backend::Backend::<()>::new().unwrap(); let _client_id = server.handle().insert_client(rx, Arc::new(())).unwrap(); - let mut socket = BufferedSocket::new(Socket::from(tx), false); + let mut socket = BufferedSocket::new(Socket::from(tx), Some(DEFAULT_MAX_BUFFER_SIZE)); socket .write_message(&Message { @@ -164,7 +167,7 @@ expand_test!(client_wrong_sender, { let mut server = server_backend::Backend::<()>::new().unwrap(); let _client_id = server.handle().insert_client(rx, Arc::new(())).unwrap(); - let mut socket = BufferedSocket::new(Socket::from(tx), false); + let mut socket = BufferedSocket::new(Socket::from(tx), Some(DEFAULT_MAX_BUFFER_SIZE)); socket .write_message(&Message { @@ -332,7 +335,7 @@ expand_test!(protocol_version_check, { Arc::new(ServerData(object_id.clone())), ); - let mut socket = BufferedSocket::new(Socket::from(tx), false); + let mut socket = BufferedSocket::new(Socket::from(tx), Some(DEFAULT_MAX_BUFFER_SIZE)); socket .write_message(&Message { diff --git a/wayland-client/Cargo.toml b/wayland-client/Cargo.toml index 8811e3a865b..3086acc4008 100644 --- a/wayland-client/Cargo.toml +++ b/wayland-client/Cargo.toml @@ -28,6 +28,7 @@ tempfile = "3.2" [features] system = ["wayland-backend/client_system"] dlopen = ["wayland-backend/dlopen"] +libwayland_1_23 = ["wayland-backend/libwayland_client_1_23"] [package.metadata.docs.rs] all-features = true diff --git a/wayland-server/Cargo.toml b/wayland-server/Cargo.toml index cc2e0e4c1b7..b31b09c517f 100644 --- a/wayland-server/Cargo.toml +++ b/wayland-server/Cargo.toml @@ -24,6 +24,7 @@ rustix = { version = "1.0.2", features = ["fs"] } system = ["wayland-backend/server_system"] dlopen = ["wayland-backend/dlopen"] libwayland_1_22 = ["wayland-backend/libwayland_server_1_22"] +libwayland_1_23 = ["libwayland_1_22", "wayland-backend/libwayland_server_1_23"] [package.metadata.docs.rs] all-features = true diff --git a/wayland-sys/Cargo.toml b/wayland-sys/Cargo.toml index 88933066216..52c859e0600 100644 --- a/wayland-sys/Cargo.toml +++ b/wayland-sys/Cargo.toml @@ -27,7 +27,9 @@ client = ["dep:dlib", "dep:log"] cursor = ["client"] egl = ["client"] server = ["libc", "memoffset", "dep:dlib", "dep:log"] +libwayland_client_1_23 = [] libwayland_server_1_22 = [] +libwayland_server_1_23 = ["libwayland_server_1_22"] [package.metadata.docs.rs] all-features = true diff --git a/wayland-sys/src/client.rs b/wayland-sys/src/client.rs index f2796399875..c14bdf3054f 100644 --- a/wayland-sys/src/client.rs +++ b/wayland-sys/src/client.rs @@ -30,6 +30,8 @@ external_library!(WaylandClient, "wayland-client", fn wl_display_cancel_read(*mut wl_display) -> (), fn wl_display_dispatch(*mut wl_display) -> c_int, fn wl_display_dispatch_pending(*mut wl_display) -> c_int, + #[cfg(feature = "libwayland_client_1_23")] + fn wl_display_set_max_buffer_size(*mut wl_display, usize) -> (), // error handling fn wl_display_get_error(*mut wl_display) -> c_int, fn wl_display_get_protocol_error(*mut wl_display, *mut *const wl_interface, *mut u32) -> u32, diff --git a/wayland-sys/src/server.rs b/wayland-sys/src/server.rs index 03ded560e0c..16f7f04518a 100644 --- a/wayland-sys/src/server.rs +++ b/wayland-sys/src/server.rs @@ -56,6 +56,8 @@ external_library!(WaylandServer, "wayland-server", fn wl_client_add_destroy_listener(*mut wl_client, *mut wl_listener) -> (), fn wl_client_get_destroy_listener(*mut wl_client, wl_notify_func_t) -> *mut wl_listener, fn wl_client_post_no_memory(*mut wl_client) -> (), + #[cfg(feature = "libwayland_server_1_23")] + fn wl_client_set_max_buffer_size(*mut wl_client, usize) -> (), fn wl_resource_create(*mut wl_client, *const wl_interface, c_int, u32) -> *mut wl_resource, fn wl_client_get_link(*mut wl_client) -> *mut wl_list, fn wl_client_from_link(*mut wl_list) -> *mut wl_client, @@ -82,6 +84,8 @@ external_library!(WaylandServer, "wayland-server", fn wl_display_add_client_created_listener(*mut wl_display, *mut wl_listener) -> (), fn wl_display_set_global_filter(*mut wl_display, wl_display_global_filter_func_t, *mut c_void) -> (), fn wl_display_get_client_list(*mut wl_display) -> *mut wl_list, + #[cfg(feature = "libwayland_server_1_23")] + fn wl_display_set_default_max_buffer_size(*mut wl_display, usize) -> (), // wl_event_loop fn wl_event_loop_create() -> *mut wl_event_loop, fn wl_event_loop_destroy(*mut wl_event_loop) -> (), diff --git a/wayland-tests/Cargo.toml b/wayland-tests/Cargo.toml index bcd07e8a97a..c7a92901c2d 100644 --- a/wayland-tests/Cargo.toml +++ b/wayland-tests/Cargo.toml @@ -17,8 +17,9 @@ tempfile = "3" [features] server_system = ["wayland-server/system"] client_system = ["wayland-client/system"] -libwayland_client_1_23 = [] +libwayland_client_1_23 = ["wayland-client/libwayland_1_23"] libwayland_server_1_22 = ["wayland-server/libwayland_1_22"] +libwayland_server_1_23 = ["libwayland_server_1_22", "wayland-server/libwayland_1_23"] [[test]] name = "attach_to_surface" diff --git a/wayland-tests/tests/buffer_size.rs b/wayland-tests/tests/buffer_size.rs index b2f2160c8a8..304aed02347 100644 --- a/wayland-tests/tests/buffer_size.rs +++ b/wayland-tests/tests/buffer_size.rs @@ -101,6 +101,49 @@ fn buffer_size_client() { // roundtrip(&mut client, &mut server, &mut client_ddata, &mut server_handler).unwrap(); } +#[cfg(feature = "libwayland_server_1_23")] +#[test] +fn buffer_size_increase() { + let mut server = TestServer::new(); + server + .display + .handle() + .create_global::(1, ()); + + server.display.backend().set_default_max_buffer_size(1024 * 32); + + let (_, mut client) = server.add_client(); + let mut client_ddata = ClientHandler { globals: globals::GlobalList::new() }; + + let registry = client.display.get_registry(&client.event_queue.handle(), ()); + + let mut server_handler = ServerHandler::default(); + + roundtrip(&mut client, &mut server, &mut client_ddata, &mut server_handler).unwrap(); + + let seat = client_ddata + .globals + .bind::( + &client.event_queue.handle(), + ®istry, + 1..2, + (), + ) + .unwrap(); + + let _pointer = seat.get_pointer(&client.event_queue.handle(), ()); + + roundtrip(&mut client, &mut server, &mut client_ddata, &mut server_handler).unwrap(); + + // Send too many Wayland events to buffer + let server_pointer = server_handler.pointer.as_ref().unwrap().clone(); + for _ in 0..10_000 { + server_pointer.motion(0, 0., 0.); + } + + roundtrip(&mut client, &mut server, &mut client_ddata, &mut server_handler).unwrap(); +} + /* * Client handler */