systray: Detect window resizez during composited rendering to prevent crashes
o9000 o9000
1 files changed,
26 insertions(+),
6 deletions(-)
jump to
M
src/systray/systraybar.c
→
src/systray/systraybar.c
@@ -647,6 +647,19 @@ break;
} } +XImage *tintXGetImage(Window win) +{ + unsigned int border_width; + int xpos, ypos; + unsigned int width, height, depth; + Window root; + if (!XGetGeometry(server.dsp, win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) { + fprintf(stderr, "Couldn't get geometry of window!\n"); + return NULL; + } + return XGetImage(server.dsp, win, 0, 0, width, height, AllPlanes, XYPixmap); +} + void systray_render_icon_composited(void* t) { // we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0@@ -676,16 +689,22 @@ traywin->render_timeout = NULL;
} int empty = 1; - XImage *ximage = XGetImage(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height, AllPlanes, XYPixmap); + XImage *ximage = tintXGetImage(traywin->win); if (ximage) { + if (ximage->width != traywin->width || + ximage->height != traywin->height) { + XFree(ximage); + XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); + return; + } XColor color; - if (traywin->width > 0 && traywin->height > 0) { - color.pixel = XGetPixel(ximage, traywin->width/2, traywin->height/2); + if (ximage->width > 0 && ximage->height > 0) { + color.pixel = XGetPixel(ximage, ximage->width/2, ximage->height/2); if (color.pixel != 0) empty = 0; int x, y; - for (x = 0; empty && x < traywin->width; x++) { - for (y = 0; empty && y < traywin->height; y++) { + for (x = 0; empty && x < ximage->width; x++) { + for (y = 0; empty && y < ximage->height; y++) { color.pixel = XGetPixel(ximage, x, y); if (color.pixel != 0) empty = 0;@@ -712,7 +731,7 @@
// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself, // so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as // drawable. If someone knows why it does not work with the traywindow itself, please tell me ;) - Pixmap tmp_pmap = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, 32); + Pixmap tmp_pmap = XCreatePixmap(server.dsp, traywin->win, traywin->width, traywin->height, 32); if (!tmp_pmap) { goto on_error; }@@ -723,6 +742,7 @@ } else if (traywin->depth == 32) {
f = XRenderFindStandardFormat(server.dsp, PictStandardARGB32); } else { printf("Strange tray icon found with depth: %d\n", traywin->depth); + XFreePixmap(server.dsp, tmp_pmap); return; } XRenderPictFormat *f32 = XRenderFindVisualFormat(server.dsp, server.visual32);