all repos — tint2 @ 4b50446a7b7301d5a228bbbf2eac67dc17976764

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

Taskbar: thumbnails (use slower but safed XGetImage)
o9000 mrovi9000@gmail.com
commit

4b50446a7b7301d5a228bbbf2eac67dc17976764

parent

e8a6c93b28dc047b9b613a0e74612c30ee838efc

1 files changed, 65 insertions(+), 39 deletions(-)

jump to
M src/util/window.csrc/util/window.c

@@ -371,8 +371,8 @@ const size_t gmask = 0xff00;

const size_t bmask = 0xff; for (size_t i = 0; i < tw * (th - 1) - 1; i++) { u_int32_t c1 = data[i]; - u_int32_t c2 = data[i+1]; - u_int32_t c3 = data[i+tw]; + u_int32_t c2 = data[i + 1]; + u_int32_t c3 = data[i + tw]; u_int32_t b = (6 * (c1 & bmask) + (c2 & bmask) + (c3 & bmask)) / 8; u_int32_t g = (6 * (c1 & gmask) + (c2 & gmask) + (c3 & gmask)) / 8; u_int32_t r = (6 * (c1 & rmask) + (c2 & rmask) + (c3 & rmask)) / 8;

@@ -381,14 +381,15 @@ }

} // This is measured to be slightly faster. -#define GetPixel(ximg, x, y) ((u_int32_t*)&(ximg->data[y * ximg->bytes_per_line]))[x] +#define GetPixel(ximg, x, y) ((u_int32_t *)&(ximg->data[y * ximg->bytes_per_line]))[x] //#define GetPixel XGetPixel -cairo_surface_t *screenshot(Window win, size_t size) +cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean use_shm) { cairo_surface_t *result = NULL; XWindowAttributes wa; - if (!XGetWindowAttributes(server.display, win, &wa) || wa.width <= 0 || wa.height <= 0 || wa.map_state != IsViewable) + if (!XGetWindowAttributes(server.display, win, &wa) || wa.width <= 0 || wa.height <= 0 || + wa.map_state != IsViewable) goto err0; if (window_is_iconified(win))

@@ -412,14 +413,18 @@ ox = oy = 0;

} XShmSegmentInfo shminfo; - XImage *ximg = XShmCreateImage(server.display, - wa.visual, - (unsigned)wa.depth, - ZPixmap, - NULL, - &shminfo, - (unsigned)wa.width, - (unsigned)wa.height); + XImage *ximg; + if (use_shm) + ximg = XShmCreateImage(server.display, + wa.visual, + (unsigned)wa.depth, + ZPixmap, + NULL, + &shminfo, + (unsigned)wa.width, + (unsigned)wa.height); + else + ximg = XGetImage(server.display, win, 0, 0, (unsigned)wa.width, (unsigned)wa.height, AllPlanes, ZPixmap); if (!ximg) { fprintf(stderr, RED "tint2: !ximg" RESET "\n"); goto err0;

@@ -428,24 +433,26 @@ if (ximg->bits_per_pixel != 24 && ximg->bits_per_pixel != 32) {

fprintf(stderr, RED "tint2: unusual bits_per_pixel" RESET "\n"); goto err1; } - shminfo.shmid = shmget(IPC_PRIVATE, (size_t)(ximg->bytes_per_line * ximg->height), IPC_CREAT | 0777); - if (shminfo.shmid < 0) { - fprintf(stderr, RED "tint2: !shmget" RESET "\n"); - goto err1; - } - shminfo.shmaddr = ximg->data = (char *)shmat(shminfo.shmid, 0, 0); - if (!shminfo.shmaddr) { - fprintf(stderr, RED "tint2: !shmat" RESET "\n"); - goto err2; - } - shminfo.readOnly = False; - if (!XShmAttach(server.display, &shminfo)) { - fprintf(stderr, RED "tint2: !xshmattach" RESET "\n"); - goto err3; - } - if (!XShmGetImage(server.display, win, ximg, 0, 0, AllPlanes)) { - fprintf(stderr, RED "tint2: !xshmgetimage" RESET "\n"); - goto err4; + if (use_shm) { + shminfo.shmid = shmget(IPC_PRIVATE, (size_t)(ximg->bytes_per_line * ximg->height), IPC_CREAT | 0777); + if (shminfo.shmid < 0) { + fprintf(stderr, RED "tint2: !shmget" RESET "\n"); + goto err1; + } + shminfo.shmaddr = ximg->data = (char *)shmat(shminfo.shmid, 0, 0); + if (!shminfo.shmaddr) { + fprintf(stderr, RED "tint2: !shmat" RESET "\n"); + goto err2; + } + shminfo.readOnly = False; + if (!XShmAttach(server.display, &shminfo)) { + fprintf(stderr, RED "tint2: !xshmattach" RESET "\n"); + goto err3; + } + if (!XShmGetImage(server.display, win, ximg, 0, 0, AllPlanes)) { + fprintf(stderr, RED "tint2: !xshmgetimage" RESET "\n"); + goto err4; + } } XGetWindowAttributes(server.display, win, &wa);

@@ -530,11 +537,14 @@ // 2nd pass

smooth_thumbnail(result); err4: - XShmDetach(server.display, &shminfo); + if (use_shm) + XShmDetach(server.display, &shminfo); err3: - shmdt(shminfo.shmaddr); + if (use_shm) + shmdt(shminfo.shmaddr); err2: - shmctl(shminfo.shmid, IPC_RMID, NULL); + if (use_shm) + shmctl(shminfo.shmid, IPC_RMID, NULL); err1: XDestroyImage(ximg); err0:

@@ -545,7 +555,8 @@ cairo_surface_t *get_window_thumbnail_cairo(Window win, int size)

{ static cairo_filter_t filter = CAIRO_FILTER_BEST; XWindowAttributes wa; - if (!XGetWindowAttributes(server.display, win, &wa) || wa.width <= 0 || wa.height <= 0 || wa.map_state != IsViewable) + if (!XGetWindowAttributes(server.display, win, &wa) || wa.width <= 0 || wa.height <= 0 || + wa.map_state != IsViewable) return NULL; int w, h; w = wa.width;

@@ -616,13 +627,27 @@ cairo_surface_t *get_window_thumbnail(Window win, int size)

{ cairo_surface_t *image_surface = NULL; if (0 && server.has_shm && server.composite_manager) { - image_surface = screenshot(win, (size_t)size); + image_surface = get_window_thumbnail_ximage(win, (size_t)size, TRUE); + if (image_surface && cairo_surface_is_blank(image_surface)) { + cairo_surface_destroy(image_surface); + image_surface = NULL; + } + if (!image_surface) + fprintf(stderr, YELLOW "tint2: XShmGetImage failed, trying slower method" RESET "\n"); + else + fprintf(stderr, "tint2: captured window using XShmGetImage\n"); + } + + if (!image_surface) { + image_surface = get_window_thumbnail_ximage(win, (size_t)size, FALSE); if (image_surface && cairo_surface_is_blank(image_surface)) { cairo_surface_destroy(image_surface); image_surface = NULL; } if (!image_surface) - fprintf(stderr, YELLOW "tint2: thumbnail fast path failed, trying slow path" RESET "\n"); + fprintf(stderr, YELLOW "tint2: XGetImage failed, trying slower method" RESET "\n"); + else + fprintf(stderr, "tint2: captured window using XGetImage\n"); } if (!image_surface) {

@@ -632,9 +657,10 @@ cairo_surface_destroy(image_surface);

image_surface = NULL; } if (!image_surface) - fprintf(stderr, YELLOW "tint2: thumbnail slow path failed" RESET "\n"); + fprintf(stderr, YELLOW "tint2: capturing window failed" RESET "\n"); + else + fprintf(stderr, "tint2: captured window using cairo\n"); } - if (!image_surface) return NULL;