From 849dcd424db630dcac345874d2bc3665f04276c1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 5 May 2024 13:42:51 +0530 Subject: [PATCH] Wayland: save energy by not rendering "suspended" windows on compositors that support that Note that this breaks kitty on GNOME 45 which has a bug, but it fine on GNOME 46. --- docs/changelog.rst | 2 ++ glfw/wl_window.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4e5befd0e..60b75d07c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -68,6 +68,8 @@ Detailed list of changes - Dont clear selections on erase in screen commands unless the erased region intersects a selection (:iss:`7408`) +- Wayland: save energy by not rendering "suspended" windows on compositors that support that + 0.34.1 [2024-04-19] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/glfw/wl_window.c b/glfw/wl_window.c index dfe869e65..d3786c721 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -761,6 +761,7 @@ static const struct xdg_toplevel_listener xdgToplevelListener = { static void apply_xdg_configure_changes(_GLFWwindow *window) { + bool suspended_changed = false; if (window->wl.pending_state & PENDING_STATE_TOPLEVEL) { uint32_t new_states = window->wl.pending.toplevel_states; int width = window->wl.pending.width; @@ -771,6 +772,10 @@ apply_xdg_configure_changes(_GLFWwindow *window) { window->wl.once.surface_configured = true; } +#ifdef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION + suspended_changed = ((new_states & TOPLEVEL_STATE_SUSPENDED) != (window->wl.current.toplevel_states & TOPLEVEL_STATE_SUSPENDED)); +#endif + if (new_states != window->wl.current.toplevel_states || width != window->wl.current.width || height != window->wl.current.height) { @@ -802,6 +807,12 @@ apply_xdg_configure_changes(_GLFWwindow *window) { inform_compositor_of_window_geometry(window, "configure"); commit_window_surface_if_safe(window); window->wl.pending_state = 0; +#ifdef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION + if (suspended_changed) { + debug("Window occlusion state changed, occluded: %d\n", (window->wl.current.toplevel_states & TOPLEVEL_STATE_SUSPENDED) != 0); + _glfwInputWindowOcclusion(window, window->wl.current.toplevel_states & TOPLEVEL_STATE_SUSPENDED); + } +#endif } typedef union pixel { @@ -1666,6 +1677,9 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowOccluded(_GLFWwindow* window UNUSED) { +#ifdef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION + return (window->wl.current.toplevel_states & TOPLEVEL_STATE_SUSPENDED) != 0; +#endif return false; }