systray: add support for multiple physical screens
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
f5314dbc9e
commit
70dbe7bc4d
|
@ -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
|
||||||
|
|
10
statusbar.c
10
statusbar.c
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue