/* Track icon visibility state changes */ void icon_track_visibility_changes(Window w) { struct TrayIcon *ti; int mapped; /* Ignore false alarms */ if ((ti = icon_list_find(w)) == NULL || !ti->is_xembed_supported) return; mapped = xembed_get_mapped_state(ti); LOG_TRACE(("xembed_is_mapped(0x%x) = %u\n", w, mapped)); LOG_TRACE(("is_visible = %u\n", ti->is_visible)); #ifdef DEBUG x11_dump_win_info(tray_data.dpy, ti->wid); #endif /* Nothing has changed */ if (mapped == ti->is_visible) return; ti->is_visible = mapped; LOG_INFO(("%s icon 0x%x\n", mapped ? "showing" : "hiding", w)); if (mapped) { /* Icon has become mapped and is listed as hidden. Show this icon. */ embedder_reset_size(ti); if (!layout_add(ti)) { xembed_set_mapped_state(ti, False); return; } embedder_show(ti); } else { /* Icon has become unmapped and is listed as visible. Hide this icon. */ layout_remove(ti); embedder_hide(ti); } embedder_update_positions(False); tray_update_window_props(); }
void configure_notify(XConfigureEvent ev) { struct TrayIcon *ti; struct Point sz; XWindowAttributes xwa; if (ev.window == tray_data.tray) { /* Tray window was resized */ /* TODO: distinguish between synthetic and real configure notifies */ /* TODO: catch rejected configure requests */ /* XXX: Geometry stuff is a mess. Geometry * is specified in slots, but almost always is * stored in pixels... */ LOG_TRACE(("tray window geometry from event: %ux%u+%d+%d\n", ev.width, ev.height, ev.x, ev.y)); /* Sometimes, configure notifies come too late, so we fetch real geometry ourselves */ XGetWindowAttributes(tray_data.dpy, tray_data.tray, &xwa); x11_get_window_abs_coords(tray_data.dpy, tray_data.tray, &tray_data.xsh.x, &tray_data.xsh.y); LOG_TRACE(("tray window geometry from X11 calls: %dx%d+%d+%d\n", xwa.width, xwa.height, tray_data.xsh.x, tray_data.xsh.y)); tray_data.xsh.width = xwa.width; tray_data.xsh.height = xwa.height; /* Update icons positions */ /* XXX: internal API is bad. example below */ icon_list_forall(&layout_translate_to_window); embedder_update_positions(True); /* Adjust window background if necessary */ tray_update_bg(False); tray_refresh_window(True); tray_update_window_strut(); scrollbars_update(); } else if ((ti = icon_list_find(ev.window)) != NULL) { /* Some icon has resized its window */ /* KDE icons are not allowed to change their size. Reset icon size. */ if (ti->cmode == CM_KDE || settings.kludge_flags & KLUDGE_FORCE_ICONS_SIZE) { embedder_reset_size(ti); return; } if (settings.kludge_flags & KLUDGE_FORCE_ICONS_SIZE) return; /* Get new window size */ if (!x11_get_window_size(tray_data.dpy, ti->wid, &sz.x, &sz.y)) { embedder_unembed(ti); return; } LOG_TRACE(("icon 0x%x was resized, new size: %ux%u, old size: %ux%u\n", ev.window, sz.x, sz.y, ti->l.wnd_sz.x, ti->l.wnd_sz.y)); /* Check if the size has really changed */ if (sz.x == ti->l.wnd_sz.x && sz.y == ti->l.wnd_sz.y) return; ti->l.wnd_sz = sz; ti->is_resized = True; /* Do the job */ layout_handle_icon_resize(ti); embedder_refresh(ti); #ifdef DEBUG print_icon_data(ti); #endif embedder_update_positions(False); tray_update_window_props(); #ifdef DEBUG dump_tray_status(); #endif } }
/* Add icon to the tray */ void add_icon(Window w, int cmode) { struct TrayIcon *ti; /* Aviod adding duplicates */ if ((ti = icon_list_find(w)) != NULL) { LOG_TRACE(("ignoring second request to embed 0x%x" "(requested cmode=%d, current cmode=%d\n", w, cmode, ti->cmode)); return; } /* Dear Edsger W. Dijkstra, I see you behind my back =( */ if ((ti = icon_list_new(w, cmode)) == NULL) goto failed0; LOG_TRACE(("starting embedding for icon 0x%x, cmode=%d\n", w, cmode)); x11_dump_win_info(tray_data.dpy, w); /* Start embedding cycle */ if (!xembed_check_support(ti)) goto failed1; if (ti->is_xembed_supported) ti->is_visible = xembed_get_mapped_state(ti); else ti->is_visible = True; if (ti->is_visible) { if (!embedder_reset_size(ti)) goto failed1; //if (!layout_add(ti)) goto failed1; } if (!xembed_embed(ti)) goto failed1; if (!embedder_embed(ti)) goto failed2; refresh_icons_later(FALSE); /* Report success */ LOG_INFO(("added icon %s (wid 0x%x) as %s\n", x11_get_window_name(tray_data.dpy, ti->wid, "<unknown>"), ti->wid, ti->is_visible ? "visible" : "hidden")); goto ok; failed2: //layout_remove(ti); failed1: icon_list_free(ti); failed0: LOG_INFO(("failed to add icon %s (wid 0x%x)\n", x11_get_window_name(tray_data.dpy, ti->wid, "<unknown>"), ti->wid)); ok: if (settings.log_level >= LOG_LEVEL_TRACE) dump_tray_status(); return; }