wl_backend: add multi-color gradient support for desktop backgrounds

Added mvgradient/mhgradient/mdgradient handling using wrlib's
RRenderMultiGradient(). This covers presets like 'Sunset' which use
more than 2 color stops.

Also cleaned up color parsing (removed empty else branches) and
removed debug logging.
This commit is contained in:
Window Maker 2026-05-24 14:30:57 +02:00
parent 93587378d9
commit 286e588110
1 changed files with 51 additions and 7 deletions

View File

@ -7692,6 +7692,7 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
if (!scr || !texture_desc || !wl_state.output)
return;
int width = wl_state.output->width;
int height = wl_state.output->height;
@ -7713,10 +7714,15 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
RColor color = {0x50, 0x50, 0x75, 0xFF};
unsigned int r, g, b;
if (colorstr) {
if (sscanf(colorstr, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
if (sscanf(colorstr, "#%2x%2x%2x", &r, &g, &b) == 3) {
color.red = r; color.green = g; color.blue = b;
} else if (sscanf(colorstr, "#%02x%02x%02x", &r, &g, &b) == 3) {
} else if (sscanf(colorstr, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
color.red = r; color.green = g; color.blue = b;
} else {
/* Try XParseColor-style names via wrlib */
RColor parsed;
color = parsed;
}
}
bg = RCreateImage(width, height, 0);
@ -7729,16 +7735,52 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
const char *c2str = WMGetFromPLString(WMGetFromPLArray(texpl, 2));
RColor color1 = {0, 0, 0, 255}, color2 = {0, 0, 0, 255};
unsigned int r, g, b;
if (c1str && sscanf(c1str, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
color1.red = r; color1.green = g; color1.blue = b;
if (c1str) {
if (sscanf(c1str, "#%2x%2x%2x", &r, &g, &b) == 3) {
color1.red = r; color1.green = g; color1.blue = b;
} else if (sscanf(c1str, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
color1.red = r; color1.green = g; color1.blue = b;
}
}
if (c2str && sscanf(c2str, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
color2.red = r; color2.green = g; color2.blue = b;
if (c2str) {
if (sscanf(c2str, "#%2x%2x%2x", &r, &g, &b) == 3) {
color2.red = r; color2.green = g; color2.blue = b;
} else if (sscanf(c2str, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
color2.red = r; color2.green = g; color2.blue = b;
}
}
int style = (type[0] == 'v' || type[0] == 'V') ? RVerticalGradient :
(type[0] == 'h' || type[0] == 'H') ? RHorizontalGradient :
RDiagonalGradient;
bg = RRenderGradient(width, height, &color1, &color2, style);
} else if ((strcasecmp(type, "mvgradient") == 0 ||
strcasecmp(type, "mhgradient") == 0 ||
strcasecmp(type, "mdgradient") == 0) &&
WMGetPropListItemCount(texpl) >= 3) {
int ncolors = WMGetPropListItemCount(texpl) - 1;
RColor **colors = wmalloc((ncolors + 1) * sizeof(RColor *));
RColor *cbuf = wmalloc(ncolors * sizeof(RColor));
unsigned int r, g, b;
int ci;
for (ci = 0; ci < ncolors; ci++) {
const char *cs = WMGetFromPLString(WMGetFromPLArray(texpl, ci + 1));
cbuf[ci] = (RColor){0, 0, 0, 255};
if (cs) {
if (sscanf(cs, "#%2x%2x%2x", &r, &g, &b) == 3) {
cbuf[ci].red = r; cbuf[ci].green = g; cbuf[ci].blue = b;
} else if (sscanf(cs, "rgb:%x/%x/%x", &r, &g, &b) == 3) {
cbuf[ci].red = r; cbuf[ci].green = g; cbuf[ci].blue = b;
}
}
colors[ci] = &cbuf[ci];
}
colors[ncolors] = NULL;
int style = (type[1] == 'v' || type[1] == 'V') ? RVerticalGradient :
(type[1] == 'h' || type[1] == 'H') ? RHorizontalGradient :
RDiagonalGradient;
bg = RRenderMultiGradient(width, height, colors, style);
wfree(cbuf);
wfree(colors);
} else if ((strcasecmp(type, "pixmap") == 0 ||
strcasecmp(type, "spixmap") == 0 ||
strcasecmp(type, "mpixmap") == 0 ||
@ -7774,8 +7816,10 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
WMReleasePropList(texpl);
if (!bg)
if (!bg) {
return;
}
/* Convert RImage to pixman_image and set as scene buffer */
struct wl_bg_buffer *buf = calloc(1, sizeof(*buf));