wibox: rework, merge titlebar

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-09-24 12:13:21 +02:00
parent 6a295e8e8c
commit 5709435392
31 changed files with 1145 additions and 1116 deletions

View File

@ -29,7 +29,7 @@ former or as a rectangular fractal for the later.
Windows are grouped by tags. Each window can be tagged with one or multiple Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags. tags. Selecting certain tags displays all windows with these tags.
*awesome* can contain small statusbars which can display anything you want: *awesome* can contain small wiboxes which can display anything you want:
all available tags, the layout, the title of the visible windows, a text, etc. all available tags, the layout, the title of the visible windows, a text, etc.
OPTIONS OPTIONS

View File

@ -91,7 +91,7 @@ for s = 1, screen.count() do
end end
-- }}} -- }}}
-- {{{ Statusbar -- {{{ Wibox
-- Create a taglist widget -- Create a taglist widget
mytaglist = widget({ type = "taglist", name = "mytaglist" }) mytaglist = widget({ type = "taglist", name = "mytaglist" })
mytaglist:buttons({ mytaglist:buttons({
@ -141,13 +141,13 @@ for s = 1, screen.count() do
mylayoutbox[s].image = image("@AWESOME_ICON_PATH@/layouts/tilew.png") mylayoutbox[s].image = image("@AWESOME_ICON_PATH@/layouts/tilew.png")
end end
-- Create a statusbar for each screen and add it -- Create a wibox for each screen and add it
mystatusbar = {} mywibox = {}
for s = 1, screen.count() do for s = 1, screen.count() do
mystatusbar[s] = wibox({ position = "top", name = "mystatusbar" .. s, mywibox[s] = wibox({ position = "top", name = "mywibox" .. s,
fg = beautiful.fg_normal, bg = beautiful.bg_normal }) fg = beautiful.fg_normal, bg = beautiful.bg_normal })
-- Add widgets to the statusbar - order matters -- Add widgets to the wibox - order matters
mystatusbar[s]:widgets({ mywibox[s]:widgets({
mytaglist, mytaglist,
mytasklist, mytasklist,
mylauncher, mylauncher,
@ -156,7 +156,7 @@ for s = 1, screen.count() do
mylayoutbox[s], mylayoutbox[s],
s == 1 and mysystray or nil s == 1 and mysystray or nil
}) })
mystatusbar[s].screen = s mywibox[s].screen = s
end end
-- }}} -- }}}

View File

@ -35,7 +35,6 @@
#include "luaa.h" #include "luaa.h"
#include "mouse.h" #include "mouse.h"
#include "systray.h" #include "systray.h"
#include "statusbar.h"
#include "wibox.h" #include "wibox.h"
#include "property.h" #include "property.h"
#include "layouts/floating.h" #include "layouts/floating.h"
@ -203,7 +202,7 @@ client_ban(client_t *c)
window_state_set(c->win, XCB_WM_STATE_ICONIC); window_state_set(c->win, XCB_WM_STATE_ICONIC);
else else
window_state_set(c->win, XCB_WM_STATE_WITHDRAWN); window_state_set(c->win, XCB_WM_STATE_WITHDRAWN);
if(c->titlebar && c->titlebar->position) if(c->titlebar)
xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); xcb_unmap_window(globalconf.connection, c->titlebar->sw.window);
} }
@ -260,8 +259,7 @@ client_stack_below(client_t *c, xcb_window_t previous)
config_win_vals[0] = previous; config_win_vals[0] = previous;
config_win_vals[1] = XCB_STACK_MODE_BELOW; config_win_vals[1] = XCB_STACK_MODE_BELOW;
if(c->titlebar if(c->titlebar)
&& c->titlebar->position)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
c->titlebar->sw.window, c->titlebar->sw.window,
@ -314,7 +312,7 @@ client_layer_translator(client_t *c)
* relatively to the first matching in the list. * relatively to the first matching in the list.
*/ */
void void
client_stack(void) client_stack()
{ {
uint32_t config_win_vals[2]; uint32_t config_win_vals[2];
client_node_t *node; client_node_t *node;
@ -330,11 +328,11 @@ client_stack(void)
if(client_layer_translator(node->client) == layer) if(client_layer_translator(node->client) == layer)
config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]); config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]);
/* then stack ontop statusbar window */ /* then stack ontop wibox window */
for(screen = 0; screen < globalconf.nscreen; screen++) for(screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *sb = globalconf.screens[screen].statusbars.tab[i]; wibox_t *sb = globalconf.screens[screen].wiboxes.tab[i];
if(sb->ontop) if(sb->ontop)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
@ -351,11 +349,11 @@ client_stack(void)
if(client_layer_translator(node->client) == layer) if(client_layer_translator(node->client) == layer)
config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]); config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]);
/* then stack not ontop statusbar window */ /* then stack not ontop wibox window */
for(screen = 0; screen < globalconf.nscreen; screen++) for(screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *sb = globalconf.screens[screen].statusbars.tab[i]; wibox_t *sb = globalconf.screens[screen].wiboxes.tab[i];
if(!sb->ontop) if(!sb->ontop)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
@ -588,11 +586,10 @@ client_resize(client_t *c, area_t geometry, bool hints)
* maximized */ * maximized */
if(c->ismoving || client_isfloating(c) if(c->ismoving || client_isfloating(c)
|| layout_get_current(new_screen) == layout_floating) || layout_get_current(new_screen) == layout_floating)
{
titlebar_update_geometry_floating(c);
if(!c->isfullscreen) if(!c->isfullscreen)
c->f_geometry = geometry; c->f_geometry = geometry;
}
titlebar_update_geometry_floating(c);
xcb_configure_window(globalconf.connection, c->win, xcb_configure_window(globalconf.connection, c->win,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
@ -601,17 +598,12 @@ client_resize(client_t *c, area_t geometry, bool hints)
values); values);
window_configure(c->win, geometry, c->border); window_configure(c->win, geometry, c->border);
/* execute hook */
hooks_property(c, "geometry");
if(c->screen != new_screen) if(c->screen != new_screen)
screen_client_moveto(c, new_screen, true, false); screen_client_moveto(c, new_screen, true, false);
}
/* call it again like it was floating, /* execute hook */
* we want it to be sticked to the window */ hooks_property(c, "geometry");
if(!c->ismoving && !client_isfloating(c) && layout != layout_floating) }
titlebar_update_geometry_floating(c);
} }
/** Set a clinet floating. /** Set a clinet floating.
@ -626,13 +618,8 @@ client_setfloating(client_t *c, bool floating)
&& (c->type == WINDOW_TYPE_NORMAL)) && (c->type == WINDOW_TYPE_NORMAL))
{ {
if((c->isfloating = floating)) if((c->isfloating = floating))
{
if(!c->isfullscreen) if(!c->isfullscreen)
{
client_resize(c, c->f_geometry, false); client_resize(c, c->f_geometry, false);
titlebar_update_geometry_floating(c);
}
}
client_need_arrange(c); client_need_arrange(c);
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
client_stack(); client_stack();
@ -852,12 +839,7 @@ client_unmanage(client_t *c)
for(int i = 0; i < tags->len; i++) for(int i = 0; i < tags->len; i++)
untag_client(c, tags->tab[i]); untag_client(c, tags->tab[i]);
if(c->titlebar) titlebar_client_detach(c);
{
xcb_unmap_window(globalconf.connection, c->titlebar->sw.window);
wibox_unref(&c->titlebar);
c->titlebar = NULL;
}
ewmh_update_net_client_list(c->phys_screen); ewmh_update_net_client_list(c->phys_screen);
@ -866,12 +848,12 @@ client_unmanage(client_t *c)
xcb_delete_property(globalconf.connection, c->win, _AWESOME_FLOATING); xcb_delete_property(globalconf.connection, c->win, _AWESOME_FLOATING);
if(client_hasstrut(c)) if(client_hasstrut(c))
/* All the statusbars (may) need to be repositioned */ /* All the wiboxes (may) need to be repositioned */
for(int screen = 0; screen < globalconf.nscreen; screen++) for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; wibox_t *s = globalconf.screens[screen].wiboxes.tab[i];
statusbar_position_update(s); wibox_position_update(s);
} }
/* set client as invalid */ /* set client as invalid */

View File

@ -14,6 +14,7 @@ class
client client
color color
coords coords
east
fg fg
flex flex
floating floating
@ -45,6 +46,7 @@ name
on on
ontop ontop
opacity opacity
orientation
pid pid
plot_data_add plot_data_add
plot_properties_set plot_properties_set
@ -57,6 +59,7 @@ selected
shadow shadow
shadow_offset shadow_offset
show_icons show_icons
south
sticky sticky
text text
ticks_count ticks_count

View File

@ -113,6 +113,8 @@ position_fromstr(const char *pos, ssize_t len)
return Right; return Right;
case A_TK_LEFT: case A_TK_LEFT:
return Left; return Left;
case A_TK_FLOATING:
return Floating;
} }
} }
@ -125,11 +127,47 @@ position_tostr(position_t p)
{ {
switch(p) switch(p)
{ {
case Top: return "top"; case Top: return "top";
case Bottom: return "bottom"; case Bottom: return "bottom";
case Right: return "right"; case Right: return "right";
case Left: return "left"; case Left: return "left";
default: return NULL; case Floating: return "floating";
default: return NULL;
}
}
/** Get a orientation type from a string.
* \param pos The orientation.
* \param len The string length, -1 if unknown.
* \return A orientation.
*/
orientation_t
orientation_fromstr(const char *pos, ssize_t len)
{
switch(a_tokenize(pos, len))
{
default:
return North;
case A_TK_SOUTH:
return South;
case A_TK_EAST:
return East;
}
}
/** Convert a orientation type to a string.
* \param p The orientation.
* \return A orientation string.
*/
const char *
orientation_tostr(orientation_t p)
{
switch(p)
{
case North: return "north";
case South: return "south";
case East: return "east";
default: return NULL;
} }
} }

View File

@ -37,8 +37,9 @@
typedef enum typedef enum
{ {
Horizontal, East,
Vertical South,
North,
} orientation_t; } orientation_t;
/** A list of possible position, not sex related */ /** A list of possible position, not sex related */
@ -47,7 +48,8 @@ typedef enum
Top, Top,
Bottom, Bottom,
Right, Right,
Left Left,
Floating
} position_t; } position_t;
/** Link a name to a function */ /** Link a name to a function */
@ -338,6 +340,8 @@ void _warn(int, const char *, const char *, ...)
position_t position_fromstr(const char *, ssize_t); position_t position_fromstr(const char *, ssize_t);
const char * position_tostr(position_t); const char * position_tostr(position_t);
orientation_t orientation_fromstr(const char *, ssize_t);
const char * orientation_tostr(orientation_t);
void *name_func_lookup(const char *, const name_func_link_t *); void *name_func_lookup(const char *, const name_func_link_t *);
const char * name_func_rlookup(void *, const name_func_link_t *); const char * name_func_rlookup(void *, const name_func_link_t *);
void a_exec(const char *); void a_exec(const char *);

18
draw.h
View File

@ -110,9 +110,21 @@ void draw_context_init(draw_context_t *, int, int, int,
static inline void static inline void
draw_context_wipe(draw_context_t *ctx) draw_context_wipe(draw_context_t *ctx)
{ {
g_object_unref(ctx->layout); if(ctx->layout)
cairo_surface_destroy(ctx->surface); {
cairo_destroy(ctx->cr); g_object_unref(ctx->layout);
ctx->layout = NULL;
}
if(ctx->surface)
{
cairo_surface_destroy(ctx->surface);
ctx->surface = NULL;
}
if(ctx->cr)
{
cairo_destroy(ctx->cr);
ctx->cr = NULL;
}
} }
font_t *draw_font_new(int, const char *); font_t *draw_font_new(int, const char *);

125
event.c
View File

@ -37,7 +37,6 @@
#include "keygrabber.h" #include "keygrabber.h"
#include "luaa.h" #include "luaa.h"
#include "systray.h" #include "systray.h"
#include "statusbar.h"
#include "screen.h" #include "screen.h"
#include "layouts/floating.h" #include "layouts/floating.h"
#include "common/atoms.h" #include "common/atoms.h"
@ -78,7 +77,7 @@ event_handle_mouse_button(client_t *c,
} }
} }
/** Get a widget node from a statusbar by coords. /** Get a widget node from a wibox by coords.
* \param Container position. * \param Container position.
* \param widgets The widget list. * \param widgets The widget list.
* \param width The container width. * \param width The container width.
@ -130,6 +129,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection));
client_t *c; client_t *c;
widget_node_t *w; widget_node_t *w;
wibox_t *wibox;
/* ev->state is /* ev->state is
* button status (8 bits) + modifiers status (8 bits) * button status (8 bits) + modifiers status (8 bits)
@ -137,35 +137,21 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
* drop them */ * drop them */
ev->state &= 0x00ff; ev->state &= 0x00ff;
for(screen = 0; screen < globalconf.nscreen; screen++) if((wibox = wibox_getbywin(ev->event))
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) || (wibox = wibox_getbywin(ev->child)))
{
wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i];
if(statusbar->sw.window == ev->event || statusbar->sw.window == ev->child)
{
/* If the statusbar is child, then x,y are
* relative to root window */
if(statusbar->sw.window == ev->child)
{
ev->event_x -= statusbar->sw.geometry.x;
ev->event_y -= statusbar->sw.geometry.y;
}
if((w = widget_getbycoords(statusbar->position, statusbar->widgets,
statusbar->sw.geometry.width,
statusbar->sw.geometry.height,
&ev->event_x, &ev->event_y)))
w->widget->button(w, ev, statusbar->screen, statusbar);
/* return even if no widget match */
return 0;
}
}
if((c = client_getbytitlebarwin(ev->event)))
{ {
if((w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets, /* If the wibox is child, then x,y are
c->titlebar->geometry.width, c->titlebar->geometry.height, * relative to root window */
if(wibox->sw.window == ev->child)
{
ev->event_x -= wibox->sw.geometry.x;
ev->event_y -= wibox->sw.geometry.y;
}
if((w = widget_getbycoords(wibox->position, wibox->widgets,
wibox->sw.geometry.width,
wibox->sw.geometry.height,
&ev->event_x, &ev->event_y))) &ev->event_x, &ev->event_y)))
w->widget->button(w, ev, c->screen, c->titlebar); w->widget->button(w, ev, wibox->screen, wibox);
/* return even if no widget match */ /* return even if no widget match */
return 0; return 0;
} }
@ -219,14 +205,13 @@ event_handle_configurerequest(void *data __attribute__ ((unused)),
if(client_isfloating(c) || layout_get_current(c->screen) == layout_floating) if(client_isfloating(c) || layout_get_current(c->screen) == layout_floating)
{ {
client_resize(c, geometry, false); client_resize(c, geometry, false);
titlebar_draw(c);
if(client_hasstrut(c)) if(client_hasstrut(c))
/* All the statusbars (may) need to be repositioned */ /* All the wiboxes (may) need to be repositioned */
for(int screen = 0; screen < globalconf.nscreen; screen++) for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; wibox_t *s = globalconf.screens[screen].wiboxes.tab[i];
statusbar_position_update(s); wibox_position_update(s);
} }
} }
else else
@ -239,10 +224,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)),
} }
} }
else else
{
titlebar_update_geometry_floating(c);
window_configure(c->win, geometry, c->border); window_configure(c->win, geometry, c->border);
}
} }
else else
{ {
@ -379,27 +361,16 @@ event_handle_motionnotify(void *data __attribute__ ((unused)),
xcb_connection_t *connection, xcb_connection_t *connection,
xcb_motion_notify_event_t *ev) xcb_motion_notify_event_t *ev)
{ {
wibox_t *statusbar = statusbar_getbywin(ev->event); wibox_t *wibox = wibox_getbywin(ev->event);
client_t *c;
widget_node_t *w; widget_node_t *w;
if(statusbar) if(wibox)
{ {
w = widget_getbycoords(statusbar->position, statusbar->widgets, w = widget_getbycoords(wibox->position, wibox->widgets,
statusbar->sw.geometry.width, wibox->sw.geometry.width,
statusbar->sw.geometry.height, wibox->sw.geometry.height,
&ev->event_x, &ev->event_y); &ev->event_x, &ev->event_y);
event_handle_widget_motionnotify(statusbar, event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w);
&statusbar->mouse_over, w);
}
else if((c = client_getbytitlebarwin(ev->event)))
{
w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets,
c->titlebar->sw.geometry.width,
c->titlebar->sw.geometry.height,
&ev->event_x, &ev->event_y);
event_handle_widget_motionnotify(c->titlebar,
&c->titlebar->mouse_over, w);
} }
return 0; return 0;
@ -415,26 +386,13 @@ event_handle_leavenotify(void *data __attribute__ ((unused)),
xcb_connection_t *connection, xcb_connection_t *connection,
xcb_leave_notify_event_t *ev) xcb_leave_notify_event_t *ev)
{ {
wibox_t *statusbar = statusbar_getbywin(ev->event); wibox_t *wibox = wibox_getbywin(ev->event);
client_t *c;
if(statusbar) if(wibox && wibox->mouse_over)
{ {
if(statusbar->mouse_over) /* call mouse leave function on widget the mouse was over */
{ luaA_wibox_userdata_new(globalconf.L, wibox);
/* call mouse leave function on widget the mouse was over */ luaA_dofunction(globalconf.L, wibox->mouse_over->widget->mouse_leave, 1, 0);
luaA_wibox_userdata_new(globalconf.L, statusbar);
luaA_dofunction(globalconf.L, statusbar->mouse_over->widget->mouse_leave, 1, 0);
}
}
else if((c = client_getbytitlebarwin(ev->event)))
{
if(c->titlebar->mouse_over)
{
/* call mouse leave function on widget the mouse was over */
luaA_wibox_userdata_new(globalconf.L, c->titlebar);
luaA_dofunction(globalconf.L, c->titlebar->mouse_over->widget->mouse_leave, 1, 0);
}
} }
return 0; return 0;
@ -491,25 +449,12 @@ event_handle_expose(void *data __attribute__ ((unused)),
xcb_connection_t *connection __attribute__ ((unused)), xcb_connection_t *connection __attribute__ ((unused)),
xcb_expose_event_t *ev) xcb_expose_event_t *ev)
{ {
client_t *c; wibox_t *wibox = wibox_getbywin(ev->window);
for(int screen = 0; screen < globalconf.nscreen; screen++) if(wibox)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) simplewindow_refresh_pixmap_partial(&wibox->sw,
{ ev->x, ev->y,
wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; ev->width, ev->height);
if(statusbar->sw.window == ev->window)
{
simplewindow_refresh_pixmap_partial(&statusbar->sw,
ev->x, ev->y,
ev->width, ev->height);
return 0;
}
}
if((c = client_getbytitlebarwin(ev->window)))
simplewindow_refresh_pixmap_partial(&c->titlebar->sw,
ev->x, ev->y,
ev->width, ev->height);
return 0; return 0;
} }

13
ewmh.c
View File

@ -31,8 +31,7 @@
#include "client.h" #include "client.h"
#include "widget.h" #include "widget.h"
#include "cnode.h" #include "cnode.h"
#include "titlebar.h" #include "wibox.h"
#include "statusbar.h"
#include "common/atoms.h" #include "common/atoms.h"
extern awesome_t globalconf; extern awesome_t globalconf;
@ -212,7 +211,7 @@ ewmh_update_workarea(int phys_screen)
tag_array_t *tags = &globalconf.screens[phys_screen].tags; tag_array_t *tags = &globalconf.screens[phys_screen].tags;
uint32_t *area = p_alloca(uint32_t, tags->len * 4); uint32_t *area = p_alloca(uint32_t, tags->len * 4);
area_t geom = screen_area_get(phys_screen, area_t geom = screen_area_get(phys_screen,
&globalconf.screens[phys_screen].statusbars, &globalconf.screens[phys_screen].wiboxes,
&globalconf.screens[phys_screen].padding, &globalconf.screens[phys_screen].padding,
true); true);
@ -533,12 +532,12 @@ ewmh_client_strut_update(client_t *c, xcb_get_property_reply_t *strut_r)
c->strut.bottom_end_x = strut[11]; c->strut.bottom_end_x = strut[11];
client_need_arrange(c); client_need_arrange(c);
/* All the statusbars (may) need to be repositioned */ /* All the wiboxes (may) need to be repositioned */
for(int screen = 0; screen < globalconf.nscreen; screen++) for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *s = globalconf.screens[screen].statusbars.tab[i]; wibox_t *s = globalconf.screens[screen].wiboxes.tab[i];
statusbar_position_update(s); wibox_position_update(s);
} }
} }
} }

View File

@ -36,7 +36,7 @@ layout_fair(int screen, const orientation_t orientation)
area_t geometry, area; area_t geometry, area;
area = screen_area_get(screen, area = screen_area_get(screen,
&globalconf.screens[screen].statusbars, &globalconf.screens[screen].wiboxes,
&globalconf.screens[screen].padding, &globalconf.screens[screen].padding,
true); true);
@ -54,7 +54,7 @@ layout_fair(int screen, const orientation_t orientation)
for(c = globalconf.clients; c; c = c->next) for(c = globalconf.clients; c; c = c->next)
if(IS_TILED(c, screen)) if(IS_TILED(c, screen))
{ {
if (orientation == Horizontal) if (orientation == East)
{ {
geometry.width = area.width / u_divisions; geometry.width = area.width / u_divisions;
geometry.height = area.height / v_divisions; geometry.height = area.height / v_divisions;
@ -86,13 +86,13 @@ layout_fair(int screen, const orientation_t orientation)
void void
layout_fairh(int screen) layout_fairh(int screen)
{ {
layout_fair(screen, Horizontal); layout_fair(screen, East);
} }
void void
layout_fairv(int screen) layout_fairv(int screen)
{ {
layout_fair(screen, Vertical); layout_fair(screen, South);
} }
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -33,7 +33,7 @@ layout_fibonacci(int screen, int shape)
client_t *c; client_t *c;
area_t geometry, area; area_t geometry, area;
geometry = area = screen_area_get(screen, geometry = area = screen_area_get(screen,
&globalconf.screens[screen].statusbars, &globalconf.screens[screen].wiboxes,
&globalconf.screens[screen].padding, &globalconf.screens[screen].padding,
true); true);

View File

@ -35,7 +35,7 @@ layout_magnifier(int screen)
client_t *c, *focus; client_t *c, *focus;
tag_t **curtags = tags_get_current(screen); tag_t **curtags = tags_get_current(screen);
area_t geometry, area = screen_area_get(screen, area_t geometry, area = screen_area_get(screen,
&globalconf.screens[screen].statusbars, &globalconf.screens[screen].wiboxes,
&globalconf.screens[screen].padding, &globalconf.screens[screen].padding,
true); true);

View File

@ -31,7 +31,7 @@ layout_max(int screen)
{ {
client_t *c; client_t *c;
area_t area = screen_area_get(screen, area_t area = screen_area_get(screen,
&globalconf.screens[screen].statusbars, &globalconf.screens[screen].wiboxes,
&globalconf.screens[screen].padding, &globalconf.screens[screen].padding,
true); true);

View File

@ -43,7 +43,7 @@ _tile(int screen, const position_t position)
tag_t **curtags = tags_get_current(screen); tag_t **curtags = tags_get_current(screen);
area = screen_area_get(screen, area = screen_area_get(screen,
&globalconf.screens[screen].statusbars, &globalconf.screens[screen].wiboxes,
&globalconf.screens[screen].padding, &globalconf.screens[screen].padding,
true); true);

View File

@ -1515,6 +1515,7 @@ end
-- bg: the background color. -- bg: the background color.
-- fg_focus: the foreground color for focused window. -- fg_focus: the foreground color for focused window.
-- fg_focus: the background color for focused window. -- fg_focus: the background color for focused window.
-- width: the titlebar width
function titlebar.add(c, args) function titlebar.add(c, args)
if not c or c.type ~= "normal" then return end if not c or c.type ~= "normal" then return end
if not args then args = {} end if not args then args = {} end
@ -1524,6 +1525,7 @@ function titlebar.add(c, args)
titlebar.data[c].bg = args.bg or theme.titlebar_bg_normal or theme.bg_normal titlebar.data[c].bg = args.bg or theme.titlebar_bg_normal or theme.bg_normal
titlebar.data[c].fg_focus = args.fg_focus or theme.titlebar_fg_focus or theme.fg_focus titlebar.data[c].fg_focus = args.fg_focus or theme.titlebar_fg_focus or theme.fg_focus
titlebar.data[c].bg_focus = args.bg_focus or theme.titlebar_bg_focus or theme.bg_focus titlebar.data[c].bg_focus = args.bg_focus or theme.titlebar_bg_focus or theme.bg_focus
titlebar.data[c].width = args.width
-- Built args -- Built args
local targs = {} local targs = {}
@ -1578,6 +1580,7 @@ function titlebar.add(c, args)
c.titlebar = tb c.titlebar = tb
titlebar.update(c) titlebar.update(c)
titlebar.update(c, "geometry")
end end
--- Update a titlebar. This should be called in some hooks. --- Update a titlebar. This should be called in some hooks.
@ -1602,6 +1605,17 @@ function titlebar.update(c, prop)
if appicon then if appicon then
appicon.image = c.icon appicon.image = c.icon
end end
elseif prop == "geometry" then
if titlebar.data[c].width then
if c.titlebar.position == "top"
or c.titlebar.position == "bottom" then
local w = math.min(titlebar.data[c].width, c:coords().width + 2 * c.border_width)
c.titlebar:geometry({ width = w })
else
local w = math.min(titlebar.data[c].width, c:coords().height + 2 * c.border_width)
c.titlebar:geometry({ height = w })
end
end
end end
if capi.client.focus == c then if capi.client.focus == c then
c.titlebar.fg = titlebar.data[c].fg_focus c.titlebar.fg = titlebar.data[c].fg_focus

1
luaa.c
View File

@ -46,7 +46,6 @@
#include "client.h" #include "client.h"
#include "screen.h" #include "screen.h"
#include "event.h" #include "event.h"
#include "statusbar.h"
#include "titlebar.h" #include "titlebar.h"
#include "mouse.h" #include "mouse.h"
#include "layouts/tile.h" #include "layouts/tile.h"

45
mouse.c
View File

@ -27,7 +27,7 @@
#include "tag.h" #include "tag.h"
#include "client.h" #include "client.h"
#include "titlebar.h" #include "titlebar.h"
#include "statusbar.h" #include "wibox.h"
#include "layouts/floating.h" #include "layouts/floating.h"
#include "layouts/tile.h" #include "layouts/tile.h"
#include "layouts/magnifier.h" #include "layouts/magnifier.h"
@ -132,7 +132,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap)
area_t snapper_geometry; area_t snapper_geometry;
area_t screen_geometry = area_t screen_geometry =
screen_area_get(c->screen, screen_area_get(c->screen,
&globalconf.screens[c->screen].statusbars, &globalconf.screens[c->screen].wiboxes,
&globalconf.screens[c->screen].padding, &globalconf.screens[c->screen].padding,
false); false);
@ -239,8 +239,7 @@ mouse_snap_to_corner(area_t a, int *x, int *y, corner_t corner)
* \param border The client border size. * \param border The client border size.
*/ */
static void static void
mouse_infobox_draw(simple_window_t *sw, mouse_infobox_draw(simple_window_t *sw, area_t geometry, int border)
area_t geometry, int border)
{ {
area_t draw_geometry = { 0, 0, sw->ctx.width, sw->ctx.height }; area_t draw_geometry = { 0, 0, sw->ctx.width, sw->ctx.height };
char size[64]; char size[64];
@ -282,10 +281,9 @@ mouse_infobox_new(simple_window_t *sw, int phys_screen, int border, area_t geome
geom.x = geometry.x + ((2 * border + geometry.width) - geom.width) / 2; geom.x = geometry.x + ((2 * border + geometry.width) - geom.width) / 2;
geom.y = geometry.y + ((2 * border + geometry.height) - geom.height) / 2; geom.y = geometry.y + ((2 * border + geometry.height) - geom.height) / 2;
simplewindow_init(sw, phys_screen, p_clear(sw, 1);
geom.x, geom.y, simplewindow_init(sw, phys_screen, geom, 0, East,
geom.width, geom.height, 0, &globalconf.colors.fg, &globalconf.colors.bg);
Top, &globalconf.colors.fg, &globalconf.colors.bg);
xcb_map_window(globalconf.connection, sw->window); xcb_map_window(globalconf.connection, sw->window);
mouse_infobox_draw(sw, geometry, border); mouse_infobox_draw(sw, geometry, border);
@ -520,7 +518,9 @@ mouse_client_move(client_t *c, int snap, bool infobox)
if(infobox) if(infobox)
mouse_infobox_draw(&sw, c->geometry, c->border); mouse_infobox_draw(&sw, c->geometry, c->border);
statusbar_refresh(); /* refresh live */
wibox_refresh();
xcb_flush(globalconf.connection);
/* keep track */ /* keep track */
last_x = mouse_x; last_x = mouse_x;
@ -539,8 +539,8 @@ mouse_client_move(client_t *c, int snap, bool infobox)
globalconf.screens[c->screen].need_arrange = true; globalconf.screens[c->screen].need_arrange = true;
globalconf.screens[newscreen].need_arrange = true; globalconf.screens[newscreen].need_arrange = true;
layout_refresh(); layout_refresh();
titlebar_refresh(); wibox_refresh();
statusbar_refresh(); xcb_flush(globalconf.connection);
} }
/* find client to swap with */ /* find client to swap with */
@ -552,7 +552,8 @@ mouse_client_move(client_t *c, int snap, bool infobox)
client_list_swap(&globalconf.clients, c, target); client_list_swap(&globalconf.clients, c, target);
globalconf.screens[c->screen].need_arrange = true; globalconf.screens[c->screen].need_arrange = true;
layout_refresh(); layout_refresh();
titlebar_refresh(); wibox_refresh();
xcb_flush(globalconf.connection);
} }
} }
@ -695,8 +696,10 @@ mouse_client_resize_floating(client_t *c, corner_t corner, bool infobox)
/* resize the client */ /* resize the client */
client_resize(c, geo, false); client_resize(c, geo, false);
/* redaw titlebar live */
titlebar_draw(c); /* refresh live */
wibox_refresh();
xcb_flush(globalconf.connection);
/* draw the infobox */ /* draw the infobox */
if(infobox) if(infobox)
@ -718,7 +721,7 @@ static void
mouse_client_resize_tiled(client_t *c) mouse_client_resize_tiled(client_t *c)
{ {
xcb_screen_t *screen; xcb_screen_t *screen;
/* screen area modulo statusbar */ /* screen area modulo wibox */
area_t area; area_t area;
/* current tag */ /* current tag */
tag_t *tag; tag_t *tag;
@ -733,7 +736,7 @@ mouse_client_resize_tiled(client_t *c)
layout = tag->layout; layout = tag->layout;
area = screen_area_get(tag->screen, area = screen_area_get(tag->screen,
&globalconf.screens[tag->screen].statusbars, &globalconf.screens[tag->screen].wiboxes,
&globalconf.screens[tag->screen].padding, &globalconf.screens[tag->screen].padding,
true); true);
@ -799,7 +802,8 @@ mouse_client_resize_tiled(client_t *c)
tag->mwfact = mwfact; tag->mwfact = mwfact;
globalconf.screens[tag->screen].need_arrange = true; globalconf.screens[tag->screen].need_arrange = true;
layout_refresh(); layout_refresh();
titlebar_refresh(); wibox_refresh();
xcb_flush(globalconf.connection);
} }
} }
@ -814,7 +818,7 @@ mouse_client_resize_tiled(client_t *c)
static void static void
mouse_client_resize_magnified(client_t *c, bool infobox) mouse_client_resize_magnified(client_t *c, bool infobox)
{ {
/* screen area modulo statusbar */ /* screen area modulo wibox */
area_t area; area_t area;
/* center of area */ /* center of area */
int center_x, center_y; int center_x, center_y;
@ -836,7 +840,7 @@ mouse_client_resize_magnified(client_t *c, bool infobox)
root = xutil_screen_get(globalconf.connection, c->phys_screen)->root; root = xutil_screen_get(globalconf.connection, c->phys_screen)->root;
area = screen_area_get(tag->screen, area = screen_area_get(tag->screen,
&globalconf.screens[tag->screen].statusbars, &globalconf.screens[tag->screen].wiboxes,
&globalconf.screens[tag->screen].padding, &globalconf.screens[tag->screen].padding,
true); true);
@ -904,7 +908,8 @@ mouse_client_resize_magnified(client_t *c, bool infobox)
tag->mwfact = mwfact; tag->mwfact = mwfact;
globalconf.screens[tag->screen].need_arrange = true; globalconf.screens[tag->screen].need_arrange = true;
layout_refresh(); layout_refresh();
titlebar_refresh(); wibox_refresh();
xcb_flush(globalconf.connection);
} }
/* draw the infobox */ /* draw the infobox */

View File

@ -28,8 +28,8 @@
#include "ewmh.h" #include "ewmh.h"
#include "tag.h" #include "tag.h"
#include "client.h" #include "client.h"
#include "statusbar.h"
#include "widget.h" #include "widget.h"
#include "wibox.h"
#include "layouts/tile.h" #include "layouts/tile.h"
extern awesome_t globalconf; extern awesome_t globalconf;
@ -156,13 +156,13 @@ screen_getbycoord(int screen, int x, int y)
/** Get screens info. /** Get screens info.
* \param screen Screen number. * \param screen Screen number.
* \param statusbars Statusbar list to remove. * \param wiboxes Wiboxes list to remove.
* \param padding Padding. * \param padding Padding.
* \param strut Honor windows strut. * \param strut Honor windows strut.
* \return The screen area. * \return The screen area.
*/ */
area_t area_t
screen_area_get(int screen, wibox_array_t *statusbars, screen_area_get(int screen, wibox_array_t *wiboxes,
padding_t *padding, bool strut) padding_t *padding, bool strut)
{ {
area_t area = globalconf.screens[screen].geometry; area_t area = globalconf.screens[screen].geometry;
@ -215,24 +215,24 @@ screen_area_get(int screen, wibox_array_t *statusbars,
} }
if(statusbars) if(wiboxes)
for(int i = 0; i < statusbars->len; i++) for(int i = 0; i < wiboxes->len; i++)
{ {
wibox_t *sb = statusbars->tab[i]; wibox_t *w = wiboxes->tab[i];
if(sb->isvisible) if(w->isvisible)
switch(sb->position) switch(w->position)
{ {
case Top: case Top:
top = MAX(top, (uint16_t) (sb->sw.geometry.y - area.y) + sb->sw.geometry.height); top = MAX(top, (uint16_t) (w->sw.geometry.y - area.y) + w->sw.geometry.height);
break; break;
case Bottom: case Bottom:
bottom = MAX(bottom, (uint16_t) (area.y + area.height) - sb->sw.geometry.y); bottom = MAX(bottom, (uint16_t) (area.y + area.height) - w->sw.geometry.y);
break; break;
case Left: case Left:
left = MAX(left, (uint16_t) (sb->sw.geometry.x - area.x) + sb->sw.geometry.width); left = MAX(left, (uint16_t) (w->sw.geometry.x - area.x) + w->sw.geometry.width);
break; break;
case Right: case Right:
right = MAX(right, (uint16_t) (area.x + area.width) - sb->sw.geometry.x); right = MAX(right, (uint16_t) (area.x + area.width) - w->sw.geometry.x);
break; break;
default: default:
break; break;
@ -249,12 +249,12 @@ screen_area_get(int screen, wibox_array_t *statusbars,
/** Get display info. /** Get display info.
* \param phys_screen Physical screen number. * \param phys_screen Physical screen number.
* \param statusbars The statusbars. * \param wiboxes The wiboxes.
* \param padding Padding. * \param padding Padding.
* \return The display area. * \return The display area.
*/ */
area_t area_t
display_area_get(int phys_screen, wibox_array_t *statusbars, padding_t *padding) display_area_get(int phys_screen, wibox_array_t *wiboxes, padding_t *padding)
{ {
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
area_t area = { .x = 0, area_t area = { .x = 0,
@ -262,12 +262,12 @@ display_area_get(int phys_screen, wibox_array_t *statusbars, padding_t *padding)
.width = s->width_in_pixels, .width = s->width_in_pixels,
.height = s->height_in_pixels }; .height = s->height_in_pixels };
if(statusbars) if(wiboxes)
for(int i = 0; i < statusbars->len; i++) for(int i = 0; i < wiboxes->len; i++)
{ {
wibox_t *sb = statusbars->tab[i]; wibox_t *w = wiboxes->tab[i];
area.y += sb->position == Top ? sb->geometry.height : 0; area.y += w->position == Top ? w->sw.geometry.height : 0;
area.height -= (sb->position == Top || sb->position == Bottom) ? sb->geometry.height : 0; area.height -= (w->position == Top || w->position == Bottom) ? w->sw.geometry.height : 0;
} }
/* make padding corrections */ /* make padding corrections */
@ -312,6 +312,9 @@ screen_client_moveto(client_t *c, int new_screen, bool dotag, bool doresize)
c->screen = new_screen; c->screen = new_screen;
if(c->titlebar)
c->titlebar->screen = new_screen;
widget_invalidate_cache(old_screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(old_screen, WIDGET_CACHE_CLIENTS);
widget_invalidate_cache(new_screen, WIDGET_CACHE_CLIENTS); widget_invalidate_cache(new_screen, WIDGET_CACHE_CLIENTS);
@ -482,7 +485,7 @@ luaA_screen_tags(lua_State *L)
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
* \luastack * \luastack
* \lfield coords The screen coordinates. Immutable. * \lfield coords The screen coordinates. Immutable.
* \lfield workarea The screen workarea, i.e. without statusbar. * \lfield workarea The screen workarea, i.e. without wiboxes.
*/ */
static int static int
luaA_screen_index(lua_State *L) luaA_screen_index(lua_State *L)
@ -503,7 +506,7 @@ luaA_screen_index(lua_State *L)
luaA_pusharea(L, s->geometry); luaA_pusharea(L, s->geometry);
break; break;
case A_TK_WORKAREA: case A_TK_WORKAREA:
luaA_pusharea(L, screen_area_get(s->index, &s->statusbars, &s->padding, true)); luaA_pusharea(L, screen_area_get(s->index, &s->wiboxes, &s->padding, true));
break; break;
default: default:
return 0; return 0;
@ -539,9 +542,9 @@ luaA_screen_padding(lua_State *L)
s->need_arrange = true; s->need_arrange = true;
/* All the statusbar repositioned */ /* All the wiboxes repositioned */
for(int i = 0; i < s->statusbars.len; i++) for(int i = 0; i < s->wiboxes.len; i++)
statusbar_position_update(s->statusbars.tab[i]); wibox_position_update(s->wiboxes.tab[i]);
ewmh_update_workarea(screen_virttophys(s->index)); ewmh_update_workarea(screen_virttophys(s->index));
} }

View File

@ -19,440 +19,8 @@
* *
*/ */
#include <xcb/xcb.h> #include "luaa.h"
#include "client.h"
#include "statusbar.h"
#include "screen.h"
#include "widget.h"
#include "wibox.h" #include "wibox.h"
#include "ewmh.h"
extern awesome_t globalconf;
/** Kick out systray windows.
* \param phys_screen Physical screen number.
*/
static void
statusbar_systray_kickout(int phys_screen)
{
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
/* Who! Check that we're not deleting a statusbar with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
xcb_reparent_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
s->root, -512, -512);
globalconf.screens[phys_screen].systray.parent = s->root;
}
static void
statusbar_systray_refresh(wibox_t *statusbar)
{
widget_node_t *systray;
if(statusbar->screen == SCREEN_UNDEF)
return;
for(systray = statusbar->widgets; systray; systray = systray->next)
if(systray->widget->type == systray_new)
{
uint32_t config_back[] = { statusbar->colors.bg.pixel };
uint32_t config_win_vals[4];
uint32_t config_win_vals_off[2] = { -512, -512 };
xembed_window_t *em;
position_t pos;
int phys_screen = statusbar->sw.ctx.phys_screen;
if(statusbar->isvisible
&& systray->widget->isvisible
&& systray->area.width)
{
pos = statusbar->position;
/* Set background of the systray window. */
xcb_change_window_attributes(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
XCB_CW_BACK_PIXEL, config_back);
/* Map it. */
xcb_map_window(globalconf.connection, globalconf.screens[phys_screen].systray.window);
/* Move it. */
switch(statusbar->position)
{
case Left:
config_win_vals[0] = systray->area.y;
config_win_vals[1] = statusbar->sw.geometry.height - systray->area.x - systray->area.width;
config_win_vals[2] = systray->area.height;
config_win_vals[3] = systray->area.width;
break;
case Right:
config_win_vals[0] = systray->area.y;
config_win_vals[1] = systray->area.x;
config_win_vals[2] = systray->area.height;
config_win_vals[3] = systray->area.width;
break;
default:
config_win_vals[0] = systray->area.x;
config_win_vals[1] = systray->area.y;
config_win_vals[2] = systray->area.width;
config_win_vals[3] = systray->area.height;
break;
}
/* reparent */
if(globalconf.screens[phys_screen].systray.parent != statusbar->sw.window)
{
xcb_reparent_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
statusbar->sw.window,
config_win_vals[0], config_win_vals[1]);
globalconf.screens[phys_screen].systray.parent = statusbar->sw.window;
}
xcb_configure_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
| XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT,
config_win_vals);
/* width = height = systray height */
config_win_vals[2] = config_win_vals[3] = systray->area.height;
config_win_vals[0] = 0;
}
else
{
xcb_unmap_window(globalconf.connection, globalconf.screens[phys_screen].systray.window);
statusbar_systray_kickout(phys_screen);
break;
}
switch(pos)
{
case Left:
config_win_vals[1] = systray->area.width - config_win_vals[3];
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) 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,
config_win_vals_off);
}
break;
case Right:
config_win_vals[1] = 0;
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) statusbar->sw.geometry.y + statusbar->sw.geometry.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,
config_win_vals_off);
}
break;
case Top:
case Bottom:
config_win_vals[1] = 0;
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(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,
config_win_vals_off);
}
break;
}
break;
}
}
/** Draw a statusbar.
* \param statusbar The statusbar to draw.
*/
static void
statusbar_draw(wibox_t *statusbar)
{
statusbar->need_update = false;
if(statusbar->isvisible)
{
widget_render(statusbar->widgets, &statusbar->sw.ctx, statusbar->sw.gc,
statusbar->sw.pixmap,
statusbar->screen, statusbar->position,
statusbar->sw.geometry.x, statusbar->sw.geometry.y,
statusbar);
simplewindow_refresh_pixmap(&statusbar->sw);
}
statusbar_systray_refresh(statusbar);
}
/** Get a statusbar by its window.
* \param w The window id.
* \return A statusbar if found, NULL otherwise.
*/
wibox_t *
statusbar_getbywin(xcb_window_t w)
{
for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++)
{
wibox_t *s = globalconf.screens[screen].statusbars.tab[i];
if(s->sw.window == w)
return s;
}
return NULL;
}
/** Statusbar refresh function.
*/
void
statusbar_refresh(void)
{
for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++)
{
wibox_t *s = globalconf.screens[screen].statusbars.tab[i];
if(s->need_update)
statusbar_draw(s);
}
}
/** Update the statusbar position. It deletes every statusbar resources and
* create them back.
* \param statusbar The statusbar.
*/
void
statusbar_position_update(wibox_t *statusbar)
{
area_t area;
bool ignore = false;
globalconf.screens[statusbar->screen].need_arrange = true;
if(!statusbar->isvisible)
{
xcb_unmap_window(globalconf.connection, statusbar->sw.window);
/* kick out systray if needed */
statusbar_systray_refresh(statusbar);
return;
}
area = screen_area_get(statusbar->screen, NULL,
&globalconf.screens[statusbar->screen].padding, true);
/* Top and Bottom wibox_t have prio */
for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++)
{
wibox_t *sb = globalconf.screens[statusbar->screen].statusbars.tab[i];
/* Ignore every statusbar after me that is in the same position */
if(statusbar == sb)
{
ignore = true;
continue;
}
else if(ignore && statusbar->position == sb->position)
continue;
switch(sb->position)
{
case Left:
switch(statusbar->position)
{
case Left:
area.x += statusbar->geometry.height;
break;
default:
break;
}
break;
case Right:
switch(statusbar->position)
{
case Right:
area.x -= statusbar->geometry.height;
break;
default:
break;
}
break;
case Top:
switch(statusbar->position)
{
case Top:
area.y += sb->geometry.height;
break;
case Left:
case Right:
area.height -= sb->geometry.height;
area.y += sb->geometry.height;
break;
default:
break;
}
break;
case Bottom:
switch(statusbar->position)
{
case Bottom:
area.y -= sb->geometry.height;
break;
case Left:
case Right:
area.height -= sb->geometry.height;
break;
default:
break;
}
break;
}
}
switch(statusbar->position)
{
case Right:
statusbar->geometry.height = area.height;
statusbar->geometry.width = 1.5 * globalconf.font->height;
switch(statusbar->align)
{
default:
statusbar->geometry.x = area.x + area.width - statusbar->geometry.width;
statusbar->geometry.y = area.y;
break;
case AlignRight:
statusbar->geometry.x = area.x + area.width - statusbar->geometry.width;
statusbar->geometry.y = area.y + area.height - statusbar->geometry.height;
break;
case AlignCenter:
statusbar->geometry.x = area.x + area.width - statusbar->geometry.width;
statusbar->geometry.y = (area.y + area.height - statusbar->geometry.height) / 2;
break;
}
break;
case Left:
statusbar->geometry.height = area.height;
statusbar->geometry.width = 1.5 * globalconf.font->height;
switch(statusbar->align)
{
default:
statusbar->geometry.x = area.x;
statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height;
break;
case AlignRight:
statusbar->geometry.x = area.x;
statusbar->geometry.y = area.y;
break;
case AlignCenter:
statusbar->geometry.x = area.x;
statusbar->geometry.y = (area.y + area.height - statusbar->geometry.height) / 2;
}
break;
case Bottom:
statusbar->geometry.width = area.width;
statusbar->geometry.height = 1.5 * globalconf.font->height;
switch(statusbar->align)
{
default:
statusbar->geometry.x = area.x;
statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height;
break;
case AlignRight:
statusbar->geometry.x = area.x + area.width - statusbar->geometry.width;
statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height;
break;
case AlignCenter:
statusbar->geometry.x = area.x + (area.width - statusbar->geometry.width) / 2;
statusbar->geometry.y = (area.y + area.height) - statusbar->geometry.height;
break;
}
break;
default:
statusbar->geometry.width = area.width;
statusbar->geometry.height = 1.5 * globalconf.font->height;
switch(statusbar->align)
{
default:
statusbar->geometry.x = area.x;
statusbar->geometry.y = area.y;
break;
case AlignRight:
statusbar->geometry.x = area.x + area.width - statusbar->geometry.width;
statusbar->geometry.y = area.y;
break;
case AlignCenter:
statusbar->geometry.x = area.x + (area.width - statusbar->geometry.width) / 2;
statusbar->geometry.y = area.y;
break;
}
break;
}
if(!statusbar->sw.window)
{
int phys_screen = screen_virttophys(statusbar->screen);
simplewindow_init(&statusbar->sw, phys_screen,
statusbar->geometry.x, statusbar->geometry.y,
statusbar->geometry.width, statusbar->geometry.height,
0, statusbar->position,
&statusbar->colors.fg, &statusbar->colors.bg);
statusbar->need_update = true;
}
/* same window size and position ? */
else
{
if(statusbar->geometry.width != statusbar->sw.geometry.width
|| statusbar->geometry.height != statusbar->sw.geometry.height)
{
simplewindow_resize(&statusbar->sw, statusbar->geometry.width, statusbar->geometry.height);
statusbar->need_update = true;
}
if(statusbar->geometry.x != statusbar->sw.geometry.x
|| statusbar->geometry.y != statusbar->sw.geometry.y)
simplewindow_move(&statusbar->sw, statusbar->geometry.x, statusbar->geometry.y);
}
xcb_map_window(globalconf.connection, statusbar->sw.window);
}
/** Create a new statusbar (DEPRECATED). /** Create a new statusbar (DEPRECATED).
* \param L The Lua VM state. * \param L The Lua VM state.
@ -470,106 +38,6 @@ luaA_statusbar_new(lua_State *L)
return luaA_wibox_new(L); return luaA_wibox_new(L);
} }
/** Remove a statubar from a screen.
* \param statusbar Statusbar to detach from screen.
*/
void
statusbar_detach(wibox_t *statusbar)
{
if(statusbar->screen != SCREEN_UNDEF)
{
bool v;
/* save visible state */
v = statusbar->isvisible;
statusbar->isvisible = false;
statusbar_position_update(statusbar);
/* restore position */
statusbar->isvisible = v;
simplewindow_wipe(&statusbar->sw);
for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++)
if(globalconf.screens[statusbar->screen].statusbars.tab[i] == statusbar)
{
wibox_array_take(&globalconf.screens[statusbar->screen].statusbars, i);
break;
}
globalconf.screens[statusbar->screen].need_arrange = true;
statusbar->screen = SCREEN_UNDEF;
statusbar->type = WIBOX_TYPE_NONE;
wibox_unref(&statusbar);
}
}
/** Attach a statusbar.
* \param statusbar The statusbar to attach.
* \param s The screen to attach the statusbar to.
*/
void
statusbar_attach(wibox_t *statusbar, screen_t *s)
{
statusbar_detach(statusbar);
statusbar->screen = s->index;
wibox_array_append(&s->statusbars, wibox_ref(&statusbar));
statusbar->type = WIBOX_TYPE_STATUSBAR;
/* All the other statusbar and ourselves need to be repositioned */
for(int i = 0; i < s->statusbars.len; i++)
statusbar_position_update(s->statusbars.tab[i]);
ewmh_update_workarea(screen_virttophys(s->index));
}
/** Statusbar newindex.
* \param L The Lua VM state.
* \param statusbar The wibox statusbar.
* \param tok The token for property.
* \return The number of elements pushed on stack.
*/
int
luaA_statusbar_newindex(lua_State *L, wibox_t *statusbar, awesome_token_t tok)
{
size_t len;
const char *buf;
position_t p;
switch(tok)
{
case A_TK_ALIGN:
buf = luaL_checklstring(L, 3, &len);
statusbar->align = draw_align_fromstr(buf, len);
statusbar_position_update(statusbar);
break;
case A_TK_POSITION:
buf = luaL_checklstring(L, 3, &len);
p = position_fromstr(buf, len);
if(p != statusbar->position)
{
statusbar->position = p;
simplewindow_wipe(&statusbar->sw);
statusbar->sw.window = 0;
if(statusbar->screen != SCREEN_UNDEF)
{
for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++)
{
wibox_t *s = globalconf.screens[statusbar->screen].statusbars.tab[i];
statusbar_position_update(s);
}
ewmh_update_workarea(screen_virttophys(statusbar->screen));
}
}
break;
default:
return 0;
}
return 0;
}
const struct luaL_reg awesome_statusbar_methods[] = const struct luaL_reg awesome_statusbar_methods[] =
{ {
{ "__call", luaA_statusbar_new }, { "__call", luaA_statusbar_new },

View File

@ -1,38 +0,0 @@
/*
* wibox.h - wibox functions header
*
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef AWESOME_WIBOX_H
#define AWESOME_WIBOX_H
#include "structs.h"
#include "swindow.h"
#include "common/refcount.h"
wibox_t * statusbar_getbywin(xcb_window_t);
void statusbar_refresh(void);
void statusbar_position_update(wibox_t *);
void statusbar_detach(wibox_t *);
void statusbar_attach(wibox_t *, screen_t *);
int luaA_statusbar_newindex(lua_State *, wibox_t *, awesome_token_t);
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -62,8 +62,7 @@ typedef enum
/** Wibox types */ /** Wibox types */
typedef enum typedef enum
{ {
WIBOX_TYPE_NONE = 0, WIBOX_TYPE_NORMAL = 0,
WIBOX_TYPE_STATUSBAR,
WIBOX_TYPE_TITLEBAR WIBOX_TYPE_TITLEBAR
} wibox_type_t; } wibox_type_t;
@ -94,14 +93,12 @@ typedef struct
bool ontop; bool ontop;
/** Visible */ /** Visible */
bool isvisible; bool isvisible;
/** Position */
position_t position;
/** Wibox type */ /** Wibox type */
wibox_type_t type; wibox_type_t type;
/** Window */ /** Window */
simple_window_t sw; simple_window_t sw;
/** Box geometry */
area_t geometry;
/** Box position */
position_t position;
/** Alignment */ /** Alignment */
alignment_t align; alignment_t align;
/** Screen */ /** Screen */
@ -112,16 +109,6 @@ typedef struct
widget_node_t *mouse_over; widget_node_t *mouse_over;
/** Need update */ /** Need update */
bool need_update; bool need_update;
/** Default colors */
struct
{
xcolor_t fg, bg;
} colors;
struct
{
xcolor_t color;
uint16_t width;
} border;
} wibox_t; } wibox_t;
ARRAY_TYPE(wibox_t *, wibox) ARRAY_TYPE(wibox_t *, wibox)
@ -367,8 +354,8 @@ typedef struct
bool need_arrange; bool need_arrange;
/** Tag list */ /** Tag list */
tag_array_t tags; tag_array_t tags;
/** Statusbars */ /** Wiboxes */
wibox_array_t statusbars; wibox_array_t wiboxes;
/** Padding */ /** Padding */
padding_t padding; padding_t padding;
/** Window that contains the systray */ /** Window that contains the systray */

193
swindow.c
View File

@ -30,25 +30,52 @@
extern awesome_t globalconf; extern awesome_t globalconf;
static void
simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s)
{
xcolor_t fg = sw->ctx.fg, bg = sw->ctx.bg;
int phys_screen = sw->ctx.phys_screen;
draw_context_wipe(&sw->ctx);
/* update draw context */
switch(sw->orientation)
{
case South:
case North:
/* we need a new pixmap this way [ ] to render */
sw->ctx.pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection,
s->root_depth,
sw->ctx.pixmap, s->root,
sw->geometry.height, sw->geometry.width);
draw_context_init(&sw->ctx, phys_screen,
sw->geometry.height, sw->geometry.width,
sw->ctx.pixmap, &fg, &bg);
break;
case East:
draw_context_init(&sw->ctx, phys_screen,
sw->geometry.width, sw->geometry.height,
sw->pixmap, &fg, &bg);
break;
}
}
/** Initialize a simple window. /** Initialize a simple window.
* \param sw The simple window to initialize. * \param sw The simple window to initialize.
* \param phys_screen Physical screen number. * \param phys_screen Physical screen number.
* \param x x coordinate. * \param geometry Window geometry.
* \param y y coordinate.
* \param w Width.
* \param h Height.
* \param border_width Window border width. * \param border_width Window border width.
* \param position The rendering position. * \param orientation The rendering orientation.
* \param bg Default foreground color. * \param bg Default foreground color.
* \param bg Default background color. * \param bg Default background color.
*/ */
void void
simplewindow_init(simple_window_t *sw, simplewindow_init(simple_window_t *sw,
int phys_screen, int phys_screen,
int16_t x, int16_t y, area_t geometry,
uint16_t w, uint16_t h,
uint16_t border_width, uint16_t border_width,
position_t position, orientation_t orientation,
const xcolor_t *fg, const xcolor_t *bg) const xcolor_t *fg, const xcolor_t *bg)
{ {
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
@ -56,10 +83,14 @@ simplewindow_init(simple_window_t *sw,
const uint32_t gc_mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; const uint32_t gc_mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
const uint32_t gc_values[2] = { s->black_pixel, s->white_pixel }; const uint32_t gc_values[2] = { s->black_pixel, s->white_pixel };
sw->geometry.x = x; sw->geometry.x = geometry.x;
sw->geometry.y = y; sw->geometry.y = geometry.y;
sw->geometry.width = w; sw->geometry.width = geometry.width;
sw->geometry.height = h; sw->geometry.height = geometry.height;
sw->border.width = border_width;
sw->orientation = orientation;
sw->ctx.fg = *fg;
sw->ctx.bg = *bg;
create_win_val[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE; create_win_val[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE;
create_win_val[1] = 1; create_win_val[1] = 1;
@ -70,39 +101,21 @@ simplewindow_init(simple_window_t *sw,
| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE; | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE;
sw->window = xcb_generate_id(globalconf.connection); sw->window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root, x, y, w, h, xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root,
geometry.x, geometry.y, geometry.width, geometry.height,
border_width, XCB_COPY_FROM_PARENT, s->root_visual, border_width, XCB_COPY_FROM_PARENT, s->root_visual,
XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
create_win_val); create_win_val);
sw->pixmap = xcb_generate_id(globalconf.connection); sw->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, w, h); xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root,
geometry.width, geometry.height);
switch(position) simplewindow_draw_context_update(sw, s);
{
xcb_pixmap_t pixmap;
case Left:
case Right:
/* we need a new pixmap this way [ ] to render */
pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection,
s->root_depth,
pixmap, s->root, h, w);
draw_context_init(&sw->ctx, phys_screen,
h, w, pixmap, fg, bg);
break;
default:
draw_context_init(&sw->ctx, phys_screen,
w, h, sw->pixmap, fg, bg);
break;
}
/* The default GC is just a newly created associated to the root window */ /* The default GC is just a newly created associated to the root window */
sw->gc = xcb_generate_id(globalconf.connection); sw->gc = xcb_generate_id(globalconf.connection);
xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values); xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values);
sw->border.width = border_width;
sw->position = position;
} }
/** Destroy all resources of a simple window. /** Destroy all resources of a simple window.
@ -111,12 +124,21 @@ simplewindow_init(simple_window_t *sw,
void void
simplewindow_wipe(simple_window_t *sw) simplewindow_wipe(simple_window_t *sw)
{ {
xcb_destroy_window(globalconf.connection, sw->window); if(sw->window)
sw->window = XCB_NONE; {
xcb_free_pixmap(globalconf.connection, sw->pixmap); xcb_destroy_window(globalconf.connection, sw->window);
sw->pixmap = XCB_NONE; sw->window = XCB_NONE;
xcb_free_gc(globalconf.connection, sw->gc); }
sw->gc = XCB_NONE; if(sw->pixmap)
{
xcb_free_pixmap(globalconf.connection, sw->pixmap);
sw->pixmap = XCB_NONE;
}
if(sw->gc)
{
xcb_free_gc(globalconf.connection, sw->gc);
sw->gc = XCB_NONE;
}
draw_context_wipe(&sw->ctx); draw_context_wipe(&sw->ctx);
} }
@ -130,41 +152,13 @@ simplewindow_move(simple_window_t *sw, int x, int y)
{ {
const uint32_t move_win_vals[] = { x, y }; const uint32_t move_win_vals[] = { x, y };
sw->geometry.x = x; if(x != sw->geometry.x || y != sw->geometry.y)
sw->geometry.y = y;
xcb_configure_window(globalconf.connection, sw->window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
move_win_vals);
}
static void
simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s)
{
xcolor_t fg = sw->ctx.fg, bg = sw->ctx.bg;
int phys_screen = sw->ctx.phys_screen;
draw_context_wipe(&sw->ctx);
/* update draw context */
switch(sw->position)
{ {
case Left: sw->geometry.x = x;
case Right: sw->geometry.y = y;
/* we need a new pixmap this way [ ] to render */ xcb_configure_window(globalconf.connection, sw->window,
sw->ctx.pixmap = xcb_generate_id(globalconf.connection); XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
xcb_create_pixmap(globalconf.connection, move_win_vals);
s->root_depth,
sw->ctx.pixmap, s->root,
sw->geometry.height, sw->geometry.width);
draw_context_init(&sw->ctx, phys_screen,
sw->geometry.height, sw->geometry.width,
sw->ctx.pixmap, &fg, &bg);
break;
default:
draw_context_init(&sw->ctx, phys_screen,
sw->geometry.width, sw->geometry.height,
sw->pixmap, &fg, &bg);
break;
} }
} }
@ -184,6 +178,9 @@ simplewindow_resize(simple_window_t *sw, int w, int h)
sw->geometry.width = resize_win_vals[0] = w; sw->geometry.width = resize_win_vals[0] = w;
sw->geometry.height = resize_win_vals[1] = h; sw->geometry.height = resize_win_vals[1] = h;
xcb_free_pixmap(globalconf.connection, sw->pixmap); xcb_free_pixmap(globalconf.connection, sw->pixmap);
/* orientation != East */
if(sw->pixmap != sw->ctx.pixmap)
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
sw->pixmap = xcb_generate_id(globalconf.connection); sw->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, w, h); xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, w, h);
xcb_configure_window(globalconf.connection, sw->window, xcb_configure_window(globalconf.connection, sw->window,
@ -195,40 +192,40 @@ simplewindow_resize(simple_window_t *sw, int w, int h)
/** Move and resize a window in one call. /** Move and resize a window in one call.
* \param sw The simple window to move and resize. * \param sw The simple window to move and resize.
* \param x The new x coordinate. * \param geom The new gometry.
* \param y The new y coordinate.
* \param w The new width.
* \param h The new height.
*/ */
void void
simplewindow_moveresize(simple_window_t *sw, int x, int y, int w, int h) simplewindow_moveresize(simple_window_t *sw, area_t geom)
{ {
uint32_t moveresize_win_vals[4], mask_vals = 0; uint32_t moveresize_win_vals[4], mask_vals = 0;
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen); xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
if(sw->geometry.x != x || sw->geometry.y != y) if(sw->geometry.x != geom.x || sw->geometry.y != geom.y)
{ {
sw->geometry.x = moveresize_win_vals[0] = x; sw->geometry.x = moveresize_win_vals[0] = geom.x;
sw->geometry.y = moveresize_win_vals[1] = y; sw->geometry.y = moveresize_win_vals[1] = geom.y;
mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
} }
if(sw->geometry.width != w || sw->geometry.height != h) if(sw->geometry.width != geom.width || sw->geometry.height != geom.height)
{ {
if(mask_vals) if(mask_vals)
{ {
sw->geometry.width = moveresize_win_vals[2] = w; sw->geometry.width = moveresize_win_vals[2] = geom.width;
sw->geometry.height = moveresize_win_vals[3] = h; sw->geometry.height = moveresize_win_vals[3] = geom.height;
} }
else else
{ {
sw->geometry.width = moveresize_win_vals[0] = w; sw->geometry.width = moveresize_win_vals[0] = geom.width;
sw->geometry.height = moveresize_win_vals[1] = h; sw->geometry.height = moveresize_win_vals[1] = geom.height;
} }
mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
xcb_free_pixmap(globalconf.connection, sw->pixmap); xcb_free_pixmap(globalconf.connection, sw->pixmap);
/* orientation != East */
if(sw->pixmap != sw->ctx.pixmap)
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
sw->pixmap = xcb_generate_id(globalconf.connection); sw->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, w, h); xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, geom.width, geom.height);
simplewindow_draw_context_update(sw, s); simplewindow_draw_context_update(sw, s);
} }
@ -272,4 +269,22 @@ simplewindow_border_color_set(simple_window_t *sw, const xcolor_t *color)
sw->border.color = *color; sw->border.color = *color;
} }
/** Set simple window orientation.
* \param sw The simple window.
* \param o The new orientation
*/
void
simplewindow_orientation_set(simple_window_t *sw, orientation_t o)
{
if(o != sw->orientation)
{
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
sw->orientation = o;
/* orientation != East */
if(sw->pixmap != sw->ctx.pixmap)
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
simplewindow_draw_context_update(sw, s);
}
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -46,22 +46,23 @@ typedef struct simple_window_t
} border; } border;
/** Draw context */ /** Draw context */
draw_context_t ctx; draw_context_t ctx;
/** Position */ /** Orientation */
position_t position; orientation_t orientation;
} simple_window_t; } simple_window_t;
void simplewindow_init(simple_window_t *s, void simplewindow_init(simple_window_t *s,
int, int16_t, int16_t, uint16_t, uint16_t, uint16_t, int, area_t, uint16_t,
position_t, const xcolor_t *, const xcolor_t *); orientation_t, const xcolor_t *, const xcolor_t *);
void simplewindow_wipe(simple_window_t *); void simplewindow_wipe(simple_window_t *);
void simplewindow_move(simple_window_t *, int, int); void simplewindow_move(simple_window_t *, int, int);
void simplewindow_resize(simple_window_t *, int, int); void simplewindow_resize(simple_window_t *, int, int);
void simplewindow_moveresize(simple_window_t *, int, int, int, int); void simplewindow_moveresize(simple_window_t *, area_t);
void simplewindow_refresh_pixmap_partial(simple_window_t *, int16_t, int16_t, uint16_t, uint16_t); void simplewindow_refresh_pixmap_partial(simple_window_t *, int16_t, int16_t, uint16_t, uint16_t);
void simplewindow_border_width_set(simple_window_t *, uint32_t); void simplewindow_border_width_set(simple_window_t *, uint32_t);
void simplewindow_border_color_set(simple_window_t *, const xcolor_t *); void simplewindow_border_color_set(simple_window_t *, const xcolor_t *);
void simplewindow_orientation_set(simple_window_t *, orientation_t);
/** Refresh the window content by copying its pixmap data to its window. /** Refresh the window content by copying its pixmap data to its window.
* \param sw The simple window to refresh. * \param sw The simple window to refresh.
@ -72,6 +73,5 @@ simplewindow_refresh_pixmap(simple_window_t *sw)
simplewindow_refresh_pixmap_partial(sw, 0, 0, sw->geometry.width, sw->geometry.height); simplewindow_refresh_pixmap_partial(sw, 0, 0, sw->geometry.width, sw->geometry.height);
} }
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -25,6 +25,7 @@
#include "client.h" #include "client.h"
#include "widget.h" #include "widget.h"
#include "wibox.h" #include "wibox.h"
#include "screen.h"
extern awesome_t globalconf; extern awesome_t globalconf;
@ -60,38 +61,6 @@ client_getbytitlebarwin(xcb_window_t win)
return NULL; return NULL;
} }
/** Draw the titlebar content.
* \param c The client.
*/
void
titlebar_draw(client_t *c)
{
if(!c || !c->titlebar || !c->titlebar->isvisible)
return;
widget_render(c->titlebar->widgets, &c->titlebar->sw.ctx,
c->titlebar->sw.gc, c->titlebar->sw.pixmap,
c->screen, c->titlebar->position,
c->titlebar->sw.geometry.x, c->titlebar->sw.geometry.y,
c->titlebar);
simplewindow_refresh_pixmap(&c->titlebar->sw);
c->titlebar->need_update = false;
}
/** Titlebar refresh function.
*/
void
titlebar_refresh(void)
{
client_t *c;
for(c = globalconf.clients; c; c = c->next)
if(c->titlebar && c->titlebar->need_update)
titlebar_draw(c);
}
void void
titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
{ {
@ -102,10 +71,7 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
default: default:
return; return;
case Top: case Top:
if(c->titlebar->geometry.width) width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width);
width = MAX(1, MIN(c->titlebar->geometry.width, geometry.width - 2 * c->titlebar->sw.border.width));
else
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
@ -118,15 +84,12 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
break; break;
} }
res->x = geometry.x + x_offset; res->x = geometry.x + x_offset;
res->y = geometry.y - c->titlebar->geometry.height - 2 * c->titlebar->sw.border.width + c->border; res->y = geometry.y - c->titlebar->sw.geometry.height - 2 * c->titlebar->sw.border.width + c->border;
res->width = width; res->width = width;
res->height = c->titlebar->geometry.height; res->height = c->titlebar->sw.geometry.height;
break; break;
case Bottom: case Bottom:
if(c->titlebar->geometry.width) width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width);
width = MAX(1, MIN(c->titlebar->geometry.width, geometry.width - 2 * c->titlebar->sw.border.width));
else
width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
@ -141,13 +104,10 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
res->x = geometry.x + x_offset; res->x = geometry.x + x_offset;
res->y = geometry.y + geometry.height + c->border; res->y = geometry.y + geometry.height + c->border;
res->width = width; res->width = width;
res->height = c->titlebar->geometry.height; res->height = c->titlebar->sw.geometry.height;
break; break;
case Left: case Left:
if(c->titlebar->geometry.width) width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width);
width = MAX(1, MIN(c->titlebar->geometry.width, geometry.height - 2 * c->titlebar->sw.border.width));
else
width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
@ -159,16 +119,13 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
y_offset = (geometry.height - width) / 2; y_offset = (geometry.height - width) / 2;
break; break;
} }
res->x = geometry.x - c->titlebar->geometry.height + c->border; res->x = geometry.x - c->titlebar->sw.geometry.width + c->border;
res->y = geometry.y + y_offset; res->y = geometry.y + y_offset;
res->width = c->titlebar->geometry.height; res->width = c->titlebar->sw.geometry.width;
res->height = width; res->height = width;
break; break;
case Right: case Right:
if(c->titlebar->geometry.width) width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width);
width = MAX(1, MIN(c->titlebar->geometry.width, geometry.height - 2 * c->titlebar->sw.border.width));
else
width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width);
switch(c->titlebar->align) switch(c->titlebar->align)
{ {
default: default:
@ -182,59 +139,12 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
} }
res->x = geometry.x + geometry.width + c->border; res->x = geometry.x + geometry.width + c->border;
res->y = geometry.y + y_offset; res->y = geometry.y + y_offset;
res->width = c->titlebar->geometry.height; res->width = c->titlebar->sw.geometry.width;
res->height = width; res->height = width;
break; break;
} }
} }
/** Set client titlebar position.
* \param c The client.
*/
void
titlebar_init(client_t *c)
{
int width = 0, height = 0;
area_t geom;
/* already had a window? */
if(c->titlebar->sw.window)
simplewindow_wipe(&c->titlebar->sw);
switch(c->titlebar->position)
{
case Top:
case Bottom:
if(c->titlebar->geometry.width)
width = MIN(c->titlebar->geometry.width, c->geometry.width - 2 * c->titlebar->sw.border.width);
else
width = c->geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width;
height = c->titlebar->geometry.height;
break;
case Left:
case Right:
if(c->titlebar->geometry.width)
height = MIN(c->titlebar->geometry.width, c->geometry.height - 2 * c->titlebar->sw.border.width);
else
height = c->geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width;
width = c->titlebar->geometry.height;
break;
}
titlebar_geometry_compute(c, c->geometry, &geom);
simplewindow_init(&c->titlebar->sw, c->phys_screen,
geom.x, geom.y, geom.width, geom.height,
c->titlebar->border.width, c->titlebar->position,
&c->titlebar->colors.fg, &c->titlebar->colors.bg);
simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color);
client_need_arrange(c);
c->titlebar->need_update = true;
}
/** Create a new titlebar (DEPRECATED). /** Create a new titlebar (DEPRECATED).
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of value pushed. * \return The number of value pushed.
@ -263,7 +173,8 @@ titlebar_client_detach(client_t *c)
{ {
wibox_unref(&c->titlebar); wibox_unref(&c->titlebar);
simplewindow_wipe(&c->titlebar->sw); simplewindow_wipe(&c->titlebar->sw);
c->titlebar->type = WIBOX_TYPE_NONE; c->titlebar->type = WIBOX_TYPE_NORMAL;
c->titlebar->screen = SCREEN_UNDEF;
c->titlebar = NULL; c->titlebar = NULL;
client_need_arrange(c); client_need_arrange(c);
client_stack(); client_stack();
@ -281,11 +192,44 @@ titlebar_client_attach(client_t *c, wibox_t *t)
if(c && t) if(c && t)
{ {
area_t wingeom;
/* check if titlebar is already on a client */ /* check if titlebar is already on a client */
titlebar_client_detach(client_getbytitlebar(t)); titlebar_client_detach(client_getbytitlebar(t));
c->titlebar = wibox_ref(&t); c->titlebar = wibox_ref(&t);
t->type = WIBOX_TYPE_TITLEBAR; t->type = WIBOX_TYPE_TITLEBAR;
titlebar_init(c); t->screen = c->screen;
switch(t->position)
{
case Floating:
t->position = Top;
case Top:
case Bottom:
if(!t->sw.geometry.height)
t->sw.geometry.height = 1.5 * globalconf.font->height;
break;
case Left:
case Right:
if(!t->sw.geometry.width)
t->sw.geometry.width = 1.5 * globalconf.font->height;
break;
}
titlebar_geometry_compute(c, c->geometry, &wingeom);
simplewindow_init(&t->sw, c->phys_screen,
wingeom, 0, t->sw.orientation,
&t->sw.ctx.fg, &t->sw.ctx.bg);
simplewindow_border_color_set(&t->sw, &t->sw.border.color);
t->need_update = true;
if(t->isvisible)
xcb_map_window(globalconf.connection, t->sw.window);
client_need_arrange(c); client_need_arrange(c);
client_stack(); client_stack();
} }
@ -300,14 +244,15 @@ titlebar_client_attach(client_t *c, wibox_t *t)
int int
luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok) luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
{ {
size_t len;
const char *buf;
client_t *c = NULL; client_t *c = NULL;
int i;
position_t position;
switch(tok) switch(tok)
{ {
position_t position;
int i;
size_t len;
const char *buf;
case A_TK_ALIGN: case A_TK_ALIGN:
if((buf = luaL_checklstring(L, 3, &len))) if((buf = luaL_checklstring(L, 3, &len)))
titlebar->align = draw_align_fromstr(buf, len); titlebar->align = draw_align_fromstr(buf, len);
@ -316,23 +261,84 @@ luaA_titlebar_newindex(lua_State *L, wibox_t *titlebar, awesome_token_t tok)
break; break;
case A_TK_BORDER_WIDTH: case A_TK_BORDER_WIDTH:
if((i = luaL_checknumber(L, 3)) >= 0) if((i = luaL_checknumber(L, 3)) >= 0)
titlebar->border.width = i; simplewindow_border_width_set(&titlebar->sw, i);
else else
return 0; return 0;
break; break;
case A_TK_BORDER_COLOR: case A_TK_BORDER_COLOR:
if((buf = luaL_checklstring(L, 3, &len))) if((buf = luaL_checklstring(L, 3, &len)))
if(xcolor_init_reply(xcolor_init_unchecked(&titlebar->border.color, buf, len))) if(xcolor_init_reply(xcolor_init_unchecked(&titlebar->sw.border.color, buf, len)))
simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color); simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->sw.border.color);
return 0; return 0;
case A_TK_POSITION: case A_TK_POSITION:
buf = luaL_checklstring(L, 3, &len); buf = luaL_checklstring(L, 3, &len);
position = position_fromstr(buf, len); position = position_fromstr(buf, len);
if(position != titlebar->position) if(position != titlebar->position)
{ {
switch(position)
{
case Left:
switch(titlebar->position)
{
int tmp;
case Left:
case Right:
break;
case Top:
case Bottom:
case Floating:
tmp = titlebar->sw.geometry.width;
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
titlebar->sw.geometry.height = tmp;
break;
}
simplewindow_orientation_set(&titlebar->sw, North);
break;
case Right:
switch(titlebar->position)
{
int tmp;
case Left:
case Right:
break;
case Top:
case Bottom:
case Floating:
tmp = titlebar->sw.geometry.width;
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
titlebar->sw.geometry.height = tmp;
break;
}
simplewindow_orientation_set(&titlebar->sw, South);
break;
case Top:
case Bottom:
case Floating:
switch(titlebar->position)
{
int tmp;
case Left:
case Right:
tmp = titlebar->sw.geometry.width;
titlebar->sw.geometry.width = titlebar->sw.geometry.height;
titlebar->sw.geometry.height = tmp;
break;
case Top:
case Bottom:
case Floating:
break;
}
simplewindow_orientation_set(&titlebar->sw, East);
break;
}
titlebar->position = position; titlebar->position = position;
c = client_getbytitlebar(titlebar); if((c = client_getbytitlebar(titlebar)))
titlebar_init(c); {
titlebar_update_geometry_floating(c);
/* call geometry hook for client because some like to
* set titlebar width in that hook, which make sense */
hooks_property(c, "geometry");
}
} }
break; break;
default: default:

View File

@ -23,13 +23,12 @@
#define AWESOME_TITLEBAR_H #define AWESOME_TITLEBAR_H
#include "structs.h" #include "structs.h"
#include "wibox.h"
client_t * client_getbytitlebar(wibox_t *); client_t * client_getbytitlebar(wibox_t *);
client_t * client_getbytitlebarwin(xcb_window_t); client_t * client_getbytitlebarwin(xcb_window_t);
void titlebar_geometry_compute(client_t *, area_t, area_t *); void titlebar_geometry_compute(client_t *, area_t, area_t *);
void titlebar_draw(client_t *);
void titlebar_init(client_t *); void titlebar_init(client_t *);
void titlebar_refresh(void);
void titlebar_client_detach(client_t *); void titlebar_client_detach(client_t *);
void titlebar_client_attach(client_t *, wibox_t *); void titlebar_client_attach(client_t *, wibox_t *);
@ -119,22 +118,6 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t geometry)
return geometry; return geometry;
} }
/** Update the titlebar geometry for a floating client.
* \param c The client.
*/
static inline void
titlebar_update_geometry_floating(client_t *c)
{
area_t geom;
if(!c->titlebar)
return;
titlebar_geometry_compute(c, c->geometry, &geom);
simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height);
c->titlebar->need_update = true;
}
/** Update the titlebar geometry for a tiled client. /** Update the titlebar geometry for a tiled client.
* \param c The client. * \param c The client.
* \param geometry The geometry the client will receive. * \param geometry The geometry the client will receive.
@ -148,8 +131,16 @@ titlebar_update_geometry_tiled(client_t *c, area_t geometry)
return; return;
titlebar_geometry_compute(c, geometry, &geom); titlebar_geometry_compute(c, geometry, &geom);
simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); wibox_moveresize(c->titlebar, geom);
c->titlebar->need_update = true; }
/** Update the titlebar geometry for a floating client.
* \param c The client.
*/
static inline void
titlebar_update_geometry_floating(client_t *c)
{
return titlebar_update_geometry_tiled(c, c->geometry);
} }
#endif #endif

716
wibox.c
View File

@ -1,5 +1,5 @@
/* /*
* wibox.c - statusbar functions * wibox.c - wibox functions
* *
* Copyright © 2008 Julien Danjou <julien@danjou.info> * Copyright © 2008 Julien Danjou <julien@danjou.info>
* *
@ -21,9 +21,9 @@
#include "screen.h" #include "screen.h"
#include "wibox.h" #include "wibox.h"
#include "statusbar.h"
#include "titlebar.h" #include "titlebar.h"
#include "client.h" #include "client.h"
#include "ewmh.h"
extern awesome_t globalconf; extern awesome_t globalconf;
@ -31,15 +31,564 @@ DO_LUA_NEW(extern, wibox_t, wibox, "wibox", wibox_ref)
DO_LUA_GC(wibox_t, wibox, "wibox", wibox_unref) DO_LUA_GC(wibox_t, wibox, "wibox", wibox_unref)
DO_LUA_EQ(wibox_t, wibox, "wibox") DO_LUA_EQ(wibox_t, wibox, "wibox")
static void
wibox_move(wibox_t *wibox, int16_t x, int16_t y)
{
if(wibox->sw.window)
simplewindow_move(&wibox->sw, x, y);
else
{
wibox->sw.geometry.x = x;
wibox->sw.geometry.y = y;
}
}
static void
wibox_resize(wibox_t *wibox, uint16_t width, uint16_t height)
{
if(wibox->sw.window)
simplewindow_resize(&wibox->sw, width, height);
else
{
wibox->sw.geometry.width = width;
wibox->sw.geometry.height = height;
}
wibox->need_update = true;
}
static void
wibox_setposition(wibox_t *wibox, position_t p)
{
if(p != wibox->position)
{
switch((wibox->position = p))
{
case Bottom:
case Top:
case Floating:
simplewindow_orientation_set(&wibox->sw, East);
break;
case Left:
simplewindow_orientation_set(&wibox->sw, North);
break;
case Right:
simplewindow_orientation_set(&wibox->sw, South);
break;
}
/* reset width/height to 0 */
if(wibox->position != Floating)
wibox->sw.geometry.width = wibox->sw.geometry.height = 0;
/* recompute position */
wibox_position_update(wibox);
/* reset all wibox position */
wibox_array_t *w = &globalconf.screens[wibox->screen].wiboxes;
for(int i = 0; i < w->len; i++)
wibox_position_update(w->tab[i]);
ewmh_update_workarea(screen_virttophys(wibox->screen));
wibox->need_update = true;
}
}
/** Kick out systray windows.
* \param phys_screen Physical screen number.
*/
static void
wibox_systray_kickout(int phys_screen)
{
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
/* Who! Check that we're not deleting a wibox with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
xcb_reparent_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
s->root, -512, -512);
globalconf.screens[phys_screen].systray.parent = s->root;
}
static void
wibox_systray_refresh(wibox_t *wibox)
{
widget_node_t *systray;
if(wibox->screen == SCREEN_UNDEF)
return;
for(systray = wibox->widgets; systray; systray = systray->next)
if(systray->widget->type == systray_new)
{
uint32_t config_back[] = { wibox->sw.ctx.bg.pixel };
uint32_t config_win_vals[4];
uint32_t config_win_vals_off[2] = { -512, -512 };
xembed_window_t *em;
position_t pos;
int phys_screen = wibox->sw.ctx.phys_screen;
if(wibox->isvisible
&& systray->widget->isvisible
&& systray->area.width)
{
pos = wibox->position;
/* Set background of the systray window. */
xcb_change_window_attributes(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
XCB_CW_BACK_PIXEL, config_back);
/* Map it. */
xcb_map_window(globalconf.connection, globalconf.screens[phys_screen].systray.window);
/* Move it. */
switch(wibox->position)
{
case Left:
config_win_vals[0] = systray->area.y;
config_win_vals[1] = wibox->sw.geometry.height - systray->area.x - systray->area.width;
config_win_vals[2] = systray->area.height;
config_win_vals[3] = systray->area.width;
break;
case Right:
config_win_vals[0] = systray->area.y;
config_win_vals[1] = systray->area.x;
config_win_vals[2] = systray->area.height;
config_win_vals[3] = systray->area.width;
break;
default:
config_win_vals[0] = systray->area.x;
config_win_vals[1] = systray->area.y;
config_win_vals[2] = systray->area.width;
config_win_vals[3] = systray->area.height;
break;
}
/* reparent */
if(globalconf.screens[phys_screen].systray.parent != wibox->sw.window)
{
xcb_reparent_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
wibox->sw.window,
config_win_vals[0], config_win_vals[1]);
globalconf.screens[phys_screen].systray.parent = wibox->sw.window;
}
xcb_configure_window(globalconf.connection,
globalconf.screens[phys_screen].systray.window,
XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
| XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT,
config_win_vals);
/* width = height = systray height */
config_win_vals[2] = config_win_vals[3] = systray->area.height;
config_win_vals[0] = 0;
}
else
return wibox_systray_kickout(phys_screen);
switch(pos)
{
case Left:
config_win_vals[1] = systray->area.width - config_win_vals[3];
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) wibox->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,
config_win_vals_off);
}
break;
case Right:
config_win_vals[1] = 0;
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) wibox->sw.geometry.y + wibox->sw.geometry.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,
config_win_vals_off);
}
break;
case Floating:
case Top:
case Bottom:
config_win_vals[1] = 0;
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(systray->area) + wibox->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,
config_win_vals_off);
}
break;
}
break;
}
}
/** Update the wibox position. It deletes every wibox resources and
* create them back.
* \param wibox The wibox.
*/
void
wibox_position_update(wibox_t *wibox)
{
area_t area, wingeom = wibox->sw.geometry;
bool ignore = false;
globalconf.screens[wibox->screen].need_arrange = true;
area = screen_area_get(wibox->screen, NULL,
&globalconf.screens[wibox->screen].padding, true);
/* Top and Bottom wibox_t have prio */
for(int i = 0; i < globalconf.screens[wibox->screen].wiboxes.len; i++)
{
wibox_t *w = globalconf.screens[wibox->screen].wiboxes.tab[i];
/* Ignore every wibox after me that is in the same position */
if(wibox == w)
{
ignore = true;
continue;
}
else if((ignore && wibox->position == w->position) || !w->isvisible)
continue;
switch(w->position)
{
case Floating:
break;
case Left:
switch(wibox->position)
{
case Left:
area.x += wibox->sw.geometry.height;
break;
default:
break;
}
break;
case Right:
switch(wibox->position)
{
case Right:
area.x -= wibox->sw.geometry.height;
break;
default:
break;
}
break;
case Top:
switch(wibox->position)
{
case Top:
area.y += w->sw.geometry.height;
break;
case Left:
case Right:
area.height -= w->sw.geometry.height;
area.y += w->sw.geometry.height;
break;
default:
break;
}
break;
case Bottom:
switch(wibox->position)
{
case Bottom:
area.y -= w->sw.geometry.height;
break;
case Left:
case Right:
area.height -= w->sw.geometry.height;
break;
default:
break;
}
break;
}
}
switch(wibox->position)
{
case Right:
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : area.height;
wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : 1.5 * globalconf.font->height;
switch(wibox->align)
{
default:
wingeom.x = area.x + area.width - wingeom.width;
wingeom.y = area.y;
break;
case AlignRight:
wingeom.x = area.x + area.width - wingeom.width;
wingeom.y = area.y + area.height - wingeom.height;
break;
case AlignCenter:
wingeom.x = area.x + area.width - wingeom.width;
wingeom.y = (area.y + area.height - wingeom.height) / 2;
break;
}
break;
case Left:
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : area.height;
wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : 1.5 * globalconf.font->height;
switch(wibox->align)
{
default:
wingeom.x = area.x;
wingeom.y = (area.y + area.height) - wingeom.height;
break;
case AlignRight:
wingeom.x = area.x;
wingeom.y = area.y;
break;
case AlignCenter:
wingeom.x = area.x;
wingeom.y = (area.y + area.height - wingeom.height) / 2;
}
break;
case Bottom:
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height;
wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : area.width;
switch(wibox->align)
{
default:
wingeom.x = area.x;
wingeom.y = (area.y + area.height) - wingeom.height;
break;
case AlignRight:
wingeom.x = area.x + area.width - wingeom.width;
wingeom.y = (area.y + area.height) - wingeom.height;
break;
case AlignCenter:
wingeom.x = area.x + (area.width - wingeom.width) / 2;
wingeom.y = (area.y + area.height) - wingeom.height;
break;
}
break;
case Top:
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height;
wingeom.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : area.width;
switch(wibox->align)
{
default:
wingeom.x = area.x;
wingeom.y = area.y;
break;
case AlignRight:
wingeom.x = area.x + area.width - wingeom.width;
wingeom.y = area.y;
break;
case AlignCenter:
wingeom.x = area.x + (area.width - wingeom.width) / 2;
wingeom.y = area.y;
break;
}
break;
case Floating:
break;
}
/* same window size and position ? */
if(wingeom.width != wibox->sw.geometry.width
|| wingeom.height != wibox->sw.geometry.height)
wibox_resize(wibox, wingeom.width, wingeom.height);
if(wingeom.x != wibox->sw.geometry.x
|| wingeom.y != wibox->sw.geometry.y)
wibox_move(wibox, wingeom.x, wingeom.y);
}
/** Get a wibox by its window.
* \param w The window id.
* \return A wibox if found, NULL otherwise.
*/
wibox_t *
wibox_getbywin(xcb_window_t w)
{
for(int screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{
wibox_t *s = globalconf.screens[screen].wiboxes.tab[i];
if(s->sw.window == w)
return s;
}
for(client_t *c = globalconf.clients; c; c = c->next)
if(c->titlebar && c->titlebar->sw.window == w)
return c->titlebar;
return NULL;
}
/** Draw a wibox.
* \param wibox The wibox to draw.
*/
static void
wibox_draw(wibox_t *wibox)
{
if(wibox->isvisible)
{
widget_render(wibox->widgets, &wibox->sw.ctx, wibox->sw.gc,
wibox->sw.pixmap,
wibox->screen, wibox->sw.orientation,
wibox->sw.geometry.x, wibox->sw.geometry.y,
wibox);
simplewindow_refresh_pixmap(&wibox->sw);
wibox->need_update = false;
}
wibox_systray_refresh(wibox);
}
/** Refresh all wiboxes. /** Refresh all wiboxes.
*/ */
void void
wibox_refresh(void) wibox_refresh(void)
{ {
statusbar_refresh(); for(int screen = 0; screen < globalconf.nscreen; screen++)
titlebar_refresh(); for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{
wibox_t *s = globalconf.screens[screen].wiboxes.tab[i];
if(s->need_update)
wibox_draw(s);
}
for(client_t *c = globalconf.clients; c; c = c->next)
if(c->titlebar && c->titlebar->need_update)
wibox_draw(c->titlebar);
} }
/** Set a wibox visible or not.
* \param wibox The wibox.
* \param v The visible value.
*/
static void
wibox_setvisible(wibox_t *wibox, bool v)
{
if(v != wibox->isvisible)
{
if((wibox->isvisible = v))
xcb_map_window(globalconf.connection, wibox->sw.window);
else
xcb_unmap_window(globalconf.connection, wibox->sw.window);
/* kick out systray if needed */
wibox_systray_refresh(wibox);
/* All the other wibox and ourselves need to be repositioned */
wibox_array_t *w = &globalconf.screens[wibox->screen].wiboxes;
for(int i = 0; i < w->len; i++)
wibox_position_update(w->tab[i]);
}
}
/** Remove a wibox from a screen.
* \param wibox Wibox to detach from screen.
*/
void
wibox_detach(wibox_t *wibox)
{
if(wibox->screen != SCREEN_UNDEF)
{
bool v;
/* save visible state */
v = wibox->isvisible;
wibox->isvisible = false;
wibox_position_update(wibox);
/* restore position */
wibox->isvisible = v;
simplewindow_wipe(&wibox->sw);
for(int i = 0; i < globalconf.screens[wibox->screen].wiboxes.len; i++)
if(globalconf.screens[wibox->screen].wiboxes.tab[i] == wibox)
{
wibox_array_take(&globalconf.screens[wibox->screen].wiboxes, i);
break;
}
globalconf.screens[wibox->screen].need_arrange = true;
wibox->screen = SCREEN_UNDEF;
wibox_unref(&wibox);
}
}
/** Attach a wibox.
* \param wibox The wibox to attach.
* \param s The screen to attach the wibox to.
*/
void
wibox_attach(wibox_t *wibox, screen_t *s)
{
int phys_screen = screen_virttophys(wibox->screen);
wibox_detach(wibox);
wibox->screen = s->index;
wibox_array_append(&s->wiboxes, wibox_ref(&wibox));
/* compute x/y/width/height if not set */
wibox_position_update(wibox);
simplewindow_init(&wibox->sw, phys_screen,
wibox->sw.geometry, 0, wibox->sw.orientation,
&wibox->sw.ctx.fg, &wibox->sw.ctx.bg);
wibox->need_update = true;
if(wibox->isvisible)
xcb_map_window(globalconf.connection, wibox->sw.window);
/* All the other wibox and ourselves need to be repositioned */
for(int i = 0; i < s->wiboxes.len; i++)
wibox_position_update(s->wiboxes.tab[i]);
ewmh_update_workarea(screen_virttophys(s->index));
}
/** Convert a wibox to a printable string. /** Convert a wibox to a printable string.
* \param L The Lua VM state. * \param L The Lua VM state.
* *
@ -59,7 +608,7 @@ luaA_wibox_tostring(lua_State *L)
* *
* \luastack * \luastack
* \lparam A table with optionaly defined values: * \lparam A table with optionaly defined values:
* position, align, fg, bg, border_widht, border_color, width and height. * position, align, fg, bg, border_width, border_color, width and height.
* \lreturn A brand new wibox. * \lreturn A brand new wibox.
*/ */
int int
@ -75,29 +624,28 @@ luaA_wibox_new(lua_State *L)
w = p_new(wibox_t, 1); w = p_new(wibox_t, 1);
w->colors.fg = globalconf.colors.fg; w->sw.ctx.fg = globalconf.colors.fg;
if((buf = luaA_getopt_lstring(L, 2, "fg", NULL, &len))) if((buf = luaA_getopt_lstring(L, 2, "fg", NULL, &len)))
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.fg, buf, len); reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.fg, buf, len);
w->colors.bg = globalconf.colors.bg; w->sw.ctx.bg = globalconf.colors.bg;
if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len))) if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len)))
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.bg, buf, len); reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.ctx.bg, buf, len);
w->colors.bg = globalconf.colors.bg; w->sw.border.color = globalconf.colors.bg;
if((buf = luaA_getopt_lstring(L, 2, "bg", NULL, &len))) if((buf = luaA_getopt_lstring(L, 2, "border_color", NULL, &len)))
reqs[++reqs_nbr] = xcolor_init_unchecked(&w->colors.bg, buf, len); reqs[++reqs_nbr] = xcolor_init_unchecked(&w->sw.border.color, buf, len);
buf = luaA_getopt_lstring(L, 2, "align", "left", &len); buf = luaA_getopt_lstring(L, 2, "align", "left", &len);
w->align = draw_align_fromstr(buf, len); w->align = draw_align_fromstr(buf, len);
w->geometry.width = luaA_getopt_number(L, 2, "width", 0); w->sw.border.width = luaA_getopt_number(L, 2, "border_width", 0);
w->geometry.height = luaA_getopt_number(L, 2, "height", 0);
if(w->geometry.height <= 0) w->sw.geometry.width = luaA_getopt_number(L, 2, "width", 0);
/* 1.5 as default factor, it fits nice but no one knows why */ w->sw.geometry.height = luaA_getopt_number(L, 2, "height", 0);
w->geometry.height = 1.5 * globalconf.font->height;
buf = luaA_getopt_lstring(L, 2, "position", "top", &len); buf = luaA_getopt_lstring(L, 2, "position", "top", &len);
w->position = position_fromstr(buf, len); wibox_setposition(w, position_fromstr(buf, len));
w->screen = SCREEN_UNDEF; w->screen = SCREEN_UNDEF;
w->isvisible = true; w->isvisible = true;
@ -112,7 +660,6 @@ luaA_wibox_new(lua_State *L)
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
* \luastack * \luastack
* \lfield geometry Geometry table.
* \lfield screen Screen number. * \lfield screen Screen number.
* \lfield client The client attached to this titlebar. * \lfield client The client attached to this titlebar.
* \lfield border_width Border width. * \lfield border_width Border width.
@ -137,9 +684,6 @@ luaA_wibox_index(lua_State *L)
{ {
client_t *c; client_t *c;
case A_TK_GEOMETRY:
luaA_pusharea(L, (*wibox)->geometry);
break;
case A_TK_VISIBLE: case A_TK_VISIBLE:
lua_pushboolean(L, (*wibox)->isvisible); lua_pushboolean(L, (*wibox)->isvisible);
break; break;
@ -154,19 +698,19 @@ luaA_wibox_index(lua_State *L)
lua_pushnumber(L, (*wibox)->screen + 1); lua_pushnumber(L, (*wibox)->screen + 1);
break; break;
case A_TK_BORDER_WIDTH: case A_TK_BORDER_WIDTH:
lua_pushnumber(L, (*wibox)->border.width); lua_pushnumber(L, (*wibox)->sw.border.width);
break; break;
case A_TK_BORDER_COLOR: case A_TK_BORDER_COLOR:
luaA_pushcolor(L, &(*wibox)->border.color); luaA_pushcolor(L, &(*wibox)->sw.border.color);
break; break;
case A_TK_ALIGN: case A_TK_ALIGN:
lua_pushstring(L, draw_align_tostr((*wibox)->align)); lua_pushstring(L, draw_align_tostr((*wibox)->align));
break; break;
case A_TK_FG: case A_TK_FG:
luaA_pushcolor(L, &(*wibox)->colors.fg); luaA_pushcolor(L, &(*wibox)->sw.ctx.fg);
break; break;
case A_TK_BG: case A_TK_BG:
luaA_pushcolor(L, &(*wibox)->colors.bg); luaA_pushcolor(L, &(*wibox)->sw.ctx.bg);
break; break;
case A_TK_POSITION: case A_TK_POSITION:
lua_pushstring(L, position_tostr((*wibox)->position)); lua_pushstring(L, position_tostr((*wibox)->position));
@ -174,6 +718,9 @@ luaA_wibox_index(lua_State *L)
case A_TK_ONTOP: case A_TK_ONTOP:
lua_pushboolean(L, (*wibox)->ontop); lua_pushboolean(L, (*wibox)->ontop);
break; break;
case A_TK_ORIENTATION:
lua_pushstring(L, orientation_tostr((*wibox)->sw.orientation));
break;
default: default:
return 0; return 0;
} }
@ -203,6 +750,49 @@ luaA_wibox_widgets(lua_State *L)
return luaA_widget_get(L, (*wibox)->widgets); return luaA_widget_get(L, (*wibox)->widgets);
} }
/* Set or get the wibox geometry.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam An optional table with wibox geometry.
* \lreturn The wibox geometry.
*/
static int
luaA_wibox_geometry(lua_State *L)
{
wibox_t **wibox = luaA_checkudata(L, 1, "wibox");
if(lua_gettop(L) == 2)
{
area_t wingeom;
luaA_checktable(L, 2);
wingeom.x = luaA_getopt_number(L, 2, "x", (*wibox)->sw.geometry.x);
wingeom.y = luaA_getopt_number(L, 2, "y", (*wibox)->sw.geometry.y);
wingeom.width = luaA_getopt_number(L, 2, "width", (*wibox)->sw.geometry.width);
wingeom.height = luaA_getopt_number(L, 2, "height", (*wibox)->sw.geometry.height);
switch((*wibox)->type)
{
case WIBOX_TYPE_TITLEBAR:
wibox_resize(*wibox, wingeom.width, wingeom.height);
break;
case WIBOX_TYPE_NORMAL:
if((*wibox)->position == Floating)
wibox_moveresize(*wibox, wingeom);
else if(wingeom.width != (*wibox)->sw.geometry.width
|| wingeom.height != (*wibox)->sw.geometry.height)
{
wibox_resize(*wibox, wingeom.width, wingeom.height);
globalconf.screens[(*wibox)->screen].need_arrange = true;
}
break;
}
}
return luaA_pusharea(L, (*wibox)->sw.geometry);
}
/** Wibox newindex. /** Wibox newindex.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
@ -221,44 +811,32 @@ luaA_wibox_newindex(lua_State *L)
case A_TK_FG: case A_TK_FG:
if((buf = luaL_checklstring(L, 3, &len))) if((buf = luaL_checklstring(L, 3, &len)))
if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->colors.fg, buf, len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->sw.ctx.fg, buf, len)))
{
(*wibox)->sw.ctx.fg = (*wibox)->colors.fg;
(*wibox)->need_update = true; (*wibox)->need_update = true;
}
break; break;
case A_TK_BG: case A_TK_BG:
if((buf = luaL_checklstring(L, 3, &len))) if((buf = luaL_checklstring(L, 3, &len)))
if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->colors.bg, buf, len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox)->sw.ctx.bg, buf, len)))
{
(*wibox)->sw.ctx.bg = (*wibox)->colors.bg;
(*wibox)->need_update = true; (*wibox)->need_update = true;
} break;
case A_TK_ALIGN:
buf = luaL_checklstring(L, 3, &len);
(*wibox)->align = draw_align_fromstr(buf, len);
wibox_position_update(*wibox);
break; break;
case A_TK_POSITION: case A_TK_POSITION:
switch((*wibox)->type) switch((*wibox)->type)
{ {
case WIBOX_TYPE_TITLEBAR: case WIBOX_TYPE_TITLEBAR:
return luaA_titlebar_newindex(L, *wibox, tok); return luaA_titlebar_newindex(L, *wibox, tok);
case WIBOX_TYPE_STATUSBAR: case WIBOX_TYPE_NORMAL:
return luaA_statusbar_newindex(L, *wibox, tok);
case WIBOX_TYPE_NONE:
if((buf = luaL_checklstring(L, 3, &len))) if((buf = luaL_checklstring(L, 3, &len)))
(*wibox)->position = position_fromstr(buf, len); wibox_setposition(*wibox, position_fromstr(buf, len));
break; break;
} }
break; break;
case A_TK_CLIENT: case A_TK_CLIENT:
/* first detach */ /* first detach */
switch((*wibox)->type)
{
case WIBOX_TYPE_NONE:
case WIBOX_TYPE_TITLEBAR:
break;
case WIBOX_TYPE_STATUSBAR:
statusbar_detach(*wibox);
break;
}
if(lua_isnil(L, 3)) if(lua_isnil(L, 3))
titlebar_client_detach(client_getbytitlebar(*wibox)); titlebar_client_detach(client_getbytitlebar(*wibox));
else else
@ -268,22 +846,20 @@ luaA_wibox_newindex(lua_State *L)
} }
break; break;
case A_TK_SCREEN: case A_TK_SCREEN:
switch((*wibox)->type)
{
case WIBOX_TYPE_NONE:
case WIBOX_TYPE_STATUSBAR:
break;
case WIBOX_TYPE_TITLEBAR:
titlebar_client_detach(client_getbytitlebar(*wibox));
break;
}
if(lua_isnil(L, 3)) if(lua_isnil(L, 3))
statusbar_detach(*wibox); {
wibox_detach(*wibox);
titlebar_client_detach(client_getbytitlebar(*wibox));
}
else else
{ {
int screen = luaL_checknumber(L, 3) - 1; int screen = luaL_checknumber(L, 3) - 1;
luaA_checkscreen(screen); luaA_checkscreen(screen);
statusbar_attach(*wibox, &globalconf.screens[screen]); if(screen != (*wibox)->screen)
{
titlebar_client_detach(client_getbytitlebar(*wibox));
wibox_attach(*wibox, &globalconf.screens[screen]);
}
} }
break; break;
case A_TK_ONTOP: case A_TK_ONTOP:
@ -294,30 +870,35 @@ luaA_wibox_newindex(lua_State *L)
client_stack(); client_stack();
} }
break; break;
case A_TK_ORIENTATION:
if((buf = luaL_checklstring(L, 3, &len)))
{
simplewindow_orientation_set(&(*wibox)->sw, orientation_fromstr(buf, len));
(*wibox)->need_update = true;
}
break;
case A_TK_VISIBLE: case A_TK_VISIBLE:
b = luaA_checkboolean(L, 3); b = luaA_checkboolean(L, 3);
if(b != (*wibox)->isvisible) if(b != (*wibox)->isvisible)
{
(*wibox)->isvisible = b;
switch((*wibox)->type) switch((*wibox)->type)
{ {
case WIBOX_TYPE_STATUSBAR: case WIBOX_TYPE_NORMAL:
statusbar_position_update(*wibox); wibox_setvisible(*wibox, b);
break; break;
case WIBOX_TYPE_NONE:
case WIBOX_TYPE_TITLEBAR: case WIBOX_TYPE_TITLEBAR:
(*wibox)->isvisible = b;
globalconf.screens[(*wibox)->screen].need_arrange = true;
break; break;
} }
} break;
case A_TK_GEOMETRY:
break; break;
default: default:
switch((*wibox)->type) switch((*wibox)->type)
{ {
case WIBOX_TYPE_TITLEBAR: case WIBOX_TYPE_TITLEBAR:
return luaA_titlebar_newindex(L, *wibox, tok); return luaA_titlebar_newindex(L, *wibox, tok);
case WIBOX_TYPE_STATUSBAR: case WIBOX_TYPE_NORMAL:
return luaA_statusbar_newindex(L, *wibox, tok);
case WIBOX_TYPE_NONE:
break; break;
} }
} }
@ -333,6 +914,7 @@ const struct luaL_reg awesome_wibox_methods[] =
const struct luaL_reg awesome_wibox_meta[] = const struct luaL_reg awesome_wibox_meta[] =
{ {
{ "widgets", luaA_wibox_widgets }, { "widgets", luaA_wibox_widgets },
{ "geometry", luaA_wibox_geometry },
{ "__index", luaA_wibox_index }, { "__index", luaA_wibox_index },
{ "__newindex", luaA_wibox_newindex }, { "__newindex", luaA_wibox_newindex },
{ "__gc", luaA_wibox_gc }, { "__gc", luaA_wibox_gc },

16
wibox.h
View File

@ -1,5 +1,5 @@
/* /*
* statusbar.h - statusbar functions header * wibox.h - wibox functions header
* *
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info> * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
* *
@ -32,6 +32,10 @@ void wibox_refresh(void);
int luaA_wibox_new(lua_State *); int luaA_wibox_new(lua_State *);
int luaA_wibox_userdata_new(lua_State *, wibox_t *); int luaA_wibox_userdata_new(lua_State *, wibox_t *);
void wibox_position_update(wibox_t *);
wibox_t * wibox_getbywin(xcb_window_t);
void wibox_detach(wibox_t *);
void wibox_attach(wibox_t *, screen_t *);
static inline void static inline void
wibox_delete(wibox_t **wibox) wibox_delete(wibox_t **wibox)
@ -41,6 +45,16 @@ wibox_delete(wibox_t **wibox)
p_delete(wibox); p_delete(wibox);
} }
static inline void
wibox_moveresize(wibox_t *wibox, area_t geometry)
{
if(wibox->sw.window)
simplewindow_moveresize(&wibox->sw, geometry);
else
wibox->sw.geometry = geometry;
wibox->need_update = true;
}
DO_RCNT(wibox_t, wibox, wibox_delete) DO_RCNT(wibox_t, wibox, wibox_delete)
ARRAY_FUNCS(wibox_t *, wibox, wibox_unref) ARRAY_FUNCS(wibox_t *, wibox, wibox_unref)

View File

@ -38,9 +38,9 @@ DO_LUA_EQ(widget_t, widget, "widget")
#include "widgetgen.h" #include "widgetgen.h"
/** Compute offset for drawing the first pixel of a widget. /** Compute offset for drawing the first pixel of a widget.
* \param barwidth The statusbar width. * \param barwidth The wibox width.
* \param widgetwidth The widget width. * \param widgetwidth The widget width.
* \param alignment The widget alignment on statusbar. * \param alignment The widget alignment on wibox.
* \return The x coordinate to draw at. * \return The x coordinate to draw at.
*/ */
int int
@ -86,17 +86,17 @@ widget_common_button(widget_node_t *w,
* \param wnode The list of widgets. * \param wnode The list of widgets.
* \param ctx The draw context where to render. * \param ctx The draw context where to render.
* \param rotate_px The rotate pixmap: where to rotate and render the final * \param rotate_px The rotate pixmap: where to rotate and render the final
* pixmap when the object oritation is not east.
* \param screen The logical screen used to render. * \param screen The logical screen used to render.
* \param position The object position. * \param orientation The object orientation.
* \param x The x coordinates of the object. * \param x The x coordinates of the object.
* \param y The y coordinates of the object. * \param y The y coordinates of the object.
* pixmap when the object position is right or left.
* \param object The wibox. * \param object The wibox.
* \todo Remove GC. * \todo Remove GC.
*/ */
void void
widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_pixmap_t rotate_px, widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_pixmap_t rotate_px,
int screen, position_t position, int screen, orientation_t orientation,
int x, int y, wibox_t *object) int x, int y, wibox_t *object)
{ {
xcb_pixmap_t rootpix; xcb_pixmap_t rootpix;
@ -121,9 +121,9 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_
if(prop_r->value_len if(prop_r->value_len
&& (data = xcb_get_property_value(prop_r)) && (data = xcb_get_property_value(prop_r))
&& (rootpix = *(xcb_pixmap_t *) data)) && (rootpix = *(xcb_pixmap_t *) data))
switch(position) switch(orientation)
{ {
case Left: case North:
draw_rotate(ctx, draw_rotate(ctx,
rootpix, ctx->pixmap, rootpix, ctx->pixmap,
s->width_in_pixels, s->height_in_pixels, s->width_in_pixels, s->height_in_pixels,
@ -132,7 +132,7 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_
y + ctx->width, y + ctx->width,
- x); - x);
break; break;
case Right: case South:
draw_rotate(ctx, draw_rotate(ctx,
rootpix, ctx->pixmap, rootpix, ctx->pixmap,
s->width_in_pixels, s->height_in_pixels, s->width_in_pixels, s->height_in_pixels,
@ -141,7 +141,7 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_
- y, - y,
x + ctx->height); x + ctx->height);
break; break;
default: case East:
xcb_copy_area(globalconf.connection, rootpix, xcb_copy_area(globalconf.connection, rootpix,
rotate_px, gc, rotate_px, gc,
x, y, x, y,
@ -168,21 +168,21 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_
if(w->widget->align == AlignFlex && w->widget->isvisible) if(w->widget->align == AlignFlex && w->widget->isvisible)
left += w->widget->draw(ctx, screen, w, left, (left + right), object); left += w->widget->draw(ctx, screen, w, left, (left + right), object);
switch(position) switch(orientation)
{ {
case Right: case South:
draw_rotate(ctx, ctx->pixmap, rotate_px, draw_rotate(ctx, ctx->pixmap, rotate_px,
ctx->width, ctx->height, ctx->width, ctx->height,
ctx->height, ctx->width, ctx->height, ctx->width,
M_PI_2, ctx->height, 0); M_PI_2, ctx->height, 0);
break; break;
case Left: case North:
draw_rotate(ctx, ctx->pixmap, rotate_px, draw_rotate(ctx, ctx->pixmap, rotate_px,
ctx->width, ctx->height, ctx->width, ctx->height,
ctx->height, ctx->width, ctx->height, ctx->width,
- M_PI_2, 0, ctx->width); - M_PI_2, 0, ctx->width);
break; break;
default: case East:
break; break;
} }
} }
@ -207,21 +207,21 @@ widget_common_new(widget_t *widget)
void void
widget_invalidate_cache(int screen, int flags) widget_invalidate_cache(int screen, int flags)
{ {
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; wibox_t *wibox = globalconf.screens[screen].wiboxes.tab[i];
widget_node_t *widget; widget_node_t *widget;
for(widget = statusbar->widgets; widget; widget = widget->next) for(widget = wibox->widgets; widget; widget = widget->next)
if(widget->widget->cache_flags & flags) if(widget->widget->cache_flags & flags)
{ {
statusbar->need_update = true; wibox->need_update = true;
break; break;
} }
} }
} }
/** Set a statusbar needs update because it has widget, or redraw a titlebar. /** Set a wibox needs update because it has widget, or redraw a titlebar.
* \todo Probably needs more optimization. * \todo Probably needs more optimization.
* \param widget The widget to look for. * \param widget The widget to look for.
*/ */
@ -233,15 +233,15 @@ widget_invalidate_bywidget(widget_t *widget)
client_t *c; client_t *c;
for(screen = 0; screen < globalconf.nscreen; screen++) for(screen = 0; screen < globalconf.nscreen; screen++)
for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) for(int i = 0; i < globalconf.screens[screen].wiboxes.len; i++)
{ {
wibox_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; wibox_t *wibox = globalconf.screens[screen].wiboxes.tab[i];
if(!statusbar->need_update) if(!wibox->need_update)
for(witer = statusbar->widgets; witer; witer = witer->next) for(witer = wibox->widgets; witer; witer = witer->next)
if(witer->widget == widget) if(witer->widget == widget)
{ {
statusbar->need_update = true; wibox->need_update = true;
break; break;
} }
} }

View File

@ -31,7 +31,7 @@
void widget_invalidate_cache(int, int); void widget_invalidate_cache(int, int);
int widget_calculate_offset(int, int, int, int); int widget_calculate_offset(int, int, int, int);
void widget_common_new(widget_t *); void widget_common_new(widget_t *);
void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, position_t, int, int, wibox_t *); void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, orientation_t, int, int, wibox_t *);
void luaA_widget_set(lua_State *, int, wibox_t *, widget_node_t **); void luaA_widget_set(lua_State *, int, wibox_t *, widget_node_t **);
int luaA_widget_get(lua_State *, widget_node_t *); int luaA_widget_get(lua_State *, widget_node_t *);

View File

@ -73,7 +73,7 @@ systray_draw(draw_context_t *ctx,
break; break;
} }
/* set statusbar orientation */ /* set wibox orientation */
/** \todo stop setting that property on each redraw */ /** \todo stop setting that property on each redraw */
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
globalconf.screens[p->sw.ctx.phys_screen].systray.window, globalconf.screens[p->sw.ctx.phys_screen].systray.window,

View File

@ -123,7 +123,7 @@ tasklist_draw_item(draw_context_t *ctx,
draw_parser_data_init(&pdata); draw_parser_data_init(&pdata);
/* Actually look for the proper background color, since /* Actually look for the proper background color, since
* otherwise the background statusbar color is used instead */ * otherwise the background wibox color is used instead */
if(draw_text_markup_expand(&pdata, if(draw_text_markup_expand(&pdata,
odata->client_labels.tab[i].label, odata->client_labels.tab[i].label,
odata->client_labels.tab[i].label_len)) odata->client_labels.tab[i].label_len))