From deab6e65b81503046a5b6c72f6574d1706347622 Mon Sep 17 00:00:00 2001 From: paul-dev8 Date: Sun, 22 Mar 2026 22:04:12 -0500 Subject: [PATCH] Update tree.rs In `src/wayland/compositor/tree.rs`, `PrivateSurfaceData::commit()`, when processing children: ```rust for child in children { let is_child_sync = ...; if !is_sync && is_child_sync { // Sync child with non-sync parent: commit child tree Self::commit_sync_surface_tree(&child, ...); } else if is_sync || is_child_sync { // Sync child: merge into parent's transaction let child_tx = std::mem::take(&mut child_data.pending_transaction); child_tx.merge_into(&my_data.pending_transaction); child_data.current_txid.0 = child_data.current_txid.0.wrapping_add(1); } // BUG: No handling for desync child with non-sync parent! // SubsurfaceCachedState.pending().location is never committed. } ``` When both parent and child are desync (the common case for Chrome), neither branch executes. The child's `SubsurfaceCachedState` pending location (set by `set_position`) is never moved to the current state. --- src/wayland/compositor/tree.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/wayland/compositor/tree.rs b/src/wayland/compositor/tree.rs index 798bf356b649..e7778c906ca6 100644 --- a/src/wayland/compositor/tree.rs +++ b/src/wayland/compositor/tree.rs @@ -305,7 +305,16 @@ impl PrivateSurfaceData { let child_tx = std::mem::take(&mut child_data.pending_transaction); child_tx.merge_into(&my_data.pending_transaction); child_data.current_txid.0 = child_data.current_txid.0.wrapping_add(1); - } + } else { ++ // Desync child with non-sync parent: per Wayland protocol spec, ++ // wl_subsurface.set_position "is applied when the parent surface's ++ // wl_surface.commit is called." Commit with None to apply pending ++ // state directly to current (bypassing the transaction queue). ++ // This is safe because desync subsurface buffer state is already ++ // applied on the child's own commit — only SubsurfaceCachedState ++ // (position) has pending changes from set_position. (smithay#1894) ++ child_data.public_data.cached_state.commit(None, dh); + } } my_data .pending_transaction