From f4af1df31e223e12ff0a18f2aaa6c1494c1e44e1 Mon Sep 17 00:00:00 2001 From: lkn Date: Thu, 25 Jun 2026 07:25:54 +0200 Subject: [PATCH] wayland: persist background across VT switch / output re-creation When switching VTs and returning, the DRM output may be destroyed and recreated. Two issues caused the background to revert: 1. pending_background was freed after first application, so subsequent output creation had nothing to reapply. 2. A new bg_rect (default purple) was created for each new output and rendered on top of the existing bg_image scene buffer. Fix: keep pending_background permanently, and disable the new bg_rect when a background image is already active in the scene graph. --- src/backend/wayland/wl_background.c | 10 +++++++--- src/backend/wayland/wl_output.c | 7 +++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/backend/wayland/wl_background.c b/src/backend/wayland/wl_background.c index 70dd22b..7e9712d 100644 --- a/src/backend/wayland/wl_background.c +++ b/src/backend/wayland/wl_background.c @@ -75,13 +75,17 @@ static int parse_color_to_rcolor(WScreen *scr, const char *name, RColor *out) { if (!scr || !texture_desc) return; - if (!wl_state.output) { - /* Output not ready yet — cache the background for later */ + + /* Always keep the texture description for output re-creation (VT switch) */ + if (!wl_state.pending_background || + strcmp(wl_state.pending_background, texture_desc) != 0) { wfree(wl_state.pending_background); wl_state.pending_background = wstrdup(texture_desc); - return; } + if (!wl_state.output) + return; + int width = scr->scr_width > 0 ? scr->scr_width : wl_state.output->width; int height = scr->scr_height > 0 ? scr->scr_height : wl_state.output->height; diff --git a/src/backend/wayland/wl_output.c b/src/backend/wayland/wl_output.c index 0ba64cf..15a66b0 100644 --- a/src/backend/wayland/wl_output.c +++ b/src/backend/wayland/wl_output.c @@ -165,16 +165,15 @@ handle_backend_new_output(struct wl_listener *listener, void *data) ost->bg_rect = wlr_scene_rect_create( wl_state.level_trees[WL_LAYER_BACKGROUND], (int)output->width, (int)output->height, bg); - wwarning("wl_backend: root background created (%dx%d)", - (int)output->width, (int)output->height); + /* Hide default rect if a background image is already active */ + if (wl_state.bg_image && wl_state.bg_image->node.enabled) + wlr_scene_node_set_enabled(&ost->bg_rect->node, false); } /* Apply any background that was cached before output was ready */ if (wl_state.pending_background && wl_state.scr) { wwarning("wl_backend: applying pending background"); wl_set_desktop_background(wl_state.scr, wl_state.pending_background); - wfree(wl_state.pending_background); - wl_state.pending_background = NULL; } }