statusbar: handle systray invisibility
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
d98c28ef86
commit
254a39b6d3
2
client.c
2
client.c
|
@ -264,7 +264,7 @@ client_focus(client_t *c, int screen)
|
|||
* \todo It might be worth stopping to restack everyone and only stack `c'
|
||||
* relatively to the first matching in the list.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
client_stack(void)
|
||||
{
|
||||
uint32_t config_win_vals[2];
|
||||
|
|
1
client.h
1
client.h
|
@ -30,6 +30,7 @@ bool client_isvisible(client_t *, int);
|
|||
client_t * client_getbywin(xcb_window_t);
|
||||
void client_focus(client_t *, int);
|
||||
void client_setlayer(client_t *, layer_t);
|
||||
void client_stack(void);
|
||||
void client_raise(client_t *);
|
||||
void client_ban(client_t *);
|
||||
void client_unban(client_t *);
|
||||
|
|
142
statusbar.c
142
statusbar.c
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "statusbar.h"
|
||||
#include "screen.h"
|
||||
#include "widget.h"
|
||||
|
@ -38,19 +39,142 @@ DO_LUA_EQ(statusbar_t, statusbar, "statusbar")
|
|||
static void
|
||||
statusbar_draw(statusbar_t *statusbar)
|
||||
{
|
||||
widget_node_t *systray;
|
||||
|
||||
statusbar->need_update = false;
|
||||
|
||||
if(!statusbar->position)
|
||||
return;
|
||||
/* found the systray if any */
|
||||
for(systray = statusbar->widgets; systray; systray = systray->next)
|
||||
if(systray->widget->type == systray_new)
|
||||
break;
|
||||
|
||||
widget_render(statusbar->widgets, statusbar->ctx, statusbar->sw->gc,
|
||||
statusbar->sw->pixmap,
|
||||
statusbar->screen, statusbar->position,
|
||||
statusbar->sw->geometry.x, statusbar->sw->geometry.y,
|
||||
statusbar, AWESOME_TYPE_STATUSBAR);
|
||||
if(statusbar->position)
|
||||
{
|
||||
widget_render(statusbar->widgets, statusbar->ctx, statusbar->sw->gc,
|
||||
statusbar->sw->pixmap,
|
||||
statusbar->screen, statusbar->position,
|
||||
statusbar->sw->geometry.x, statusbar->sw->geometry.y,
|
||||
statusbar, AWESOME_TYPE_STATUSBAR);
|
||||
simplewindow_refresh_pixmap(statusbar->sw);
|
||||
}
|
||||
|
||||
simplewindow_refresh_pixmap(statusbar->sw);
|
||||
xcb_aux_sync(globalconf.connection);
|
||||
if(systray)
|
||||
{
|
||||
uint32_t config_win_vals[4];
|
||||
uint32_t config_win_vals_off[4] = { -1, -1, 1, 1 };
|
||||
xembed_window_t *em;
|
||||
position_t pos;
|
||||
|
||||
if(statusbar->position && systray->widget->isvisible)
|
||||
{
|
||||
pos = statusbar->position;
|
||||
/* width */
|
||||
config_win_vals[2] = systray->area.height;
|
||||
/* height */
|
||||
config_win_vals[3] = systray->area.height;
|
||||
}
|
||||
else
|
||||
/* hide */
|
||||
pos = Off;
|
||||
|
||||
switch(pos)
|
||||
{
|
||||
case Left:
|
||||
config_win_vals[0] = statusbar->sw->geometry.x + systray->area.y;
|
||||
config_win_vals[1] = statusbar->sw->geometry.y + statusbar->sw->geometry.height
|
||||
- systray->area.x - config_win_vals[3];
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == statusbar->phys_screen)
|
||||
{
|
||||
if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) statusbar->sw->geometry.y)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[1] -= config_win_vals[3];
|
||||
}
|
||||
else
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals_off);
|
||||
}
|
||||
client_stack();
|
||||
break;
|
||||
case Right:
|
||||
config_win_vals[0] = statusbar->sw->geometry.x - systray->area.y;
|
||||
config_win_vals[1] = statusbar->sw->geometry.y + systray->area.x;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == statusbar->phys_screen)
|
||||
{
|
||||
if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) statusbar->sw->geometry.y + statusbar->ctx->width)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[1] += config_win_vals[3];
|
||||
}
|
||||
else
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals_off);
|
||||
}
|
||||
client_stack();
|
||||
break;
|
||||
case Top:
|
||||
case Bottom:
|
||||
config_win_vals[0] = statusbar->sw->geometry.x + systray->area.x;
|
||||
config_win_vals[1] = statusbar->sw->geometry.y + systray->area.y;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == statusbar->phys_screen)
|
||||
{
|
||||
/* if(x + width < systray.x + systray.width) */
|
||||
if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(systray->area) + statusbar->sw->geometry.x)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, em->win);
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[0] += config_win_vals[2];
|
||||
}
|
||||
else
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals_off);
|
||||
}
|
||||
client_stack();
|
||||
break;
|
||||
default:
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == statusbar->phys_screen)
|
||||
xcb_configure_window(globalconf.connection, em->win,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals_off);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Statusbar refresh function.
|
||||
|
|
10
widget.c
10
widget.c
|
@ -154,20 +154,16 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_
|
|||
draw_rectangle(ctx, rectangle, 1.0, true, &ctx->bg);
|
||||
|
||||
for(w = wnode; w; w = w->next)
|
||||
if(w->widget->align == AlignLeft)
|
||||
/* special case: systray need to be called even if it's not visible */
|
||||
if(w->widget->isvisible || w->widget->type == systray_new)
|
||||
if(w->widget->align == AlignLeft && w->widget->isvisible)
|
||||
left += w->widget->draw(ctx, screen, w, left, (left + right), object, type);
|
||||
|
||||
/* renders right widget from last to first */
|
||||
for(w = *widget_node_list_last(&wnode); w; w = w->prev)
|
||||
if(w->widget->align == AlignRight)
|
||||
if(w->widget->isvisible || w->widget->type == systray_new)
|
||||
if(w->widget->align == AlignRight && w->widget->isvisible)
|
||||
right += w->widget->draw(ctx, screen, w, right, (left + right), object, type);
|
||||
|
||||
for(w = wnode; w; w = w->next)
|
||||
if(w->widget->align == AlignFlex)
|
||||
if(w->widget->isvisible || w->widget->type == systray_new)
|
||||
if(w->widget->align == AlignFlex && w->widget->isvisible)
|
||||
left += w->widget->draw(ctx, screen, w, left, (left + right), object, type);
|
||||
|
||||
switch(position)
|
||||
|
|
|
@ -40,35 +40,21 @@ systray_draw(draw_context_t *ctx,
|
|||
void *p,
|
||||
awesome_type_t type)
|
||||
{
|
||||
int phys_screen;
|
||||
xembed_window_t *em;
|
||||
uint32_t orient, config_win_vals[4];
|
||||
uint32_t orient;
|
||||
/* p is always a statusbar, titlebars are forbidden */
|
||||
statusbar_t *sb = (statusbar_t *) p;
|
||||
|
||||
/* we are on a statusbar */
|
||||
assert(type == AWESOME_TYPE_STATUSBAR);
|
||||
|
||||
phys_screen = screen_virttophys(screen);
|
||||
|
||||
w->area.height = ctx->height;
|
||||
|
||||
/* width */
|
||||
config_win_vals[2] = w->area.height;
|
||||
/* height */
|
||||
config_win_vals[3] = w->area.height;
|
||||
|
||||
if(!w->widget->isvisible)
|
||||
{
|
||||
w->area.width = 0;
|
||||
config_win_vals[0] = - config_win_vals[2];
|
||||
config_win_vals[1] = - config_win_vals[3];
|
||||
}
|
||||
else if(ctx->width - used > 0)
|
||||
if(ctx->width - used > 0)
|
||||
{
|
||||
int i = 0;
|
||||
xembed_window_t *em;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == phys_screen)
|
||||
if(em->phys_screen == sb->phys_screen)
|
||||
i++;
|
||||
w->area.width = MIN(i * ctx->height, ctx->width - used);
|
||||
}
|
||||
|
@ -81,94 +67,24 @@ systray_draw(draw_context_t *ctx,
|
|||
w->widget->align);
|
||||
w->area.y = 0;
|
||||
|
||||
/* inform that there's a widget */
|
||||
globalconf.screens[sb->phys_screen].systray.has_systray_widget = true;
|
||||
|
||||
switch(sb->position)
|
||||
{
|
||||
case Left:
|
||||
if(w->widget->isvisible)
|
||||
{
|
||||
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];
|
||||
}
|
||||
orient = _NET_SYSTEM_TRAY_ORIENTATION_VERT;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
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,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[1] -= config_win_vals[3];
|
||||
}
|
||||
else
|
||||
xcb_unmap_window(globalconf.connection, em->win);
|
||||
}
|
||||
break;
|
||||
case Right:
|
||||
if(w->widget->isvisible)
|
||||
{
|
||||
config_win_vals[0] = sb->sw->geometry.x - w->area.y;
|
||||
config_win_vals[1] = sb->sw->geometry.y + w->area.x;
|
||||
}
|
||||
case Left:
|
||||
orient = _NET_SYSTEM_TRAY_ORIENTATION_VERT;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
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,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[1] += config_win_vals[3];
|
||||
}
|
||||
else
|
||||
xcb_unmap_window(globalconf.connection, em->win);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(w->widget->isvisible)
|
||||
{
|
||||
config_win_vals[0] = sb->sw->geometry.x + w->area.x;
|
||||
config_win_vals[1] = sb->sw->geometry.y + w->area.y;
|
||||
}
|
||||
orient = _NET_SYSTEM_TRAY_ORIENTATION_HORZ;
|
||||
for(em = globalconf.embedded; em; em = em->next)
|
||||
if(em->phys_screen == phys_screen)
|
||||
{
|
||||
/* if(x + width < systray.x + systray.width) */
|
||||
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,
|
||||
XCB_CONFIG_WINDOW_X
|
||||
| XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH
|
||||
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||
config_win_vals);
|
||||
config_win_vals[0] += config_win_vals[2];
|
||||
}
|
||||
else
|
||||
xcb_unmap_window(globalconf.connection, em->win);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* inform that there's a widget */
|
||||
globalconf.screens[phys_screen].systray.has_systray_widget = true;
|
||||
|
||||
/* set statusbar orientation */
|
||||
/** \todo stop setting that property on each redraw */
|
||||
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
|
||||
globalconf.screens[phys_screen].systray.window,
|
||||
globalconf.screens[sb->phys_screen].systray.window,
|
||||
_NET_SYSTEM_TRAY_ORIENTATION, CARDINAL, 32, 1, &orient);
|
||||
|
||||
return w->area.width;
|
||||
|
|
Loading…
Reference in New Issue