systray: Cleaned up the code a bit
@@ -126,7 +126,8 @@
void draw_systray(void *obj, cairo_t *c) { if (systray_composited) { - if (render_background) XFreePixmap(server.dsp, render_background); + if (render_background) + XFreePixmap(server.dsp, render_background); render_background = XCreatePixmap(server.dsp, server.root_win, systray.area.width, systray.area.height, server.depth); XCopyArea(server.dsp, systray.area.pix, render_background, server.gc, 0, 0, systray.area.width, systray.area.height, 0, 0); }@@ -163,8 +164,7 @@ sysbar->icons_per_column = (height+sysbar->area.paddingx) / (sysbar->icon_size+sysbar->area.paddingx);
sysbar->marging = height - (sysbar->icons_per_column-1)*(sysbar->icon_size+sysbar->area.paddingx) - sysbar->icon_size; sysbar->icons_per_row = count / sysbar->icons_per_column + (count%sysbar->icons_per_column != 0); systray.area.width = (2 * systray.area.bg->border.width) + (2 * systray.area.paddingxlr) + (sysbar->icon_size * sysbar->icons_per_row) + ((sysbar->icons_per_row-1) * systray.area.paddingx); - } - else { + } else { int width = sysbar->area.width - 2*sysbar->area.bg->border.width - 2*sysbar->area.paddingy; // here icons_per_row always higher than 0 sysbar->icons_per_row = (width+sysbar->area.paddingx) / (sysbar->icon_size+sysbar->area.paddingx);@@ -189,44 +189,42 @@ int start = panel->area.bg->border.width + panel->area.paddingy + systray.area.bg->border.width + systray.area.paddingy + sysbar->marging/2;
if (panel_horizontal) { posy = start; posx = systray.area.posx + systray.area.bg->border.width + systray.area.paddingxlr; - } - else { + } else { posx = start; posy = systray.area.posy + systray.area.bg->border.width + systray.area.paddingxlr; } TrayWindow *traywin; GSList *l; - for (i=1, l = systray.list_icons; l ; i++, l = l->next) { + for (i = 1, l = systray.list_icons; l ; i++, l = l->next) { traywin = (TrayWindow*)l->data; if (traywin->hide) continue; traywin->y = posy; traywin->x = posx; - // printf("systray %d %d : pos %d, %d\n", traywin->id, traywin->tray_id, posx, posy); + // printf("systray %d %d : pos %d, %d\n", traywin->parent, traywin->win, posx, posy); traywin->width = sysbar->icon_size; traywin->height = sysbar->icon_size; if (panel_horizontal) { - if (i % sysbar->icons_per_column) + if (i % sysbar->icons_per_column) { posy += sysbar->icon_size + sysbar->area.paddingx; - else { + } else { posy = start; posx += (sysbar->icon_size + systray.area.paddingx); } - } - else { - if (i % sysbar->icons_per_row) + } else { + if (i % sysbar->icons_per_row) { posx += sysbar->icon_size + systray.area.paddingx; - else { + } else { posx = start; posy += (sysbar->icon_size + systray.area.paddingx); } } // position and size the icon window - XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, traywin->width, traywin->height); - XMoveResizeWindow(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height); + XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height); + XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); } refresh_systray = 1; }@@ -242,10 +240,10 @@ // protocol already started
if (!systray_enabled) stop_net(); return; - } - else + } else { if (!systray_enabled) return; + } Window win = XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN);@@ -330,7 +328,6 @@
gboolean error; int window_error_handler(Display *d, XErrorEvent *e) { - d=d;e=e; error = TRUE; if (e->error_code != BadWindow) { printf("error_handler %d\n", e->error_code);@@ -353,14 +350,12 @@ if (systray.sort == SYSTRAY_SORT_ASCENDING ||
systray.sort == SYSTRAY_SORT_DESCENDING) { XTextProperty name_a, name_b; - if (XGetWMName(server.dsp, traywin_a->tray_id, &name_a) == 0) { + if (XGetWMName(server.dsp, traywin_a->win, &name_a) == 0) { return -1; - } - else if (XGetWMName(server.dsp, traywin_b->tray_id, &name_b) == 0) { + } else if (XGetWMName(server.dsp, traywin_b->win, &name_b) == 0) { XFree(name_a.value); return 1; - } - else { + } else { gint retval = g_ascii_strncasecmp((char*)name_a.value, (char*)name_b.value, -1) * (systray.sort == SYSTRAY_SORT_ASCENDING ? 1 : -1); XFree(name_a.value);@@ -379,7 +374,7 @@ return 0;
} -gboolean add_icon(Window id) +gboolean add_icon(Window win) { TrayWindow *traywin; Panel *panel = systray.area.panel;@@ -393,7 +388,7 @@ int actual_format;
unsigned long nitems; unsigned long bytes_after; unsigned char *prop = 0; - int ret = XGetWindowProperty(server.dsp, id, server.atom._NET_WM_PID, 0, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); + int ret = XGetWindowProperty(server.dsp, win, server.atom._NET_WM_PID, 0, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); if (ret == Success && prop) { pid = prop[1] * 256; pid += prop[0];@@ -404,7 +399,7 @@ // Check if the application leaves behind empty icons
GSList *l; int num_empty_same_pid = 0; for (l = systray.list_icons; l; l = l->next) { - if (((TrayWindow*)l->data)->tray_id == id) + if (((TrayWindow*)l->data)->win == win) return FALSE; if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty) num_empty_same_pid++;@@ -416,18 +411,17 @@ if (num_empty_same_pid > max_num_empty_same_pid) {
for (l = systray.list_icons; l; l = l->next) { if (pid && ((TrayWindow*)l->data)->pid == pid && ((TrayWindow*)l->data)->empty) { num_empty_same_pid++; - fprintf(stderr, "Removing tray icon %lu from misbehaving application with pid=%d\n", ((TrayWindow*)l->data)->tray_id, pid); + fprintf(stderr, "Removing tray icon %lu from misbehaving application with pid=%d\n", ((TrayWindow*)l->data)->win, pid); remove_icon((TrayWindow*)l->data); break; } } } - //printf("add_icon: %d, pid %d, %d\n", id, pid, num_empty_same_pid); + //printf("add_icon: %d, pid %d, %d\n", win, pid, num_empty_same_pid); // Create the parent window that will embed the icon - error = FALSE; XWindowAttributes attr; - if (XGetWindowAttributes(server.dsp, id, &attr) == False) + if (XGetWindowAttributes(server.dsp, win, &attr) == False) return FALSE; unsigned long mask = 0; XSetWindowAttributes set_attr;@@ -443,23 +437,24 @@ } else {
set_attr.background_pixmap = ParentRelative; mask = CWBackPixmap; } - Window parent_window = XCreateWindow(server.dsp, panel->main_win, 0, 0, 30, 30, 0, attr.depth, InputOutput, visual, mask, &set_attr); + Window parent = XCreateWindow(server.dsp, panel->main_win, 0, 0, 30, 30, 0, attr.depth, InputOutput, visual, mask, &set_attr); // Watch for the icon trying to resize itself / closing again + error = FALSE; XErrorHandler old = XSetErrorHandler(window_error_handler); - XSelectInput(server.dsp, id, StructureNotifyMask); + XSelectInput(server.dsp, win, StructureNotifyMask); XSync(server.dsp, False); XSetErrorHandler(old); if (error != FALSE) { fprintf(stderr, "tint2 : cannot add systray icon\n"); - XDestroyWindow(server.dsp, parent_window); + XDestroyWindow(server.dsp, parent); return FALSE; } // Add the icon to the list traywin = g_new0(TrayWindow, 1); - traywin->id = parent_window; - traywin->tray_id = id; + traywin->parent = parent; + traywin->win = win; traywin->hide = hide; traywin->depth = attr.depth; // Reparenting is done at the first paint event when the window is positioned correctly over its empty background,@@ -479,7 +474,7 @@ systray.list_icons = g_slist_prepend(systray.list_icons, traywin);
else systray.list_icons = g_slist_append(systray.list_icons, traywin); systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows); - // printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons)); + // printf("add_icon win %lx, %d\n", win, g_slist_length(systray.list_icons)); // Resize and redraw the systray systray.area.resize = 1;@@ -494,10 +489,11 @@ return TRUE;
Panel* panel = systray.area.panel; + error = FALSE; XErrorHandler old = XSetErrorHandler(window_error_handler); // Reparent - XReparentWindow(server.dsp, traywin->tray_id, traywin->id, 0, 0); + XReparentWindow(server.dsp, traywin->win, traywin->parent, 0, 0); XSync(server.dsp, False); traywin->reparented = 1;@@ -509,14 +505,14 @@ e.xclient.type = ClientMessage;
e.xclient.serial = 0; e.xclient.send_event = True; e.xclient.message_type = server.atom._XEMBED; - e.xclient.window = traywin->id; + e.xclient.window = traywin->parent; e.xclient.format = 32; e.xclient.data.l[0] = CurrentTime; e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY; e.xclient.data.l[2] = 0; - e.xclient.data.l[3] = traywin->id; + e.xclient.data.l[3] = traywin->parent; e.xclient.data.l[4] = 0; - XSendEvent(server.dsp, traywin->tray_id, False, 0xFFFFFF, &e); + XSendEvent(server.dsp, traywin->win, False, 0xFFFFFF, &e); XSync(server.dsp, False); }@@ -528,7 +524,7 @@ unsigned long nbitem, bytes;
unsigned char *data = 0; int ret; - ret = XGetWindowProperty(server.dsp, traywin->tray_id, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data); + ret = XGetWindowProperty(server.dsp, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data); if (ret == Success) { if (data) { if (nbitem == 2) {@@ -546,8 +542,8 @@ }
// Redirect rendering when using compositing if (systray_composited) { - traywin->damage = XDamageCreate(server.dsp, traywin->id, XDamageReportRawRectangles); - XCompositeRedirectWindow(server.dsp, traywin->id, CompositeRedirectManual); + traywin->damage = XDamageCreate(server.dsp, traywin->parent, XDamageReportRawRectangles); + XCompositeRedirectWindow(server.dsp, traywin->parent, CompositeRedirectManual); } XSync(server.dsp, False);@@ -559,9 +555,9 @@ }
// Make the icon visible if (!traywin->hide) - XMapWindow(server.dsp, traywin->tray_id); + XMapWindow(server.dsp, traywin->win); if (!traywin->hide && !panel->is_hidden) - XMapRaised(server.dsp, traywin->id); + XMapRaised(server.dsp, traywin->parent); return TRUE; }@@ -572,9 +568,9 @@ XErrorHandler old;
// remove from our list systray.list_icons = g_slist_remove(systray.list_icons, traywin); - //printf("remove_icon: %d\n", traywin->tray_id); + //printf("remove_icon: %d\n", traywin->win); - XSelectInput(server.dsp, traywin->tray_id, NoEventMask); + XSelectInput(server.dsp, traywin->win, NoEventMask); if (traywin->damage) XDamageDestroy(server.dsp, traywin->damage);@@ -582,9 +578,9 @@ // reparent to root
error = FALSE; old = XSetErrorHandler(window_error_handler); if (!traywin->hide) - XUnmapWindow(server.dsp, traywin->tray_id); - XReparentWindow(server.dsp, traywin->tray_id, server.root_win, 0, 0); - XDestroyWindow(server.dsp, traywin->id); + XUnmapWindow(server.dsp, traywin->win); + XReparentWindow(server.dsp, traywin->win, server.root_win, 0, 0); + XDestroyWindow(server.dsp, traywin->parent); XSync(server.dsp, False); XSetErrorHandler(old); stop_timeout(traywin->render_timeout);@@ -610,13 +606,14 @@
void net_message(XClientMessageEvent *e) { unsigned long opcode; - Window id; + Window win; opcode = e->data.l[1]; switch (opcode) { case SYSTEM_TRAY_REQUEST_DOCK: - id = e->data.l[2]; - if (id) add_icon(id); + win = e->data.l[2]; + if (win) + add_icon(win); break; case SYSTEM_TRAY_BEGIN_MESSAGE:@@ -662,15 +659,20 @@ traywin->render_timeout = NULL;
} int empty = 1; - XImage *ximage = XGetImage(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height, AllPlanes, XYPixmap); + XImage *ximage = XGetImage(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height, AllPlanes, XYPixmap); if (ximage) { XColor color; - int x, y; - for (x = 0; empty && x < traywin->width; x++) { - for (y = 0; empty && y < traywin->height; y++) { - color.pixel = XGetPixel(ximage, x, y); - if (color.pixel != 0) - empty = 0; + if (traywin->width > 0 && traywin->height > 0) { + color.pixel = XGetPixel(ximage, traywin->width/2, traywin->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++) { + color.pixel = XGetPixel(ximage, x, y); + if (color.pixel != 0) + empty = 0; + } } } XFree(ximage);@@ -681,7 +683,7 @@ systray.area.resize = 1;
panel_refresh = 1; systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows); } - //printf("systray_render_icon_now: %d empty %d\n", traywin->tray_id, empty); + //printf("systray_render_icon_now: %d empty %d\n", traywin->win, empty); if (empty) return;@@ -695,19 +697,19 @@ // 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); XRenderPictFormat* f; - if (traywin->depth == 24) + if (traywin->depth == 24) { f = XRenderFindStandardFormat(server.dsp, PictStandardRGB24); - else if (traywin->depth == 32) + } else if (traywin->depth == 32) { f = XRenderFindStandardFormat(server.dsp, PictStandardARGB32); - else { + } else { printf("Strange tray icon found with depth: %d\n", traywin->depth); return; } Picture pict_image; //if (server.real_transparency) - //pict_image = XRenderCreatePicture(server.dsp, traywin->id, f, 0, 0); + //pict_image = XRenderCreatePicture(server.dsp, traywin->parent, f, 0, 0); // reverted Rev 407 because here it's breaking alls icon with systray + xcompmgr - pict_image = XRenderCreatePicture(server.dsp, traywin->tray_id, f, 0, 0); + pict_image = XRenderCreatePicture(server.dsp, traywin->win, f, 0, 0); Picture pict_drawable = XRenderCreatePicture(server.dsp, tmp_pmap, XRenderFindVisualFormat(server.dsp, server.visual32), 0, 0); XRenderComposite(server.dsp, PictOpSrc, pict_image, None, pict_drawable, 0, 0, 0, 0, 0, 0, traywin->width, traywin->height); XRenderFreePicture(server.dsp, pict_image);@@ -756,8 +758,8 @@ if (!traywin->render_timeout)
systray_render_icon_composited(traywin); } else { // Trigger window repaint - XClearArea(server.dsp, traywin->id, 0, 0, traywin->width, traywin->height, True); - XClearArea(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height, True); + XClearArea(server.dsp, traywin->parent, 0, 0, traywin->width, traywin->height, True); + XClearArea(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height, True); } }
@@ -35,8 +35,8 @@
typedef struct { - Window id; - Window tray_id; + Window parent; + Window win; int x, y; int width, height; // TODO: manage icon's show/hide
@@ -831,10 +831,10 @@ TrayWindow *traywin;
GSList *l; for (l = systray.list_icons; l ; l = l->next) { traywin = (TrayWindow*)l->data; - if (traywin->tray_id == win) { + if (traywin->win == win) { //printf("move tray %d\n", traywin->x); - XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, traywin->width, traywin->height); - XMoveResizeWindow(server.dsp, traywin->tray_id, 0, 0, traywin->width, traywin->height); + XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height); + XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); panel_refresh = 1; refresh_systray = 1; return;@@ -1269,7 +1269,7 @@ }
if (e.xany.window == g_tooltip.window || !systray_enabled) break; for (it = systray.list_icons; it; it = g_slist_next(it)) { - if (((TrayWindow*)it->data)->tray_id == e.xany.window) { + if (((TrayWindow*)it->data)->win == e.xany.window) { remove_icon((TrayWindow*)it->data); break; }@@ -1414,7 +1414,7 @@ GSList *l;
XDamageNotifyEvent* de = &event_union.de; for (l = systray.list_icons; l ; l = l->next) { traywin = (TrayWindow*)l->data; - if ( traywin->id == de->drawable ) { + if ( traywin->parent == de->drawable ) { systray_render_icon(traywin); break; }