1
0
Fork 0
forked from wry/wry

wl_compositor: implement version 7

This commit is contained in:
Julian Orth 2026-02-28 15:02:10 +01:00
parent 9b870fb8e2
commit 28e699d1b4
5 changed files with 43 additions and 2 deletions

View file

@ -166,7 +166,7 @@ Jay supports the following wayland protocols:
| jay_popup_ext_manager_v1 | 1 | | | jay_popup_ext_manager_v1 | 1 | |
| jay_tray_v1 | 1 | | | jay_tray_v1 | 1 | |
| org_kde_kwin_server_decoration_manager | 1 | | | org_kde_kwin_server_decoration_manager | 1 | |
| wl_compositor | 6 | | | wl_compositor | 7 | |
| wl_data_device_manager | 4 | | | wl_data_device_manager | 4 | |
| wl_drm | 2 | | | wl_drm | 2 | |
| wl_fixes | 1 | | | wl_fixes | 1 | |

View file

@ -69,6 +69,11 @@ impl WlCompositorRequestHandler for WlCompositor {
self.client.add_client_obj(&region)?; self.client.add_client_obj(&region)?;
Ok(()) Ok(())
} }
fn release(&self, _req: Release, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.client.remove_obj(self)?;
Ok(())
}
} }
global_base!(WlCompositorGlobal, WlCompositor, WlCompositorError); global_base!(WlCompositorGlobal, WlCompositor, WlCompositorError);
@ -79,7 +84,7 @@ impl Global for WlCompositorGlobal {
} }
fn version(&self) -> u32 { fn version(&self) -> u32 {
6 7
} }
} }

View file

@ -218,6 +218,7 @@ pub struct SurfaceBuffer {
sync_files: SmallMap<BufferResvUser, SyncFile, 1>, sync_files: SmallMap<BufferResvUser, SyncFile, 1>,
pub release_sync: ReleaseSync, pub release_sync: ReleaseSync,
release: Option<SyncObjRelease>, release: Option<SyncObjRelease>,
_surface_release: SmallVec<[SurfaceRelease; 1]>,
} }
impl Drop for SurfaceBuffer { impl Drop for SurfaceBuffer {
@ -462,6 +463,7 @@ struct PendingState {
color_description: Option<Option<Rc<ColorDescription>>>, color_description: Option<Option<Rc<ColorDescription>>>,
serial: Option<u64>, serial: Option<u64>,
alpha_mode: Option<AlphaMode>, alpha_mode: Option<AlphaMode>,
surface_release: SmallVec<[SurfaceRelease; 1]>,
} }
struct AttachedSubsurfaceState { struct AttachedSubsurfaceState {
@ -482,6 +484,7 @@ impl PendingState {
self.acquire_point = next.acquire_point.take(); self.acquire_point = next.acquire_point.take();
self.release_point = next.release_point.take(); self.release_point = next.release_point.take();
self.explicit_sync = mem::take(&mut next.explicit_sync); self.explicit_sync = mem::take(&mut next.explicit_sync);
self.surface_release = mem::take(&mut next.surface_release);
} }
macro_rules! opt { macro_rules! opt {
($name:ident) => { ($name:ident) => {
@ -1096,6 +1099,9 @@ impl WlSurfaceRequestHandler for WlSurface {
release.committed = true; release.committed = true;
} }
self.verify_explicit_sync(pending)?; 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 { if ext.commit_requested(pending) == CommitAction::ContinueCommit {
self.commit_timeline.commit(slf, pending)?; self.commit_timeline.commit(slf, pending)?;
} }
@ -1132,6 +1138,15 @@ impl WlSurfaceRequestHandler for WlSurface {
self.pending.borrow_mut().offset = (req.x, req.y); self.pending.borrow_mut().offset = (req.x, req.y);
Ok(()) Ok(())
} }
fn get_release(&self, req: GetRelease, _slf: &Rc<Self>) -> 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 { impl WlSurface {
@ -1219,6 +1234,7 @@ impl WlSurface {
sync_files: Default::default(), sync_files: Default::default(),
release_sync, release_sync,
release: pending.release_point.take(), release: pending.release_point.take(),
_surface_release: mem::take(&mut pending.surface_release),
}; };
self.buffer.set(Some(Rc::new(surface_buffer))); self.buffer.set(Some(Rc::new(surface_buffer)));
} else { } else {
@ -2151,6 +2167,8 @@ pub enum WlSurfaceError {
PrepareAsyncUpload(#[source] GfxError), PrepareAsyncUpload(#[source] GfxError),
#[error("Could not register a commit timeout")] #[error("Could not register a commit timeout")]
RegisterCommitTimeout(#[source] IoUringError), RegisterCommitTimeout(#[source] IoUringError),
#[error("Content update contains release callbacks but no non-null buffer")]
SurfaceReleaseWithoutAttach,
} }
efrom!(WlSurfaceError, ClientError); efrom!(WlSurfaceError, ClientError);
efrom!(WlSurfaceError, XdgSurfaceError); efrom!(WlSurfaceError, XdgSurfaceError);
@ -2282,3 +2300,14 @@ impl Drop for SyncObjRelease {
self.signal(None); self.signal(None);
} }
} }
pub struct SurfaceRelease {
cb: Rc<WlCallback>,
}
impl Drop for SurfaceRelease {
fn drop(&mut self) {
self.cb.send_done(0);
let _ = self.cb.client.remove_obj(&*self.cb);
}
}

View file

@ -5,3 +5,6 @@ request create_surface {
request create_region { request create_region {
id: id(wl_region) (new), id: id(wl_region) (new),
} }
request release (destructor, since = 7) {
}

View file

@ -64,3 +64,7 @@ event preferred_buffer_scale (since = 6) {
event preferred_buffer_transform (since = 6) { event preferred_buffer_transform (since = 6) {
transform: u32, transform: u32,
} }
request get_release (since = 7) {
callback: id(wl_callback) (new),
}