wl_backend: fix background color parsing to support named colors

The color parser only handled #RRGGBB and rgb:XX/XX/XX formats, but
Window Maker backgrounds use X11 named colors (deepskyblue4, black,
tomato4, etc.). Now uses wGetColor() which resolves any color format
through the backend's color lookup.

Also: solid backgrounds now update the scene rect directly (faster,
no buffer allocation needed).
This commit is contained in:
Window Maker 2026-05-24 14:35:50 +02:00
parent 286e588110
commit a62a05bbb7
1 changed files with 27 additions and 37 deletions

View File

@ -203,6 +203,7 @@
#include "../../dock.h" /* WDock (for clip->collapsed) */
#include "../../appicon.h" /* WAppIcon */
#include "../../defaults.h" /* wDefaultsCheckDomains */
#include "../../resources.h" /* wGetColor */
#include "../../menu.h" /* WMenu, WMenuEntry */
#include "../../balloon.h" /* WBalloon */
#include "../../dialog.h" /* WMRestart, WMAbort */
@ -7687,6 +7688,18 @@ static const struct wlr_buffer_impl bg_buffer_impl = {
.end_data_ptr_access = bg_buffer_end_data_ptr_access,
};
static int parse_color_to_rcolor(WScreen *scr, const char *name, RColor *out)
{
WMColorRGB wmc;
if (!name || !wGetColor(scr, name, &wmc))
return 0;
out->red = wmc.red >> 8;
out->green = wmc.green >> 8;
out->blue = wmc.blue >> 8;
out->alpha = 255;
return 1;
}
static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
{
if (!scr || !texture_desc || !wl_state.output)
@ -7712,21 +7725,18 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
if (strcasecmp(type, "solid") == 0 && WMGetPropListItemCount(texpl) >= 2) {
const char *colorstr = WMGetFromPLString(WMGetFromPLArray(texpl, 1));
RColor color = {0x50, 0x50, 0x75, 0xFF};
unsigned int r, g, b;
if (colorstr) {
if (sscanf(colorstr, "#%2x%2x%2x", &r, &g, &b) == 3) {
color.red = r; color.green = g; color.blue = b;
} 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;
}
if (colorstr)
parse_color_to_rcolor(scr, colorstr, &color);
/* For solid colors, just update the scene rect directly */
if (wl_state.bg_rect) {
float c[4] = { color.red/255.0f, color.green/255.0f, color.blue/255.0f, 1.0f };
wlr_scene_rect_set_color(wl_state.bg_rect, c);
wlr_scene_node_set_enabled(&wl_state.bg_rect->node, true);
if (wl_state.bg_image)
wlr_scene_node_set_enabled(&wl_state.bg_image->node, false);
}
bg = RCreateImage(width, height, 0);
if (bg) RClearImage(bg, &color);
WMReleasePropList(texpl);
return;
} else if ((strcasecmp(type, "vgradient") == 0 ||
strcasecmp(type, "hgradient") == 0 ||
strcasecmp(type, "dgradient") == 0) &&
@ -7734,21 +7744,8 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
const char *c1str = WMGetFromPLString(WMGetFromPLArray(texpl, 1));
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) {
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) {
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;
}
}
if (c1str) parse_color_to_rcolor(scr, c1str, &color1);
if (c2str) parse_color_to_rcolor(scr, c2str, &color2);
int style = (type[0] == 'v' || type[0] == 'V') ? RVerticalGradient :
(type[0] == 'h' || type[0] == 'H') ? RHorizontalGradient :
RDiagonalGradient;
@ -7760,18 +7757,11 @@ static void wl_set_desktop_background(WScreen *scr, const char *texture_desc)
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;
}
}
if (cs) parse_color_to_rcolor(scr, cs, &cbuf[ci]);
colors[ci] = &cbuf[ci];
}
colors[ncolors] = NULL;