wayland: Phase 65 — prop_get_transient_for via xdg_toplevel->parent

Implement prop_get_transient_for for the Wayland backend by walking the
xdg_surface->toplevel->parent pointer and looking up the corresponding
wl_toplevel_view to return its synthetic WNativeWindow ID.

This ensures dialog windows and other transient toplevels that set a
parent via set_parent() are correctly identified as transients by the
policy layer (wManageWindow sets transient_for / no_miniaturizable /
no_miniaturize_button correctly).

Add a helper wl_find_view_by_xdg_surface() for surface-based lookups.
Smoke test gains a header comment noting Phase 65 is a build-only check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-28 09:29:28 +01:00
parent cc846daeca
commit 9bdf3c058b
2 changed files with 34 additions and 1 deletions

View File

@ -54,6 +54,9 @@
* Phase 64: zxdg_decoration_manager_v1 advertised; new_toplevel_decoration
* listener responds immediately with CLIENT_SIDE mode so clients draw their
* own title bars (no X11 frame rendering in the Wayland path).
* Phase 65: prop_get_transient_for implemented — walks xdg_toplevel->parent
* chain and returns the synthetic WNativeWindow ID of the parent view so
* dialog windows are correctly identified as transients by the policy layer.
*/
#ifdef HAVE_CONFIG_H
@ -202,6 +205,18 @@ wl_find_view_by_id(WNativeWindow id)
return NULL;
}
/* Phase 65: look up the view for a given wlr_xdg_surface pointer. */
static struct wl_toplevel_view *
wl_find_view_by_xdg_surface(struct wlr_xdg_surface *surf)
{
struct wl_toplevel_view *v;
wl_list_for_each(v, &wl_state.toplevel_list, link) {
if (v->xdg_surface == surf)
return v;
}
return NULL;
}
/*
* Phase 46: XDG toplevel title changed — update wwin->wm_instance.
*/
@ -977,7 +992,23 @@ wl_prop_get_wmaker_menu(WNativeWindow win,
}
static WNativeWindow
wl_prop_get_transient_for(WNativeWindow win) { (void)win; return WNATIVE_NONE; }
wl_prop_get_transient_for(WNativeWindow win)
{
/* Phase 65: return the synthetic ID of the parent XDG toplevel, or
* WNATIVE_NONE if this surface has no parent. The wlroots XDG
* implementation stores the parent as xdg_surface->toplevel->parent
* (a wlr_xdg_surface *). We walk the view list to find its ID. */
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v || !v->xdg_surface || !v->xdg_surface->toplevel)
return WNATIVE_NONE;
struct wlr_xdg_surface *parent = v->xdg_surface->toplevel->parent;
if (!parent)
return WNATIVE_NONE;
struct wl_toplevel_view *pv = wl_find_view_by_xdg_surface(parent);
if (!pv)
return WNATIVE_NONE;
return pv->id;
}
static int wl_prop_has_wmaker_menu(WNativeWindow win) { (void)win; return 0; }
static int wl_prop_has_gtk_object_path(WNativeWindow win) { (void)win; return 0; }

View File

@ -50,6 +50,8 @@
# 22. (Phase 64) zxdg_decoration_manager_v1 advertised in global registry;
# compositor logs "xdg-decoration-manager created"; new toplevels receive
# CLIENT_SIDE mode ("decoration mode=client_side" logged).
# 23. (Phase 65) prop_get_transient_for returns parent XDG surface ID for
# dialog windows (build-only check — weston-simple-shm has no transients).
#
# This test grows as wl_backend vtable slots are implemented.
#