diff --git a/src/event_loop/run.rs b/src/event_loop/run.rs index cb83288..50fb414 100644 --- a/src/event_loop/run.rs +++ b/src/event_loop/run.rs @@ -643,6 +643,12 @@ pub( crate ) fn try_run( mut app: A ) -> Result<(), RunError> // appeared. Specs are re-queried next frame for drawing. reconcile_overlays( &mut data ); + // Subsurfaces must map with the main surface's first buffer, not a frame later. + if !data.first_frame_committed + { + super::subsurface::reconcile_subsurfaces( &mut data ); + } + // Draw any surface that's configured, dirty, and not already waiting // on a frame callback. The compositor decides our cadence — when no // surface qualifies we just loop back to `dispatch(None)` and sleep. diff --git a/src/event_loop/subsurface.rs b/src/event_loop/subsurface.rs index 6301782..e6d184f 100644 --- a/src/event_loop/subsurface.rs +++ b/src/event_loop/subsurface.rs @@ -285,6 +285,8 @@ pub( crate ) fn reconcile_subsurfaces( data: &mut AppData ) // parent buffer — the cheap per-frame move. for ( parent, wl ) in dirty_parents { + // A bufferless commit is a protocol error on a session-lock surface. + if parent == SubsurfaceParent::Main && !data.first_frame_committed { continue; } arm_parent_frame( data, parent, &wl ); wl.commit(); }