From 5ef07b9ce9d3a61a83bac71b7d7a16934ce78883 Mon Sep 17 00:00:00 2001 From: Riteo Date: Thu, 26 Sep 2024 10:07:53 +0200 Subject: [PATCH] Wayland: Use suspended event only if supported In a previous PR I made an oversight and checked for the new `suspended` event even on legacy compositors, breaking suspension for them. This patch goes trough the trouble of checking for the xdg_toplevel version and seeing whether we have to use one method or the other. --- .../wayland/display_server_wayland.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 3fbbc263a01..56421609edf 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1219,9 +1219,27 @@ void DisplayServerWayland::process_events() { } else { try_suspend(); } - } else if (!wayland_thread.is_suspended() || wayland_thread.get_reset_frame()) { - // At last, a sign of life! We're no longer suspended. - suspended = false; + } else { + // We have to pick into the Wayland thread to figure out if suspension events + // are supported or if we have to use an heuristic as a fallback. + WaylandThread::WindowState *ws = wayland_thread.wl_surface_get_window_state(wayland_thread.window_get_wl_surface(MAIN_WINDOW_ID)); + ERR_FAIL_NULL(ws); + + struct xdg_toplevel *xdg_toplevel = ws->xdg_toplevel; + if (!xdg_toplevel) { + xdg_toplevel = libdecor_frame_get_xdg_toplevel(ws->libdecor_frame); + } + ERR_FAIL_NULL(xdg_toplevel); + + bool suspend_supported = xdg_toplevel_get_version(xdg_toplevel) >= 6; + + if (suspend_supported) { + suspended = wayland_thread.is_suspended(); + } else { + // Older compositors don't have any way of telling us that a window is + // suspended so we'll kick us out of the suspended state with a frame event. + suspended = !wayland_thread.get_reset_frame(); + } } #ifdef DBUS_ENABLED