From 87f52565c361a9b736362cf91c7a4dbefcdd9465 Mon Sep 17 00:00:00 2001 From: "Pedro M. de Echanove Pasquin" Date: Thu, 10 Sep 2026 22:54:27 +0200 Subject: [PATCH] App: add on_main_frame_committed, called after every main-surface commit 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. --- src/app.rs | 6 ++++++ src/event_loop/frame.rs | 1 + 2 files changed, 7 insertions(+) diff --git a/src/app.rs b/src/app.rs index bce75e5..8bf7164 100644 --- a/src/app.rs +++ b/src/app.rs @@ -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. diff --git a/src/event_loop/frame.rs b/src/event_loop/frame.rs index b2ac7cd..657be8e 100644 --- a/src/event_loop/frame.rs +++ b/src/event_loop/frame.rs @@ -75,6 +75,7 @@ pub( crate ) fn draw_frame( data: &mut AppData ) -> bool data.first_frame_committed = true; first_commit_now = true; } + data.app.on_main_frame_committed(); } for ( _, ss ) in data.secondaries.iter_mut()