int main(int argc, char **argv) { int i; struct sbuf s; if (argc < 2) usage(); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') icon_name = argv[i]; if (!strncmp(argv[i], "--icon-size=", 12)) xatoi(&icon_size, argv[i] + 12, XATOI_NONNEG, "config.icon_size"); if (!strncmp(argv[i], "--theme=", 8)) theme = argv[i] + 8; if (!strncmp(argv[i], "--help", 6)) usage(); } if (!icon_name) { fprintf(stderr, "fatal: no icon-name specified\n"); exit(1); } sbuf_init(&s); icon_find_init(); if (theme) icon_find_add_theme(theme); else icon_find_add_theme("default"); icon_find_add_theme("hicolor"); sbuf_cpy(&s, icon_name); icon_find(&s, icon_size); if (s.len) printf("%s\n", s.buf); else fprintf(stderr, "warning: could not find icon '%s'\n", icon_name); return 0; }
static void event(XEvent *ev){ struct trayicon *icon; void *v; switch(ev->type){ case SelectionClear: if(ev->xselectionclear.selection == net_system_tray_s && XGetSelectionOwner(display, net_system_tray_s) != selwindow){ warn(DEBUG_ERROR, "fdtray: Another application (window %lx) has forcibly taken the system tray registration", ev->xselectionclear.window); exitapp = True; } break; case PropertyNotify: if(ev->xproperty.atom != xembed_info) break; icon = icon_find(ev->xproperty.window); if(!icon || icon->type!=my_id) break; v = catch_BadWindow_errors(); Bool map = get_map(icon->w); if(uncatch_BadWindow_errors(v)){ warn(DEBUG_WARN, "Tray icon %lx is invalid", icon->w); icon_remove(icon->w); } else { icon_set_mapping(icon, map); } break; case ConfigureNotify: icon = icon_find(ev->xconfigure.window); if(!icon || icon->type!=my_id) break; v = catch_BadWindow_errors(); { XWindowAttributes a; XGetWindowAttributes(display, icon->w, &a); if(a.width != iconsize || a.height != iconsize) XResizeWindow(display, icon->w, iconsize, iconsize); } if(uncatch_BadWindow_errors(v)){ warn(DEBUG_WARN, "Tray icon %lx is invalid", icon->w); icon_remove(icon->w); } break; case ReparentNotify: icon = icon_find(ev->xreparent.window); if(!icon || icon->type!=my_id) break; if(is_icon_parent(ev->xreparent.parent)){ send_xembed_notify(icon->w, ev->xreparent.parent); } else { warn(DEBUG_WARN, "Tray icon %lx was reparented, removing", icon->w); icon_remove(icon->w); } break; case DestroyNotify: icon = icon_find(ev->xdestroywindow.window); if(!icon || icon->type!=my_id) break; warn(DEBUG_WARN, "Tray icon %lx was destroyed, removing", icon->w); icon_remove(icon->w); break; case ClientMessage: if(ev->xclient.message_type == net_system_tray_opcode){ switch(ev->xclient.data.l[1]){ case 0: // SYSTEM_TRAY_REQUEST_DOCK add(ev->xclient.data.l[2]); break; case 1: // SYSTEM_TRAY_BEGIN_MESSAGE icon = icon_find(ev->xclient.window); if(!icon || icon->type!=my_id) break; *(int *)icon->data = ev->xclient.data.l[4]; icon_begin_message(icon->w, ev->xclient.data.l[4], ev->xclient.data.l[3], ev->xclient.data.l[2]); break; case 2: // SYSTEM_TRAY_CANCEL_MESSAGE icon = icon_find(ev->xclient.window); if(!icon || icon->type!=my_id) break; icon_cancel_message(icon->w, ev->xclient.data.l[2]); break; } } else if(ev->xclient.message_type == net_system_tray_message_data){ icon = icon_find(ev->xclient.window); if(!icon || icon->type!=my_id) break; icon_message_data(icon->w, *(int *)icon->data, ev->xclient.data.b, 20); } break; } }