From 228d20a72c43a07a2c2cdf16fd2cc202a12dc95d Mon Sep 17 00:00:00 2001 From: o9000 Date: Thu, 7 Jan 2016 12:50:54 +0100 Subject: [PATCH] Systray: handle changing icon names and reorder if necessary --- src/systray/systraybar.c | 54 ++++++++++++++++++++++++++++++++++- src/systray/systraybar.h | 3 ++ src/tint.c | 61 ++++++++++++++++------------------------ 3 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 718fbae..f3410b3 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -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; +} diff --git a/src/systray/systraybar.h b/src/systray/systraybar.h index 9e0bfbd..447c0b2 100644 --- a/src/systray/systraybar.h +++ b/src/systray/systraybar.h @@ -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 diff --git a/src/tint.c b/src/tint.c index f78fb40..d9897cd 100644 --- a/src/tint.c +++ b/src/tint.c @@ -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); } } }