App: add on_main_frame_committed, called after every main-surface commit
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

A host that hands part of its content to input-transparent subsurfaces has no way to know when the main frame that replaces that content has actually been sent: `view()` runs when the tree is dirty, but the draw can be deferred by a pending frame callback, so a subsurface dropped on the strength of the rebuild alone can vanish a frame before the main paints its replacement. The new hook fires in `draw_frame` right after the main buffer is rendered and committed, before the subsurfaces are reconciled for the same iteration, so the host can retire a subsurface knowing the main frame behind it is already out. `on_first_frame_committed` keeps its one-shot role.
This commit is contained in:
2026-09-10 22:54:27 +02:00
parent c9ae5438f8
commit 87f52565c3
2 changed files with 7 additions and 0 deletions
+6
View File
@@ -561,6 +561,12 @@ pub trait App: 'static
/// presented as soon as my VT becomes active".
fn on_first_frame_committed( &mut self ) {}
/// Called every time a buffer for the main surface has been rendered and
/// committed, before the subsurfaces are reconciled for the same
/// iteration. Lets a host retire or mount a subsurface in the same flush
/// as the main frame it replaces, so the swap lands in one frame.
fn on_main_frame_committed( &mut self ) {}
/// Called when the surface is asked to close (compositor request, titlebar button,
/// layer-shell closed event). Return `true` to allow the application to exit,
/// or `false` to cancel.
+1
View File
@@ -75,6 +75,7 @@ pub( crate ) fn draw_frame<A: App>( data: &mut AppData<A> ) -> bool
data.first_frame_committed = true;
first_commit_now = true;
}
data.app.on_main_frame_committed();
}
for ( _, ss ) in data.secondaries.iter_mut()