Systray: handle changing icon names and reorder if necessary

This commit is contained in:
o9000 2016-01-07 12:50:54 +01:00
parent 29a34083c9
commit 228d20a72c
3 changed files with 81 additions and 37 deletions

View file

@ -506,6 +506,24 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
return 0;
}
void print_icons()
{
fprintf(stderr, "systray.list_icons: \n");
for (GSList *l = systray.list_icons; l; l = l->next) {
TrayWindow *t = l->data;
fprintf(stderr, "%s\n", t->name);
}
fprintf(stderr, "systray.list_icons order: \n");
for (GSList *l = systray.list_icons; l; l = l->next) {
if (l->next) {
TrayWindow *t = l->data;
TrayWindow *u = l->next->data;
int cmp = compare_traywindows(t, u);
fprintf(stderr, "%s %s %s\n", t->name, cmp < 0 ? "<" : cmp == 0 ? "=" : ">" , u->name);
}
}
}
gboolean add_icon(Window win)
{
XTextProperty xname;
@ -714,6 +732,7 @@ gboolean add_icon(Window win)
else
systray.list_icons = g_slist_append(systray.list_icons, traywin);
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
// print_icons();
if (!traywin->hide && !panel->is_hidden) {
if (systray_profile)
@ -1117,6 +1136,28 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
refresh_systray = 1;
}
void systray_property_notify(TrayWindow *traywin, XEvent *e)
{
Atom at = e->xproperty.atom;
if (at == server.atom.WM_NAME) {
free(traywin->name);
XTextProperty xname;
if (XGetWMName(server.display, traywin->win, &xname)) {
traywin->name = strdup((char *)xname.value);
XFree(xname.value);
} else {
traywin->name = strdup("");
}
if (systray.sort == SYSTRAY_SORT_ASCENDING ||
systray.sort == SYSTRAY_SORT_DESCENDING) {
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
// print_icons();
}
}
}
void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
{
if (systray_profile)
@ -1366,7 +1407,7 @@ void systray_render_icon_composited(void *t)
create_heuristic_mask(data, traywin->width, traywin->height);
}
int empty = image_empty(data, traywin->width, traywin->height);
gboolean empty = FALSE; //image_empty(data, traywin->width, traywin->height);
if (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)
adjust_asb(data,
traywin->width,
@ -1389,6 +1430,7 @@ void systray_render_icon_composited(void *t)
if (traywin->empty != empty) {
traywin->empty = empty;
systray.list_icons = g_slist_sort(systray.list_icons, compare_traywindows);
// print_icons();
// Resize and redraw the systray
if (systray_profile)
fprintf(stderr,
@ -1542,3 +1584,13 @@ gboolean systray_on_monitor(int i_monitor, int num_panelss)
return (i_monitor == systray_monitor) ||
(i_monitor == 0 && (systray_monitor >= num_panelss || systray_monitor < 0));
}
TrayWindow *systray_find_icon(Window win)
{
for (GSList *l = systray.list_icons; l; l = l->next) {
TrayWindow *traywin = (TrayWindow *)l->data;
if (traywin->win == win || traywin->parent == win)
return traywin;
}
return NULL;
}

View file

@ -102,7 +102,10 @@ gboolean request_embed_icon(TrayWindow *traywin);
void systray_resize_request_event(TrayWindow *traywin, XEvent *e);
gboolean request_embed_icon(TrayWindow *traywin);
void systray_reconfigure_event(TrayWindow *traywin, XEvent *e);
void systray_property_notify(TrayWindow *traywin, XEvent *e);
void systray_destroy_event(TrayWindow *traywin);
void kde_update_icons();
TrayWindow *systray_find_icon(Window win);
#endif

View file

@ -1048,6 +1048,12 @@ void event_property_notify(XEvent *e)
panel_refresh = TRUE;
}
} else {
TrayWindow *traywin = systray_find_icon(win);
if (traywin) {
systray_property_notify(traywin, e);
return;
}
Task *task = task_get_task(win);
if (debug) {
char *atom_name = XGetAtomName(server.display, at);
@ -1161,15 +1167,10 @@ void event_configure_notify(XEvent *e)
return;
}
// 'win' is a trayer icon
TrayWindow *traywin;
GSList *l;
for (l = systray.list_icons; l; l = l->next) {
traywin = (TrayWindow *)l->data;
if (traywin->win == win) {
systray_reconfigure_event(traywin, e);
return;
}
TrayWindow *traywin = systray_find_icon(win);
if (traywin) {
systray_reconfigure_event(traywin, e);
return;
}
// 'win' move in another monitor
@ -1646,27 +1647,19 @@ start:
event_configure_notify(&e);
break;
case ConfigureRequest:
// 'win' is a trayer icon
for (GSList *it = systray.list_icons; it; it = g_slist_next(it)) {
TrayWindow *traywin = (TrayWindow *)it->data;
if (traywin->win == e.xany.window) {
systray_reconfigure_event(traywin, &e);
break;
}
}
case ConfigureRequest: {
TrayWindow *traywin = systray_find_icon(e.xany.window);
if (traywin)
systray_reconfigure_event(traywin, &e);
break;
}
case ResizeRequest:
// 'win' is a trayer icon
for (GSList *it = systray.list_icons; it; it = g_slist_next(it)) {
TrayWindow *traywin = (TrayWindow *)it->data;
if (traywin->win == e.xany.window) {
systray_resize_request_event(traywin, &e);
break;
}
}
case ResizeRequest: {
TrayWindow *traywin = systray_find_icon(e.xany.window);
if (traywin)
systray_resize_request_event(traywin, &e);
break;
}
case ReparentNotify: {
if (!systray_enabled)
@ -1674,8 +1667,8 @@ start:
Panel *systray_panel = (Panel *)systray.area.panel;
if (e.xany.window == systray_panel->main_win) // don't care
break;
for (GSList *it = systray.list_icons; it; it = g_slist_next(it)) {
TrayWindow *traywin = (TrayWindow *)it->data;
TrayWindow *traywin = systray_find_icon(e.xreparent.window);
if (traywin) {
if (traywin->win == e.xreparent.window) {
if (traywin->parent == e.xreparent.parent) {
embed_icon(traywin);
@ -1855,13 +1848,9 @@ start:
default:
if (e.type == XDamageNotify + damage_event) {
XDamageNotifyEvent *de = (XDamageNotifyEvent *)&e;
for (GSList *l = systray.list_icons; l; l = l->next) {
TrayWindow *traywin = (TrayWindow *)l->data;
if (traywin->parent == de->drawable) {
systray_render_icon(traywin);
break;
}
}
TrayWindow *traywin = systray_find_icon(de->drawable);
if (traywin)
systray_render_icon(traywin);
}
}
}