diff --git a/awesomerc.lua.in b/awesomerc.lua.in index 9c12a56f2..80e7dc45a 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -124,9 +124,9 @@ for s = 1, screen.count() do mystatusbar[s]:widget_add(mymenubox) mystatusbar[s]:widget_add(mytextbox) mystatusbar[s]:widget_add(mylayoutbox[s]) + mystatusbar[s]:widget_add(mysystray) mystatusbar[s]:add(s) end -mystatusbar[screen.count()]:widget_add(mysystray) -- }}} -- {{{ Mouse bindings diff --git a/statusbar.c b/statusbar.c index a1f904a06..c81df3cb9 100644 --- a/statusbar.c +++ b/statusbar.c @@ -377,14 +377,6 @@ luaA_statusbar_widget_add(lua_State *L) widget_t **widget = luaA_checkudata(L, 2, "widget"); widget_node_t *w = p_new(widget_node_t, 1); - if((*widget)->type == systray_new) - { - if(globalconf.systray) - luaL_error(L, "system tray already added and only one is allowed"); - else - globalconf.systray = *sb; - } - (*sb)->need_update = true; w->widget = *widget; widget_node_list_append(&(*sb)->widgets, w); @@ -411,8 +403,6 @@ widget_remove_loop: for(w = (*sb)->widgets; w; w = w->next) if(w->widget == *widget) { - if(*sb == globalconf.systray && (*widget)->type == systray_new) - globalconf.systray = NULL; widget_unref(widget); widget_node_list_detach(&(*sb)->widgets, w); p_delete(&w); diff --git a/structs.h b/structs.h index ea508064e..acd15ff85 100644 --- a/structs.h +++ b/structs.h @@ -372,6 +372,8 @@ typedef struct statusbar_t *statusbar; /** Padding */ padding_t padding; + /** Statusbar that contains the systray */ + statusbar_t *systray; } screen_t; /** Main configuration structure */ @@ -416,8 +418,6 @@ struct awesome_t char *configpath; /** Floating window placement algo */ FloatingPlacement *floating_placement; - /** Statusbar that contains the systray */ - statusbar_t *systray; /** Selected clients history */ client_node_t *focus; /** Stack client history */ diff --git a/systray.c b/systray.c index cb69934f1..1ef195e4d 100644 --- a/systray.c +++ b/systray.c @@ -25,6 +25,7 @@ #include "structs.h" #include "systray.h" #include "window.h" +#include "widget.h" #include "common/xembed.h" #define SYSTEM_TRAY_REQUEST_DOCK 0 /* Begin icon docking */ @@ -38,6 +39,7 @@ int systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info) { xembed_window_t *em; + int i; const uint32_t select_input_val[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY @@ -62,12 +64,15 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i xembed_window_list_append(&globalconf.embedded, em); xembed_embedded_notify(globalconf.connection, em->win, - globalconf.systray->sw->window, + globalconf.screens[phys_screen].systray->sw->window, MIN(XEMBED_VERSION, em->info.version)); if(em->info.flags & XEMBED_MAPPED) xcb_map_window(globalconf.connection, em->win); + for(i = 0; i < globalconf.screens_info->nscreen; i++) + widget_invalidate_cache(i, WIDGET_CACHE_EMBEDDED); + return 0; } diff --git a/widgets/systray.c b/widgets/systray.c index 66782c38d..6641b2532 100644 --- a/widgets/systray.c +++ b/widgets/systray.c @@ -22,17 +22,13 @@ #include #include "widget.h" +#include "screen.h" #include "common/xembed.h" extern awesome_t globalconf; -typedef struct -{ - bool init; -} systray_data_t; - static bool -systray_init(void) +systray_init(statusbar_t *sb) { xutil_intern_atom_request_t atom_systray_q, atom_manager_q; xcb_atom_t atom_systray; @@ -41,13 +37,13 @@ systray_init(void) /* Send requests */ atom_manager_q = xutil_intern_atom(globalconf.connection, &globalconf.atoms, atom_name); - snprintf(atom_name, sizeof(atom_name), "_NET_SYSTEM_TRAY_S%d", globalconf.default_screen); + snprintf(atom_name, sizeof(atom_name), "_NET_SYSTEM_TRAY_S%d", sb->sw->phys_screen); atom_systray_q = xutil_intern_atom(globalconf.connection, &globalconf.atoms, atom_name); /* Fill event */ ev.format = 32; ev.data.data32[0] = XCB_CURRENT_TIME; - ev.data.data32[2] = globalconf.systray->sw->window; + ev.data.data32[2] = sb->sw->window; ev.data.data32[3] = ev.data.data32[4] = 0; ev.response_type = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, atom_manager_q); @@ -57,7 +53,7 @@ systray_init(void) atom_systray_q); xcb_set_selection_owner(globalconf.connection, - globalconf.systray->sw->window, + sb->sw->window, atom_systray, XCB_CURRENT_TIME); @@ -69,16 +65,25 @@ systray_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), widget_node_t *w, int offset, int used __attribute__ ((unused)), - void *p __attribute__ ((unused))) + void *p) { - int i = 0; + int i = 0, phys_screen; xembed_window_t *em; uint32_t config_win_vals[6]; - systray_data_t *d = w->widget->data; + /* p is always a statusbar, titlebars are forbidden */ + statusbar_t *sb = (statusbar_t *) p; + phys_screen = screen_virttophys(screen); - if(!d->init) - d->init = systray_init(); + /* only init and take systray handling if noone has it and if we have a + * window to handle others... windows. */ + if(!globalconf.screens[phys_screen].systray && sb->sw) + { + globalconf.screens[phys_screen].systray = sb; + systray_init(sb); + } + else if(globalconf.screens[phys_screen].systray != p) + return (w->area.width = 0); for(em = globalconf.embedded; em; em = em->next) i++; @@ -99,18 +104,18 @@ systray_draw(draw_context_t *ctx, /* height */ config_win_vals[3] = w->area.height; /* sibling */ - config_win_vals[4] = globalconf.systray->sw->window; + config_win_vals[4] = sb->sw->window; /* stack mode */ config_win_vals[5] = XCB_STACK_MODE_ABOVE; - switch(globalconf.systray->position) + switch(sb->position) { case Left: - config_win_vals[0] = globalconf.systray->sw->geometry.x + w->area.y; - config_win_vals[1] = globalconf.systray->sw->geometry.y + globalconf.systray->sw->geometry.height + config_win_vals[0] = sb->sw->geometry.x + w->area.y; + config_win_vals[1] = sb->sw->geometry.y + sb->sw->geometry.height - w->area.x - config_win_vals[3]; for(em = globalconf.embedded; em; em = em->next) - if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) globalconf.systray->sw->geometry.y) + if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) sb->sw->geometry.y) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -127,10 +132,10 @@ systray_draw(draw_context_t *ctx, xcb_unmap_window(globalconf.connection, em->win); break; case Right: - config_win_vals[0] = globalconf.systray->sw->geometry.x - w->area.y; - config_win_vals[1] = globalconf.systray->sw->geometry.y + w->area.x; + config_win_vals[0] = sb->sw->geometry.x - w->area.y; + config_win_vals[1] = sb->sw->geometry.y + w->area.x; for(em = globalconf.embedded; em; em = em->next) - if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) globalconf.systray->sw->geometry.y + ctx->width) + if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) sb->sw->geometry.y + ctx->width) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -148,13 +153,13 @@ systray_draw(draw_context_t *ctx, break; default: /* x */ - config_win_vals[0] = globalconf.systray->sw->geometry.x + w->area.x; + config_win_vals[0] = sb->sw->geometry.x + w->area.x; /* y */ - config_win_vals[1] = globalconf.systray->sw->geometry.y + w->area.y; + config_win_vals[1] = sb->sw->geometry.y + w->area.y; for(em = globalconf.embedded; em; em = em->next) /* if(x + width < systray.x + systray.width) */ - if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(w->area) + globalconf.systray->sw->geometry.x) + if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(w->area) + sb->sw->geometry.x) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -185,7 +190,6 @@ systray_new(alignment_t align) w->align = align; w->draw = systray_draw; w->cache_flags = WIDGET_CACHE_EMBEDDED; - w->data = p_new(systray_data_t, 1); return w; }