systray: force a repaint on icon resize

This commit is contained in:
o9000 2015-06-14 11:21:42 +02:00
parent f5b2de62b6
commit b13540123b
3 changed files with 61 additions and 42 deletions

View file

@ -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() void stop_net()
{ {
//fprintf(stderr, "tint2 : systray stopped\n"); //fprintf(stderr, "tint2 : systray stopped\n");
@ -554,6 +582,9 @@ gboolean reparent_icon(TrayWindow *traywin)
if (nbitem == 2) { if (nbitem == 2) {
int hide = ((data[1] & XEMBED_MAPPED) == 0); int hide = ((data[1] & XEMBED_MAPPED) == 0);
if (hide) { 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"); //fprintf(stderr, "tint2: window refused embedding\n");
//remove_icon(traywin); //remove_icon(traywin);
//XFree(data); //XFree(data);
@ -628,34 +659,26 @@ void remove_icon(TrayWindow *traywin)
panel_refresh = 1; panel_refresh = 1;
} }
void systray_reconfigure_event(TrayWindow *traywin)
void net_message(XClientMessageEvent *e)
{ {
unsigned long opcode; //printf("move tray %d\n", traywin->x);
Window win; XMoveResizeWindow(server.dsp, traywin->parent, traywin->x, traywin->y, traywin->width, traywin->height);
if (traywin->reparented) {
opcode = e->data.l[1]; XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height);
switch (opcode) { // Trigger window repaint
case SYSTEM_TRAY_REQUEST_DOCK: stop_timeout(traywin->render_timeout);
win = e->data.l[2]; traywin->render_timeout = add_timeout(50, 0, systray_render_icon, traywin, &traywin->render_timeout);
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;
} }
panel_refresh = 1;
refresh_systray = 1;
} }
void systray_destroy_event(TrayWindow *traywin)
{
remove_icon(traywin);
}
void systray_render_icon_composited(void* t) 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 // 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; unsigned int border_width;
int xpos, ypos; int xpos, ypos;
unsigned int width, height, depth; 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 (!traywin->reparented) {
if (!reparent_icon(traywin)) if (!reparent_icon(traywin))
return; return;
if (systray_composited) { if (systray_composited) {
// We need to process the events in the main loop first // We need to process the events in the main loop first
stop_timeout(traywin->render_timeout); 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; return;
} }
} }
if (systray_composited) { if (systray_composited) {
if (!traywin->render_timeout) systray_render_icon_composited(traywin);
systray_render_icon_composited(traywin);
} else { } else {
// Trigger window repaint // Trigger window repaint
XClearArea(server.dsp, traywin->parent, 0, 0, traywin->width, traywin->height, True); XClearArea(server.dsp, traywin->parent, 0, 0, traywin->width, traywin->height, True);

View file

@ -85,7 +85,9 @@ gboolean add_icon(Window id);
void remove_icon(TrayWindow *traywin); void remove_icon(TrayWindow *traywin);
void refresh_systray_icon(); 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(); void kde_update_icons();
#endif #endif

View file

@ -831,12 +831,7 @@ void event_configure_notify (Window win)
for (l = systray.list_icons; l ; l = l->next) { for (l = systray.list_icons; l ; l = l->next) {
traywin = (TrayWindow*)l->data; traywin = (TrayWindow*)l->data;
if (traywin->win == win) { if (traywin->win == win) {
//printf("move tray %d\n", traywin->x); systray_reconfigure_event(traywin);
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;
return; return;
} }
} }
@ -1270,7 +1265,7 @@ start:
break; break;
for (it = systray.list_icons; it; it = g_slist_next(it)) { for (it = systray.list_icons; it; it = g_slist_next(it)) {
if (((TrayWindow*)it->data)->win == e.xany.window) { if (((TrayWindow*)it->data)->win == e.xany.window) {
remove_icon((TrayWindow*)it->data); systray_destroy_event((TrayWindow*)it->data);
break; break;
} }
} }
@ -1407,14 +1402,11 @@ start:
default: default:
if (e.type == XDamageNotify+damage_event) { if (e.type == XDamageNotify+damage_event) {
// union needed to avoid strict-aliasing warnings by gcc XDamageNotifyEvent *de = (XDamageNotifyEvent*)&e;
union { XEvent e; XDamageNotifyEvent de; } event_union = {.e=e};
TrayWindow *traywin;
GSList *l; GSList *l;
XDamageNotifyEvent* de = &event_union.de;
for (l = systray.list_icons; l ; l = l->next) { for (l = systray.list_icons; l ; l = l->next) {
traywin = (TrayWindow*)l->data; TrayWindow *traywin = (TrayWindow*)l->data;
if ( traywin->parent == de->drawable ) { if (traywin->parent == de->drawable) {
systray_render_icon(traywin); systray_render_icon(traywin);
break; break;
} }