X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fsystray%2Fsystraybar.c;h=ef1578fcf2791514fc868e474e2c87640ddfe5c6;hb=5679142e44a103a6fe1e62365fe991d273e41049;hp=307fa18caa2577d8fccdf444b084b0f0eccb2a75;hpb=bd3c2db488b1662fffd7cb5e6226613df2f7dec7;p=chaz%2Ftint2 diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 307fa18..ef1578f 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -37,7 +37,7 @@ GSList *icons; #define SYSTEM_TRAY_CANCEL_MESSAGE 2 // selection window -Window net_sel_win = None; +Window net_sel_win = None, hint_win = None; // freedesktop specification doesn't allow multi systray Systraybar systray; @@ -45,23 +45,14 @@ Systraybar systray; void init_systray() { - cleanup_systray(); - Panel *panel = &panel1[0]; systray.area.parent = panel; systray.area.panel = panel; systray.area._draw_foreground = draw_systray; systray.area._resize = resize_systray; - if (systray.area.on_screen) { - if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != None) { - fprintf(stderr, "tint2 : another systray is running\n"); - systray.area.on_screen = 0; - } - } - if (systray.area.on_screen) - systray.area.on_screen = net_init(); + systray.area.on_screen = init_net(); if (!systray.area.on_screen) return; @@ -75,6 +66,8 @@ void init_systray() systray.area.posx = panel->area.width - panel->area.paddingxlr - panel->area.pix.border.width - systray.area.width; if (panel->clock.area.on_screen) systray.area.posx -= (panel->clock.area.width + panel->area.paddingx); + if (panel->battery.area.on_screen) + systray.area.posx -= (panel->battery.area.width + panel->area.paddingx); systray.area.redraw = 1; } @@ -82,16 +75,19 @@ void init_systray() void cleanup_systray() { - free_area(&systray.area); - - if (net_sel_win != None) { - XDestroyWindow(server.dsp, net_sel_win); - net_sel_win = None; - } if (systray.list_icons) { + GSList *it; + + for (it = systray.list_icons; it; it = it->next) + remove_icon((TrayWindow*)it->data); + g_slist_free(systray.list_icons); systray.list_icons = 0; } + + free_area(&systray.area); + + cleanup_net(); } @@ -103,16 +99,18 @@ void draw_systray(void *obj, cairo_t *c, int active) GSList *l; int icon_size; + //printf("draw_systray %d %d\n", systray.area.posx, systray.area.width); icon_size = sysbar->area.height - (2 * sysbar->area.pix.border.width) - (2 * sysbar->area.paddingy); for (l = systray.list_icons; l ; l = l->next) { traywin = (TrayWindow*)l->data; - printf("draw_systray %d %d\n", systray.area.posx, systray.area.width); // watch for the icon trying to resize itself! - XSelectInput(server.dsp, traywin->id, StructureNotifyMask); + XSelectInput(server.dsp, traywin->id, StructureNotifyMask|ResizeRedirectMask); // position and size the icon window XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, icon_size, icon_size); + // ceci intervertie les fonds : le premier icone prend le fond du dernier + // le dernier prend le fond de l'avant dernier, ... // resize our window so that the new window can fit in it //fix_geometry(); @@ -126,6 +124,7 @@ void draw_systray(void *obj, cairo_t *c, int active) // show the window XMapRaised(server.dsp, traywin->id); } + XSetWindowBackgroundPixmap (server.dsp, panel->main_win, systray.area.pix.pmap); } @@ -147,6 +146,8 @@ void resize_systray(void *obj) systray.area.posx = panel->area.width - panel->area.pix.border.width - panel->area.paddingxlr - systray.area.width; if (panel->clock.area.on_screen) systray.area.posx -= (panel->clock.area.width + panel->area.paddingx); + if (panel->battery.area.on_screen) + systray.area.posx -= (panel->battery.area.width + panel->area.paddingx); systray.area.redraw = 1; @@ -164,9 +165,39 @@ void resize_systray(void *obj) printf("resize_systray %d %d\n", systray.area.posx, systray.area.width); } +/* +void create_hint_win() +{ + XWMHints hints; + XClassHint classhints; + Panel *panel = systray.area.panel; + + hint_win = XCreateSimpleWindow(server.dsp, server.root_win, 0, 0, 1, 1, 0, 0, 0); + + hints.flags = StateHint | WindowGroupHint | IconWindowHint; + hints.initial_state = WithdrawnState; + hints.window_group = hint_win; + hints.icon_window = panel->main_win; + + classhints.res_name = "docker"; + classhints.res_class = "Docker"; + + XSetWMProperties(server.dsp, hint_win, NULL, NULL, NULL, 0, + NULL, &hints, &classhints); + + XMapWindow(server.dsp, hint_win); +} +*/ -int net_init() +int init_net() { + if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != None) { + fprintf(stderr, "tint2 : another systray is running\n"); + return 0; + } + + //create_hint_win(); + // init systray protocol net_sel_win = XCreateSimpleWindow(server.dsp, server.root_win, -1, -1, 1, 1, 0, 0, 0); @@ -196,12 +227,16 @@ int net_init() } -//Window win, root; -int width, height; -int border; -int icon_size; +void cleanup_net() +{ + if (net_sel_win != None) { + XDestroyWindow(server.dsp, net_sel_win); + net_sel_win = None; + } +} +/* void fix_geometry() { GSList *it; @@ -216,7 +251,7 @@ void fix_geometry() XResizeWindow(server.dsp, panel->main_win, width + border * 2, height + border * 2); } - +*/ gboolean error; int window_error_handler(Display *d, XErrorEvent *e) @@ -232,14 +267,14 @@ int window_error_handler(Display *d, XErrorEvent *e) } -gboolean icon_swallow(TrayWindow *traywin) +gboolean icon_swallow(Window id) { XErrorHandler old; Panel *panel = systray.area.panel; error = FALSE; old = XSetErrorHandler(window_error_handler); - XReparentWindow(server.dsp, traywin->id, panel->main_win, 0, 0); + XReparentWindow(server.dsp, id, panel->main_win, 0, 0); XSync(server.dsp, False); XSetErrorHandler(old); @@ -248,10 +283,15 @@ gboolean icon_swallow(TrayWindow *traywin) // The traywin must have its id and type set. -gboolean icon_add(Window id) +gboolean add_icon(Window id) { TrayWindow *traywin; + if (!icon_swallow(id)) { + fprintf(stderr, "tint2 : not icon_swallow\n"); + return FALSE; + } + traywin = g_new0(TrayWindow, 1); traywin->id = id; @@ -265,15 +305,6 @@ gboolean icon_add(Window id) panel->area.resize = 1; panel_refresh = 1; - if (!icon_swallow(traywin)) { - printf("not icon_swallow\n"); - g_free(traywin); - return FALSE; - } - else - printf("icon_swallow\n"); - //return TRUE; - // => calcul x, y, width, height dans resize /* // find the positon for the systray app window @@ -291,14 +322,20 @@ gboolean icon_add(Window id) } -void icon_remove(TrayWindow *traywin) +void remove_icon(TrayWindow *traywin) { XErrorHandler old; - Window win_id = traywin->id; XSelectInput(server.dsp, traywin->id, NoEventMask); - // remove it from our list + // reparent to root + error = FALSE; + old = XSetErrorHandler(window_error_handler); + XReparentWindow(server.dsp, traywin->id, server.root_win, 0, 0); + XSync(server.dsp, False); + XSetErrorHandler(old); + + // remove from our list systray.list_icons = g_slist_remove(systray.list_icons, traywin); g_free(traywin); printf("suppression d'un icone %d\n", g_slist_length(systray.list_icons)); @@ -308,19 +345,7 @@ void icon_remove(TrayWindow *traywin) Panel *panel = systray.area.panel; panel->area.resize = 1; panel_refresh = 1; - return; -/* - // reparent it to root - error = FALSE; - old = XSetErrorHandler(window_error_handler); - XReparentWindow(server.dsp, win_id, root, 0, 0); - XSync(server.dsp, False); - XSetErrorHandler(old); - - reposition_icons(); - fix_geometry(); - */ } @@ -334,7 +359,7 @@ void net_message(XClientMessageEvent *e) switch (opcode) { case SYSTEM_TRAY_REQUEST_DOCK: id = e->data.l[2]; - if (id) icon_add(id); + if (id) add_icon(id); break; case SYSTEM_TRAY_BEGIN_MESSAGE: @@ -358,91 +383,4 @@ void net_message(XClientMessageEvent *e) } -/* -void event_loop() -{ - XEvent e; - Window cover; - GSList *it; - - while (!exit_app) { - while (XPending(server.dsp)) { - XNextEvent(display, &e); - - switch (e.type) - { - case PropertyNotify: - // systray window list has changed? - if (e.xproperty.atom == kde_systray_prop) { - XSelectInput(display, win, NoEventMask); - kde_update_icons(); - XSelectInput(display, win, StructureNotifyMask); - - while (XCheckTypedEvent(display, PropertyNotify, &e)); - } - - break; - - case ConfigureNotify: - if (e.xany.window != win) { - // find the icon it pertains to and beat it into submission - GSList *it; - - for (it = icons; it != NULL; it = g_slist_next(it)) { - TrayWindow *traywin = it->data; - if (traywin->id == e.xany.window) { - XMoveResizeWindow(display, traywin->id, traywin->x, traywin->y, - icon_size, icon_size); - break; - } - } - break; - } - - // briefly cover the entire containing window, which causes it and - // all of the icons to refresh their windows. finally, they update - // themselves when the background of the main window's parent changes. - - cover = XCreateSimpleWindow(display, win, 0, 0, - border * 2 + width, border * 2 + height, - 0, 0, 0); - XMapWindow(display, cover); - XDestroyWindow(display, cover); - - break; - - case ReparentNotify: - if (e.xany.window == win) // reparented to us - break; - case UnmapNotify: - case DestroyNotify: - for (it = icons; it; it = g_slist_next(it)) { - if (((TrayWindow*)it->data)->id == e.xany.window) { - icon_remove(it); - break; - } - } - break; - - case ClientMessage: - if (e.xclient.message_type == net_opcode_atom && - e.xclient.format == 32 && - e.xclient.window == net_sel_win) - net_message(&e.xclient); - - default: - break; - } - } - usleep(500000); - } - - // remove/unparent all the icons - while (icons) { - // do the remove here explicitly, cuz the event handler isn't going to - // happen anymore. - icon_remove(icons); - } -} -*/