all repos — tint2 @ b13540123b070b081f9daab50f1fd992f71f5754

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

systray: force a repaint on icon resize
o9000 o9000
commit

b13540123b070b081f9daab50f1fd992f71f5754

parent

f5b2de62b652141949eb9e1eb1e1a3c850cf0eeb

3 files changed, 61 insertions(+), 42 deletions(-)

jump to
M src/systray/systraybar.csrc/systray/systraybar.c

@@ -308,6 +308,34 @@ XSendEvent(server.dsp, server.root_win, False, StructureNotifyMask, (XEvent*)&ev);

} +void net_message(XClientMessageEvent *e) +{ + unsigned long opcode; + Window win; + + opcode = e->data.l[1]; + switch (opcode) { + case SYSTEM_TRAY_REQUEST_DOCK: + win = e->data.l[2]; + if (win) + add_icon(win); + break; + + case SYSTEM_TRAY_BEGIN_MESSAGE: + case SYSTEM_TRAY_CANCEL_MESSAGE: + // we don't show baloons messages. + break; + + default: + if (opcode == server.atom._NET_SYSTEM_TRAY_MESSAGE_DATA) + printf("message from dockapp: %s\n", e->data.b); + else + fprintf(stderr, "SYSTEM_TRAY : unknown message type\n"); + break; + } +} + + void stop_net() { //fprintf(stderr, "tint2 : systray stopped\n");

@@ -554,6 +582,9 @@ if (data) {

if (nbitem == 2) { int hide = ((data[1] & XEMBED_MAPPED) == 0); if (hide) { + // In theory we have to check the embedding with this and remove icons that refuse embedding. + // In practice we have no idea when the other application processes the event and accepts the embed so we cannot check without a race. + // Race can be triggered with PyGtk(2) apps. //fprintf(stderr, "tint2: window refused embedding\n"); //remove_icon(traywin); //XFree(data);

@@ -628,33 +659,25 @@ systray.area.resize = 1;

panel_refresh = 1; } +void systray_reconfigure_event(TrayWindow *traywin) +{ + //printf("move tray %d\n", traywin->x); + XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height); + if (traywin->reparented) { + XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); + // Trigger window repaint + stop_timeout(traywin->render_timeout); + traywin->render_timeout = add_timeout(50, 0, systray_render_icon, traywin, &traywin->render_timeout); + } + panel_refresh = 1; + refresh_systray = 1; +} -void net_message(XClientMessageEvent *e) +void systray_destroy_event(TrayWindow *traywin) { - unsigned long opcode; - Window win; - - opcode = e->data.l[1]; - switch (opcode) { - case SYSTEM_TRAY_REQUEST_DOCK: - win = e->data.l[2]; - if (win) - add_icon(win); - break; - - case SYSTEM_TRAY_BEGIN_MESSAGE: - case SYSTEM_TRAY_CANCEL_MESSAGE: - // we don't show baloons messages. - break; + remove_icon(traywin); +} - default: - if (opcode == server.atom._NET_SYSTEM_TRAY_MESSAGE_DATA) - printf("message from dockapp: %s\n", e->data.b); - else - fprintf(stderr, "SYSTEM_TRAY : unknown message type\n"); - break; - } -} void systray_render_icon_composited(void* t) {

@@ -685,6 +708,8 @@ traywin->render_timeout = NULL;

} { + // We shouldn't have to do this as we already listen for structure notify events. + // But things work fine so why change it. unsigned int border_width; int xpos, ypos; unsigned int width, height, depth;

@@ -816,22 +841,22 @@ return;

} -void systray_render_icon(TrayWindow* traywin) +void systray_render_icon(void* t) { + TrayWindow* traywin = t; if (!traywin->reparented) { if (!reparent_icon(traywin)) return; if (systray_composited) { // We need to process the events in the main loop first stop_timeout(traywin->render_timeout); - traywin->render_timeout = add_timeout(50, 0, systray_render_icon_composited, traywin, &traywin->render_timeout); + traywin->render_timeout = add_timeout(50, 0, systray_render_icon, traywin, &traywin->render_timeout); return; } } if (systray_composited) { - if (!traywin->render_timeout) - systray_render_icon_composited(traywin); + systray_render_icon_composited(traywin); } else { // Trigger window repaint XClearArea(server.dsp, traywin->parent, 0, 0, traywin->width, traywin->height, True);
M src/systray/systraybar.hsrc/systray/systraybar.h

@@ -85,7 +85,9 @@ gboolean add_icon(Window id);

void remove_icon(TrayWindow *traywin); void refresh_systray_icon(); -void systray_render_icon(TrayWindow* traywin); +void systray_render_icon(void *t); +void systray_reconfigure_event(TrayWindow *traywin); +void systray_destroy_event(TrayWindow *traywin); void kde_update_icons(); #endif
M src/tint.csrc/tint.c

@@ -831,12 +831,7 @@ GSList *l;

for (l = systray.list_icons; l ; l = l->next) { traywin = (TrayWindow*)l->data; if (traywin->win == win) { - //printf("move tray %d\n", traywin->x); - XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height); - if (traywin->reparented) - XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); - panel_refresh = 1; - refresh_systray = 1; + systray_reconfigure_event(traywin); return; } }

@@ -1270,7 +1265,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)->win == e.xany.window) { - remove_icon((TrayWindow*)it->data); + systray_destroy_event((TrayWindow*)it->data); break; } }

@@ -1407,14 +1402,11 @@ }

default: if (e.type == XDamageNotify+damage_event) { - // union needed to avoid strict-aliasing warnings by gcc - union { XEvent e; XDamageNotifyEvent de; } event_union = {.e=e}; - TrayWindow *traywin; + XDamageNotifyEvent *de = (XDamageNotifyEvent*)&e; GSList *l; - XDamageNotifyEvent* de = &event_union.de; for (l = systray.list_icons; l ; l = l->next) { - traywin = (TrayWindow*)l->data; - if ( traywin->parent == de->drawable ) { + TrayWindow *traywin = (TrayWindow*)l->data; + if (traywin->parent == de->drawable) { systray_render_icon(traywin); break; }