systray: add support for multiple physical screens

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-14 23:20:35 +02:00
parent f5314dbc9e
commit 70dbe7bc4d
5 changed files with 39 additions and 40 deletions

View File

@ -124,9 +124,9 @@ for s = 1, screen.count() do
mystatusbar[s]:widget_add(mymenubox) mystatusbar[s]:widget_add(mymenubox)
mystatusbar[s]:widget_add(mytextbox) mystatusbar[s]:widget_add(mytextbox)
mystatusbar[s]:widget_add(mylayoutbox[s]) mystatusbar[s]:widget_add(mylayoutbox[s])
mystatusbar[s]:widget_add(mysystray)
mystatusbar[s]:add(s) mystatusbar[s]:add(s)
end end
mystatusbar[screen.count()]:widget_add(mysystray)
-- }}} -- }}}
-- {{{ Mouse bindings -- {{{ Mouse bindings

View File

@ -377,14 +377,6 @@ luaA_statusbar_widget_add(lua_State *L)
widget_t **widget = luaA_checkudata(L, 2, "widget"); widget_t **widget = luaA_checkudata(L, 2, "widget");
widget_node_t *w = p_new(widget_node_t, 1); 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; (*sb)->need_update = true;
w->widget = *widget; w->widget = *widget;
widget_node_list_append(&(*sb)->widgets, w); widget_node_list_append(&(*sb)->widgets, w);
@ -411,8 +403,6 @@ widget_remove_loop:
for(w = (*sb)->widgets; w; w = w->next) for(w = (*sb)->widgets; w; w = w->next)
if(w->widget == *widget) if(w->widget == *widget)
{ {
if(*sb == globalconf.systray && (*widget)->type == systray_new)
globalconf.systray = NULL;
widget_unref(widget); widget_unref(widget);
widget_node_list_detach(&(*sb)->widgets, w); widget_node_list_detach(&(*sb)->widgets, w);
p_delete(&w); p_delete(&w);

View File

@ -372,6 +372,8 @@ typedef struct
statusbar_t *statusbar; statusbar_t *statusbar;
/** Padding */ /** Padding */
padding_t padding; padding_t padding;
/** Statusbar that contains the systray */
statusbar_t *systray;
} screen_t; } screen_t;
/** Main configuration structure */ /** Main configuration structure */
@ -416,8 +418,6 @@ struct awesome_t
char *configpath; char *configpath;
/** Floating window placement algo */ /** Floating window placement algo */
FloatingPlacement *floating_placement; FloatingPlacement *floating_placement;
/** Statusbar that contains the systray */
statusbar_t *systray;
/** Selected clients history */ /** Selected clients history */
client_node_t *focus; client_node_t *focus;
/** Stack client history */ /** Stack client history */

View File

@ -25,6 +25,7 @@
#include "structs.h" #include "structs.h"
#include "systray.h" #include "systray.h"
#include "window.h" #include "window.h"
#include "widget.h"
#include "common/xembed.h" #include "common/xembed.h"
#define SYSTEM_TRAY_REQUEST_DOCK 0 /* Begin icon docking */ #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) systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info)
{ {
xembed_window_t *em; xembed_window_t *em;
int i;
const uint32_t select_input_val[] = const uint32_t select_input_val[] =
{ {
XCB_EVENT_MASK_STRUCTURE_NOTIFY 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_window_list_append(&globalconf.embedded, em);
xembed_embedded_notify(globalconf.connection, em->win, xembed_embedded_notify(globalconf.connection, em->win,
globalconf.systray->sw->window, globalconf.screens[phys_screen].systray->sw->window,
MIN(XEMBED_VERSION, em->info.version)); MIN(XEMBED_VERSION, em->info.version));
if(em->info.flags & XEMBED_MAPPED) if(em->info.flags & XEMBED_MAPPED)
xcb_map_window(globalconf.connection, em->win); 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; return 0;
} }

View File

@ -22,17 +22,13 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include "widget.h" #include "widget.h"
#include "screen.h"
#include "common/xembed.h" #include "common/xembed.h"
extern awesome_t globalconf; extern awesome_t globalconf;
typedef struct
{
bool init;
} systray_data_t;
static bool static bool
systray_init(void) systray_init(statusbar_t *sb)
{ {
xutil_intern_atom_request_t atom_systray_q, atom_manager_q; xutil_intern_atom_request_t atom_systray_q, atom_manager_q;
xcb_atom_t atom_systray; xcb_atom_t atom_systray;
@ -41,13 +37,13 @@ systray_init(void)
/* Send requests */ /* Send requests */
atom_manager_q = xutil_intern_atom(globalconf.connection, &globalconf.atoms, atom_name); 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); atom_systray_q = xutil_intern_atom(globalconf.connection, &globalconf.atoms, atom_name);
/* Fill event */ /* Fill event */
ev.format = 32; ev.format = 32;
ev.data.data32[0] = XCB_CURRENT_TIME; 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.data.data32[3] = ev.data.data32[4] = 0;
ev.response_type = xutil_intern_atom_reply(globalconf.connection, ev.response_type = xutil_intern_atom_reply(globalconf.connection,
&globalconf.atoms, atom_manager_q); &globalconf.atoms, atom_manager_q);
@ -57,7 +53,7 @@ systray_init(void)
atom_systray_q); atom_systray_q);
xcb_set_selection_owner(globalconf.connection, xcb_set_selection_owner(globalconf.connection,
globalconf.systray->sw->window, sb->sw->window,
atom_systray, atom_systray,
XCB_CURRENT_TIME); XCB_CURRENT_TIME);
@ -69,16 +65,25 @@ systray_draw(draw_context_t *ctx,
int screen __attribute__ ((unused)), int screen __attribute__ ((unused)),
widget_node_t *w, widget_node_t *w,
int offset, int used __attribute__ ((unused)), int offset, int used __attribute__ ((unused)),
void *p __attribute__ ((unused))) void *p)
{ {
int i = 0; int i = 0, phys_screen;
xembed_window_t *em; xembed_window_t *em;
uint32_t config_win_vals[6]; 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) /* only init and take systray handling if noone has it and if we have a
d->init = systray_init(); * 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) for(em = globalconf.embedded; em; em = em->next)
i++; i++;
@ -99,18 +104,18 @@ systray_draw(draw_context_t *ctx,
/* height */ /* height */
config_win_vals[3] = w->area.height; config_win_vals[3] = w->area.height;
/* sibling */ /* sibling */
config_win_vals[4] = globalconf.systray->sw->window; config_win_vals[4] = sb->sw->window;
/* stack mode */ /* stack mode */
config_win_vals[5] = XCB_STACK_MODE_ABOVE; config_win_vals[5] = XCB_STACK_MODE_ABOVE;
switch(globalconf.systray->position) switch(sb->position)
{ {
case Left: case Left:
config_win_vals[0] = globalconf.systray->sw->geometry.x + w->area.y; config_win_vals[0] = sb->sw->geometry.x + w->area.y;
config_win_vals[1] = globalconf.systray->sw->geometry.y + globalconf.systray->sw->geometry.height config_win_vals[1] = sb->sw->geometry.y + sb->sw->geometry.height
- w->area.x - config_win_vals[3]; - w->area.x - config_win_vals[3];
for(em = globalconf.embedded; em; em = em->next) 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_map_window(globalconf.connection, em->win);
xcb_configure_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); xcb_unmap_window(globalconf.connection, em->win);
break; break;
case Right: case Right:
config_win_vals[0] = globalconf.systray->sw->geometry.x - w->area.y; config_win_vals[0] = sb->sw->geometry.x - w->area.y;
config_win_vals[1] = globalconf.systray->sw->geometry.y + w->area.x; config_win_vals[1] = sb->sw->geometry.y + w->area.x;
for(em = globalconf.embedded; em; em = em->next) 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_map_window(globalconf.connection, em->win);
xcb_configure_window(globalconf.connection, em->win, xcb_configure_window(globalconf.connection, em->win,
@ -148,13 +153,13 @@ systray_draw(draw_context_t *ctx,
break; break;
default: default:
/* x */ /* 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 */ /* 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) for(em = globalconf.embedded; em; em = em->next)
/* if(x + width < systray.x + systray.width) */ /* 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_map_window(globalconf.connection, em->win);
xcb_configure_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->align = align;
w->draw = systray_draw; w->draw = systray_draw;
w->cache_flags = WIDGET_CACHE_EMBEDDED; w->cache_flags = WIDGET_CACHE_EMBEDDED;
w->data = p_new(systray_data_t, 1);
return w; return w;
} }