wayland: fix clip icon rendering with filled triangle arrows

The clip icon was not rendering properly because:
1. An early return prevented painting when workspaces were not yet
   initialized (moved the check so base tile always paints)
2. The filled triangle arrows (top-right and bottom-left) drawn by
   X11 paintClipButtons were missing entirely

Add pixel-level triangle drawing matching the X11 implementation
geometry: CLIP_BUTTON_SIZE-based sizing with 5px margins.
This commit is contained in:
lkn 2026-06-21 18:12:05 +02:00
parent a3413a8402
commit 0ace31b8a4
1 changed files with 32 additions and 4 deletions

View File

@ -175,8 +175,6 @@ void wl_clip_icon_paint(WAppIcon *aicon)
return;
WScreen *scr = aicon->icon->core->screen_ptr;
if (!scr->workspaces || !scr->workspaces[scr->current_workspace])
return;
/* Paint base tile + icon image */
wl_appicon_paint(aicon);
@ -185,7 +183,8 @@ void wl_clip_icon_paint(WAppIcon *aicon)
if (!fb || !fb->image)
return;
WWorkspace *workspace = scr->workspaces[scr->current_workspace];
WWorkspace *workspace = (scr->workspaces && scr->workspaces[scr->current_workspace])
? scr->workspaces[scr->current_workspace] : NULL;
/* Use aicon->dock to read collapsed state — workspace->clip may be a
* stale freed pointer during wWorkspaceRestoreState (the old clip is
* destroyed before scr->workspaces[i]->clip is reassigned, and we
@ -210,13 +209,42 @@ void wl_clip_icon_paint(WAppIcon *aicon)
WMDrawString(scr->wmscreen, d, color, scr->clip_title_font, tx, 2, ws_number, nlength);
/* Draw workspace name at bottom */
if (wPreferences.show_clip_title) {
if (wPreferences.show_clip_title && workspace) {
int length = strlen(workspace->name);
int ty = size - WMFontHeight(scr->clip_title_font) - 3;
tx = CLIP_BUTTON_SIZE * size / 64;
WMDrawString(scr->wmscreen, d, color, scr->clip_title_font, tx, ty, workspace->name, length);
}
/* Draw clip arrows (filled triangles) matching X11 paintClipButtons */
uint32_t pixel = ((uint32_t)0xFF << 24) |
((uint32_t)WMRedComponentOfColor(color) >> 8 << 16) |
((uint32_t)WMGreenComponentOfColor(color) >> 8 << 8) |
((uint32_t)WMBlueComponentOfColor(color) >> 8);
uint32_t *data = (uint32_t *)pixman_image_get_data(fb->image);
int stride = pixman_image_get_stride(fb->image) / 4;
int pt = CLIP_BUTTON_SIZE * size / 64;
int as = pt - 15;
/* Top-right arrow: vertices (size-5-as,5) (size-6,5) (size-6,4+as) */
for (int row = 5; row <= 4 + as; row++) {
/* Triangle: at row=5 full width, at row=4+as width=1 */
int x0 = size - 6;
int x1 = size - 6 - (row - 5) * as / (as > 0 ? as : 1);
for (int col = x1; col <= x0 && col < size; col++)
if (row < fb->height && col >= 0)
data[row * stride + col] = pixel;
}
/* Bottom-left arrow: vertices (5,size-5-as) (5,size-6) (4+as,size-6) */
for (int row = size - 5 - as; row <= size - 6; row++) {
int progress = row - (size - 5 - as);
int x1 = 5 + progress * as / (as > 0 ? as : 1);
for (int col = 5; col <= x1 && col < size; col++)
if (row >= 0 && row < fb->height)
data[row * stride + col] = pixel;
}
/* Commit updated buffer */
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
}