wayland: implement draw_bevel + render button bg with wTextureRenderImage

Two fixes for button/titlebar bevel consistency:

1. Implement the draw_bevel noop with real light/dim border drawing
   from the WTexSolid colors.

2. Render button backgrounds using wTextureRenderImage with WREL_RAISED
   (same function the titlebar uses). This produces the identical
   2-pixel wrlib bevel (RBevelImage/RBEV_RAISED2) that the titlebar
   gets, ensuring buttons and titlebar match exactly.
This commit is contained in:
lkn 2026-06-25 07:53:41 +02:00
parent 06dd22254d
commit 09b1ed5edf
2 changed files with 46 additions and 17 deletions

View File

@ -936,27 +936,34 @@ wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
uint32_t fg_pixel = 0xFF000000 | ((color >> 16 & 0xFF) << 16) |
((color >> 8 & 0xFF) << 8) | (color & 0xFF);
uint32_t fill_bg = pushed ? fg_pixel : bg_pixel;
uint32_t fill_fg = pushed ? bg_pixel : fg_pixel;
uint32_t *dst = pixman_image_get_data(btn_fb->image);
int dst_stride = pixman_image_get_stride(btn_fb->image) / 4;
for (int y = 0; y < bh; y++)
for (int x = 0; x < bw; x++)
dst[y * dst_stride + x] = fill_bg;
unsigned char bg_r = (bg_pixel >> 16) & 0xFF;
unsigned char bg_g = (bg_pixel >> 8) & 0xFF;
unsigned char bg_b = bg_pixel & 0xFF;
uint32_t hi_c = 0xFF000000 | ((uint32_t)(bg_r + (255-bg_r)/3) << 16) |
((uint32_t)(bg_g + (255-bg_g)/3) << 8) | (bg_b + (255-bg_b)/3);
uint32_t lo_c = 0xFF000000 | ((uint32_t)(bg_r * 2/3) << 16) |
((uint32_t)(bg_g * 2/3) << 8) | (bg_b * 2/3);
uint32_t hi = pushed ? lo_c : hi_c;
uint32_t lo = pushed ? hi_c : lo_c;
for (int x = 0; x < bw; x++) { dst[x] = hi; dst[(bh-1) * dst_stride + x] = lo; }
for (int y = 0; y < bh; y++) { dst[y * dst_stride] = hi; dst[y * dst_stride + bw - 1] = lo; }
/* Render button background with same texture+bevel as titlebar */
RImage *bg_img = wTextureRenderImage(texture, bw, bh,
pushed ? WREL_SUNKEN : WREL_RAISED);
if (bg_img) {
unsigned char *src = bg_img->data;
int has_alpha = (bg_img->format == RRGBAFormat);
for (int y = 0; y < bh && y < bg_img->height; y++) {
for (int x = 0; x < bw && x < bg_img->width; x++) {
int si = (y * bg_img->width + x) * (has_alpha ? 4 : 3);
unsigned char r = src[si], g = src[si+1], b = src[si+2];
unsigned char a = has_alpha ? src[si+3] : 0xFF;
dst[y * dst_stride + x] = ((uint32_t)a << 24) |
((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b;
}
}
RReleaseImage(bg_img);
} else {
uint32_t fill_bg = pushed ? fg_pixel : bg_pixel;
for (int y = 0; y < bh; y++)
for (int x = 0; x < bw; x++)
dst[y * dst_stride + x] = fill_bg;
}
int ix = (bw - icon->width) / 2 + (pushed ? 1 : 0);
int iy = (bh - icon->height) / 2 + (pushed ? 1 : 0);

View File

@ -241,7 +241,29 @@ void wl_noop_manage_all_windows(WScreen *scr, int crash_recovery)
void wl_noop_icon_change_title(WIcon *icon, WWindow *wwin) { wIconChangeTitle(icon, wwin); }void wl_noop_do_kaboom(WScreen *scr, WNativeWindow win, int x, int y)
{ (void)scr; (void)win; (void)x; (void)y; }void wl_noop_draw_bevel(WNativeWindow d, unsigned int width, unsigned int height,
WTexSolid *texture, int relief)
{ (void)d; (void)width; (void)height; (void)texture; (void)relief; }
{
if (relief == WREL_FLAT || !texture)
return;
struct wl_frame_buf *fb = frame_buf_find(d);
if (!fb || !fb->image)
return;
uint32_t *dst = (uint32_t *)pixman_image_get_data(fb->image);
int stride = pixman_image_get_stride(fb->image) / 4;
int w = (int)width, h = (int)height;
uint32_t light = 0xFF000000 | ((uint32_t)texture->light.red >> 8 << 16) |
((uint32_t)texture->light.green >> 8 << 8) |
((uint32_t)texture->light.blue >> 8);
uint32_t dim = 0xFF000000 | ((uint32_t)texture->dim.red >> 8 << 16) |
((uint32_t)texture->dim.green >> 8 << 8) |
((uint32_t)texture->dim.blue >> 8);
if (relief == WREL_RAISED) {
for (int x = 0; x < w; x++) { dst[x] = light; dst[(h-1)*stride+x] = dim; }
for (int y = 0; y < h; y++) { dst[y*stride] = light; dst[y*stride+w-1] = dim; }
} else {
for (int x = 0; x < w; x++) { dst[x] = dim; dst[(h-1)*stride+x] = light; }
for (int y = 0; y < h; y++) { dst[y*stride] = dim; dst[y*stride+w-1] = light; }
}
}
void wl_noop_appmenu_send(WNativeWindow window, int what, int tag)
{ (void)window; (void)what; (void)tag; }