From b13540123b070b081f9daab50f1fd992f71f5754 Mon Sep 17 00:00:00 2001 From: o9000 Date: Sun, 14 Jun 2015 11:21:42 +0200 Subject: [PATCH] systray: force a repaint on icon resize --- src/systray/systraybar.c | 81 ++++++++++++++++++++++++++-------------- src/systray/systraybar.h | 4 +- src/tint.c | 18 +++------ 3 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index d8cbe34..d7750cb 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -308,6 +308,34 @@ void start_net() } +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 @@ gboolean reparent_icon(TrayWindow *traywin) 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,34 +659,26 @@ void remove_icon(TrayWindow *traywin) panel_refresh = 1; } - -void net_message(XClientMessageEvent *e) +void systray_reconfigure_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; - - 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; + //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 systray_destroy_event(TrayWindow *traywin) +{ + remove_icon(traywin); +} + + 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 @@ -685,6 +708,8 @@ void systray_render_icon_composited(void* t) } { + // 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 @@ on_systray_error: } -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); diff --git a/src/systray/systraybar.h b/src/systray/systraybar.h index 7fe7879..02fde58 100644 --- a/src/systray/systraybar.h +++ b/src/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 diff --git a/src/tint.c b/src/tint.c index d73e228..cb3bad3 100644 --- a/src/tint.c +++ b/src/tint.c @@ -831,12 +831,7 @@ void event_configure_notify (Window win) 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 @@ start: 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 @@ start: 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; }