diff --git a/src/backend/wayland/wl_icon.c b/src/backend/wayland/wl_icon.c index 8b10afb..08130a9 100644 --- a/src/backend/wayland/wl_icon.c +++ b/src/backend/wayland/wl_icon.c @@ -249,6 +249,67 @@ void wl_clip_icon_paint(WAppIcon *aicon) wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); } +void wl_appicon_paint_dock_dots(WAppIcon *aicon, void *wapp_ptr) +{ + WApplication *wapp = (WApplication *)wapp_ptr; + if (!aicon || !aicon->icon || !aicon->icon->core) + return; + + struct wl_frame_buf *fb = frame_buf_find((WNativeWindow)aicon->icon->core->window); + if (!fb || !fb->image) + return; + + int size = wPreferences.icon_size; + uint32_t *data = (uint32_t *)pixman_image_get_data(fb->image); + int stride = pixman_image_get_stride(fb->image) / 4; + int m = size / 64; + if (m < 1) m = 1; + + /* Docked + not running + has command: draw 3 dots near bottom */ + if (aicon->docked && !aicon->running && aicon->command != NULL) { + int dy = size - (6 * m); + int dots_x[3] = { 4*m, 9*m, 14*m }; + for (int d = 0; d < 3; d++) { + int dx = dots_x[d]; + /* Black shadow (offset +1,+1) */ + for (int row = dy+1; row < dy+1 + 2*m && row < size; row++) + for (int col = dx+1; col < dx+1 + 3*m && col < size; col++) + data[row * stride + col] = 0xFF000000; + /* White dot */ + for (int row = dy; row < dy + 2*m && row < size; row++) + for (int col = dx; col < dx + 3*m && col < size; col++) + data[row * stride + col] = 0xFFFFFFFF; + } + } + +#ifdef HIDDENDOT + if (wapp && wapp->flags.hidden) { + int dy = size - (6 * m); + /* Draw only first dot (7px width) */ + for (int row = dy; row < dy + 2*m && row < size; row++) + for (int col = 0; col < 7 && col < size; col++) + data[row * stride + col] = 0xFFFFFFFF; + } +#else + (void)wapp; +#endif + + /* Launching: stipple (darken every other pixel) */ + if (aicon->launching) { + for (int row = 0; row < size && row < fb->height; row++) { + for (int col = (row & 1); col < size && col < fb->width; col += 2) { + uint32_t px = data[row * stride + col]; + uint32_t r = ((px >> 16) & 0xFF) >> 1; + uint32_t g = ((px >> 8) & 0xFF) >> 1; + uint32_t b = (px & 0xFF) >> 1; + data[row * stride + col] = (px & 0xFF000000) | (r << 16) | (g << 8) | b; + } + } + } + + wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); +} + void wl_drawer_icon_paint(WAppIcon *aicon) { if (!aicon || !aicon->icon || !aicon->icon->core) diff --git a/src/backend/wayland/wl_stubs.c b/src/backend/wayland/wl_stubs.c index e192e68..d30dc8a 100644 --- a/src/backend/wayland/wl_stubs.c +++ b/src/backend/wayland/wl_stubs.c @@ -219,8 +219,8 @@ WScreen *wl_noop_screen_for_window(WNativeWindow window) const char *mask_path, WMNativeCursor *cursor_out) { (void)scr; (void)bitmap_path; (void)mask_path; (void)cursor_out; return 0; } void wl_noop_cursor_free(WMNativeCursor cursor) { (void)cursor; } -void wl_noop_cursor_set(WNativeWindow window, WMNativeCursor cursor) { (void)window; (void)cursor; }void wl_noop_appicon_paint_dock_dots(WAppIcon *aicon, void *wapp) -{ (void)aicon; (void)wapp; } +void wl_noop_cursor_set(WNativeWindow window, WMNativeCursor cursor) { (void)window; (void)cursor; } +void wl_appicon_paint_dock_dots(WAppIcon *aicon, void *wapp); int wl_noop_pixmap_get_size(unsigned long drawable, unsigned int *w, unsigned int *h, unsigned int *depth) { (void)drawable; *w = 0; *h = 0; *depth = 0; return 0; } @@ -497,7 +497,7 @@ const WMBackend wl_backend = { .cursor_free = wl_noop_cursor_free, .cursor_set = wl_noop_cursor_set, .pointer_change_cursor = wl_pointer_change_cursor, - .appicon_paint_dock_dots = wl_noop_appicon_paint_dock_dots, + .appicon_paint_dock_dots = wl_appicon_paint_dock_dots, .pixmap_get_size = wl_noop_pixmap_get_size, .icon_paint_title_bg = wl_noop_icon_paint_title_bg, .icon_select_paint = wl_noop_icon_select_paint,