app, event_loop: first-frame-committed hook and foreign_toplevel app_id only
Two independent changes, both blockers for a working desktop session through the loginmanager-daemon handoff and the dock's running-app icons. `App::on_first_frame_committed` is a new trait hook fired exactly once, immediately after the very first `wl_surface.commit` of a rendered buffer on the main surface. `AppData` grows a `first_frame_committed: bool`, `draw_frame` now returns whether this call performed that first commit, and `try_run` invokes the hook after the borrows held during the draw are released. Used by the loginmanager-daemon-aware crustace path to signal "ready to be presented" back to the daemon as soon as the GPU has the first frame — the actual present can still be deferred under VT switching (no DRM master yet), but the client-side commit is the right edge for handoff. `toplevel_display_id` in the foreign-toplevel-list handler no longer falls back to `info.title` or `info.identifier` when `info.app_id` is empty. Smithay creates each `ext-foreign-toplevel-list-v1` handle with `app_id = ""` and `init_new_instance` flushes a `done` immediately, so subscribers used to see the protocol-level identifier (a 32-char `Alphanumeric` random token) as the "app id" of every new toplevel — and remained stuck on it whenever the client's real `set_app_id` arrived between done events but the subscribing app's matcher couldn't resolve it to a `.desktop` entry. Returning the raw `app_id` (empty or not) makes that first transient `done` ignorable by the consumer's own empty-string guard; the second `done`, carrying the real app id, is processed normally.
This commit is contained in:
@@ -468,10 +468,16 @@ fn toplevel_display_id(
|
||||
handle: &ExtForeignToplevelHandleV1,
|
||||
) -> String
|
||||
{
|
||||
// Only ever surface the client's `app_id`. The protocol-level
|
||||
// `identifier` is a server-internal random opaque token, not an
|
||||
// app handle; smithay creates the toplevel handle with an empty
|
||||
// `app_id` and `init_new_instance` flushes a `done` immediately,
|
||||
// so apps subscribing through this binding would otherwise see
|
||||
// the random identifier as their "app id" until the client's
|
||||
// real `set_app_id` lands. `title` is also unsuitable — it
|
||||
// changes every time the window's title text updates.
|
||||
let Some( info ) = list.info( handle ) else { return String::new(); };
|
||||
if !info.app_id.is_empty() { return info.app_id; }
|
||||
if !info.title.is_empty() { return info.title; }
|
||||
info.identifier
|
||||
info.app_id
|
||||
}
|
||||
|
||||
impl<A: App> ForeignToplevelListHandler for AppData<A>
|
||||
|
||||
Reference in New Issue
Block a user