From 6f31791945880c930b65505abeb04edf2451f23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Sep 2025 13:32:10 +0200 Subject: [PATCH] xwayland: Ignore non-InputOutput children in window_get_client_toplevel InputOnly windows aren't relevant here. E.g. mutter-x11-frames uses GTK4, which creates a 1x1 InputOnly child window, which previously prevented this code from working as intended. v2: (Olivier Fourdan) * Rename output_child -> input_output_child. * Add comment in get_single_input_output_child explaining why we return NULL if input_output_child is already non-NULL. Part-of: --- hw/xwayland/xwayland-window.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index c69b24fc5..db611d247 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -484,6 +484,25 @@ window_is_wm_window(WindowPtr window) return *is_wm_window; } +static WindowPtr +get_single_input_output_child(WindowPtr window) +{ + WindowPtr iter, input_output_child = NULL; + + for (iter = window->firstChild; iter; iter = iter->nextSib) { + if (iter->drawable.class != InputOutput) + continue; + + /* We're looking for a single InputOutput child, bail if there are multiple */ + if (input_output_child) + return NULL; + + input_output_child = iter; + } + + return input_output_child; +} + static WindowPtr window_get_client_toplevel(WindowPtr window) { @@ -492,14 +511,10 @@ window_get_client_toplevel(WindowPtr window) /* If the toplevel window is owned by the window-manager, then the * actual client toplevel window has been reparented to some window-manager * decoration/wrapper windows. In that case recurse by checking the client - * of the first *and only* child of the decoration/wrapper window. + * of the only InputOutput child of the decoration/wrapper window. */ - while (window_is_wm_window(window)) { - if (!window->firstChild || window->firstChild != window->lastChild) - return NULL; /* Should never happen, skip resolution emulation */ - - window = window->firstChild; - } + while (window && window_is_wm_window(window)) + window = get_single_input_output_child(window); return window; }