From 28e699d1b40ac9c428f4f7754a8aed02ef8975b7 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 28 Feb 2026 15:02:10 +0100 Subject: [PATCH] wl_compositor: implement version 7 --- docs/features.md | 2 +- src/ifs/wl_compositor.rs | 7 ++++++- src/ifs/wl_surface.rs | 29 +++++++++++++++++++++++++++++ wire/wl_compositor.txt | 3 +++ wire/wl_surface.txt | 4 ++++ 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/features.md b/docs/features.md index 86b0ba7f..92e3eb2a 100644 --- a/docs/features.md +++ b/docs/features.md @@ -166,7 +166,7 @@ Jay supports the following wayland protocols: | jay_popup_ext_manager_v1 | 1 | | | jay_tray_v1 | 1 | | | org_kde_kwin_server_decoration_manager | 1 | | -| wl_compositor | 6 | | +| wl_compositor | 7 | | | wl_data_device_manager | 4 | | | wl_drm | 2 | | | wl_fixes | 1 | | diff --git a/src/ifs/wl_compositor.rs b/src/ifs/wl_compositor.rs index 439f45db..b205c8da 100644 --- a/src/ifs/wl_compositor.rs +++ b/src/ifs/wl_compositor.rs @@ -69,6 +69,11 @@ impl WlCompositorRequestHandler for WlCompositor { self.client.add_client_obj(®ion)?; Ok(()) } + + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } } global_base!(WlCompositorGlobal, WlCompositor, WlCompositorError); @@ -79,7 +84,7 @@ impl Global for WlCompositorGlobal { } fn version(&self) -> u32 { - 6 + 7 } } diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 82a472cd..af643945 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -218,6 +218,7 @@ pub struct SurfaceBuffer { sync_files: SmallMap, pub release_sync: ReleaseSync, release: Option, + _surface_release: SmallVec<[SurfaceRelease; 1]>, } impl Drop for SurfaceBuffer { @@ -462,6 +463,7 @@ struct PendingState { color_description: Option>>, serial: Option, alpha_mode: Option, + surface_release: SmallVec<[SurfaceRelease; 1]>, } struct AttachedSubsurfaceState { @@ -482,6 +484,7 @@ impl PendingState { self.acquire_point = next.acquire_point.take(); self.release_point = next.release_point.take(); self.explicit_sync = mem::take(&mut next.explicit_sync); + self.surface_release = mem::take(&mut next.surface_release); } macro_rules! opt { ($name:ident) => { @@ -1096,6 +1099,9 @@ impl WlSurfaceRequestHandler for WlSurface { release.committed = true; } self.verify_explicit_sync(pending)?; + if pending.surface_release.is_not_empty() && not_matches!(pending.buffer, Some(Some(_))) { + return Err(WlSurfaceError::SurfaceReleaseWithoutAttach); + } if ext.commit_requested(pending) == CommitAction::ContinueCommit { self.commit_timeline.commit(slf, pending)?; } @@ -1132,6 +1138,15 @@ impl WlSurfaceRequestHandler for WlSurface { self.pending.borrow_mut().offset = (req.x, req.y); Ok(()) } + + fn get_release(&self, req: GetRelease, _slf: &Rc) -> Result<(), Self::Error> { + let cb = Rc::new(WlCallback::new(req.callback, &self.client)); + track!(self.client, cb); + self.client.add_client_obj(&cb)?; + let release = SurfaceRelease { cb }; + self.pending.borrow_mut().surface_release.push(release); + Ok(()) + } } impl WlSurface { @@ -1219,6 +1234,7 @@ impl WlSurface { sync_files: Default::default(), release_sync, release: pending.release_point.take(), + _surface_release: mem::take(&mut pending.surface_release), }; self.buffer.set(Some(Rc::new(surface_buffer))); } else { @@ -2151,6 +2167,8 @@ pub enum WlSurfaceError { PrepareAsyncUpload(#[source] GfxError), #[error("Could not register a commit timeout")] RegisterCommitTimeout(#[source] IoUringError), + #[error("Content update contains release callbacks but no non-null buffer")] + SurfaceReleaseWithoutAttach, } efrom!(WlSurfaceError, ClientError); efrom!(WlSurfaceError, XdgSurfaceError); @@ -2282,3 +2300,14 @@ impl Drop for SyncObjRelease { self.signal(None); } } + +pub struct SurfaceRelease { + cb: Rc, +} + +impl Drop for SurfaceRelease { + fn drop(&mut self) { + self.cb.send_done(0); + let _ = self.cb.client.remove_obj(&*self.cb); + } +} diff --git a/wire/wl_compositor.txt b/wire/wl_compositor.txt index 2a721567..428d1e9b 100644 --- a/wire/wl_compositor.txt +++ b/wire/wl_compositor.txt @@ -5,3 +5,6 @@ request create_surface { request create_region { id: id(wl_region) (new), } + +request release (destructor, since = 7) { +} diff --git a/wire/wl_surface.txt b/wire/wl_surface.txt index 8a7e1d2a..35a4e216 100644 --- a/wire/wl_surface.txt +++ b/wire/wl_surface.txt @@ -64,3 +64,7 @@ event preferred_buffer_scale (since = 6) { event preferred_buffer_transform (since = 6) { transform: u32, } + +request get_release (since = 7) { + callback: id(wl_callback) (new), +}