systray: force a repaint on icon resize
This commit is contained in:
parent
f5b2de62b6
commit
b13540123b
3 changed files with 61 additions and 42 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
18
src/tint.c
18
src/tint.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue