Re: [Draft] Introduction of Widget Layouts
Gregor Best <gbe <at> intepi.net>
2009-07-02 00:39:46 GMT
Once again, it's update time. I think I fixed all bugs I found and those
pointed out in the reactions to my previous posts, but testing is still
welcome and needed :)
I attached a series of patches (reorganized, some were split, some where
merged, it should be easier to read now) and updated the git repo at
git.mercenariesguild.net
--
GCS/IT/M d- s+:- a--- C++ UL+++ US UB++ P+++ L+++ E--- W+ N+ o--
K- w--- O M-- V PS+ PE- Y+ PGP+++ t+ 5 X+ R tv+ b++ DI+++ D+++ G+
e- h! r y+
Gregor Best
From c9c9ba5538c8c6b195a81551573b1284d5c2450d Mon Sep 17 00:00:00 2001
From: Julien Danjou <julien <at> danjou.info>
Date: Fri, 16 Jan 2009 11:10:27 +0100
Subject: [PATCH 01/15] wibox: rebuild table at every draw
This will be necessary for using the new Lua layout system.
Signed-off-by: Julien Danjou <julien <at> danjou.info>
---
wibox.c | 29 ++++++-----------------------
widget.c | 7 ++++++-
widget.h | 2 +-
3 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/wibox.c b/wibox.c
index eb092b2..07043c2 100644
--- a/wibox.c
+++ b/wibox.c
<at> <at> -499,19 +499,6 <at> <at> luaA_wibox_new(lua_State *L)
return 1;
}
-/** Rebuild wibox widgets list.
- * \param L The Lua VM state.
- * \param wibox The wibox.
- */
-static void
-wibox_widgets_table_build(lua_State *L, wibox_t *wibox)
-{
- widget_node_array_wipe(&wibox->widgets);
- widget_node_array_init(&wibox->widgets);
- luaA_table2widgets(L, &wibox->widgets);
- wibox_need_update(wibox);
-}
-
/** Check if a wibox widget table has an item.
* \param L The Lua VM state.
* \param wibox The wibox.
<at> <at> -541,8 +528,8 <at> <at> luaA_wibox_invalidate_byitem(lua_State *L, const void *item)
wibox_t *wibox = *w;
if(luaA_wibox_hasitem(L, wibox, item))
{
- /* recompute widget node list */
- wibox_widgets_table_build(L, wibox);
+ /* update wibox */
+ wibox_need_update(wibox);
lua_pop(L, 1); /* remove widgets table */
}
<at> <at> -553,8 +540,8 <at> <at> luaA_wibox_invalidate_byitem(lua_State *L, const void *item)
client_t *c = *_c;
if(c->titlebar && luaA_wibox_hasitem(L, c->titlebar, item))
{
- /* recompute widget node list */
- wibox_widgets_table_build(L, c->titlebar);
+ /* update wibox */
+ wibox_need_update(c->titlebar);
lua_pop(L, 1); /* remove widgets table */
}
}
<at> <at> -848,12 +835,8 <at> <at> luaA_wibox_newindex(lua_State *L)
luaA_warn(L, "table is looping, cannot use this as widget table");
return 0;
}
- /* register object */
- luaA_register(L, 3, &wibox->widgets_table);
- /* duplicate table because next function will eat it */
- lua_pushvalue(L, -1);
- /* recompute widget node list */
- wibox_widgets_table_build(L, wibox);
+ luaA_register(L, 3, &(wibox->widgets_table));
+ wibox_need_update(wibox);
luaA_table2wtable(L);
break;
case A_TK_OPACITY:
diff --git a/widget.c b/widget.c
index c47d333..c2f6430 100644
--- a/widget.c
+++ b/widget.c
<at> <at> -103,7 +103,7 <at> <at> widget_getbycoords(orientation_t orientation, widget_node_array_t *widgets,
* \param L The Lua VM state.
* \param widgets The linked list of widget node.
*/
-void
+static void
luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
{
if(lua_istable(L, -1))
<at> <at> -193,6 +193,11 <at> <at> widget_render(wibox_t *wibox)
widget_node_array_t *widgets = &wibox->widgets;
+ widget_node_array_wipe(widgets);
+ widget_node_array_init(widgets);
+ lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
+ luaA_table2widgets(globalconf.L, widgets);
+
/* compute geometry */
for(int i = 0; i < widgets->len; i++)
if(widgets->tab[i].widget->align == AlignLeft
diff --git a/widget.h b/widget.h
index f2ca048..e9d9e7e 100644
--- a/widget.h
+++ b/widget.h
<at> <at> -73,7 +73,7 <at> <at> struct widget_node_t
widget_t *widget_getbycoords(orientation_t, widget_node_array_t *, int, int, int16_t *, int16_t *);
void widget_render(wibox_t *);
-void luaA_table2widgets(lua_State *, widget_node_array_t *);
+int luaA_widget_userdata_new(lua_State *, widget_t *);
void widget_invalidate_bywidget(widget_t *);
void widget_invalidate_bytype(widget_constructor_t *);
--
1.6.3.3
From 4d341aa74f65af7c79f9dc22b1393a943a6f4c59 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Mon, 6 Apr 2009 09:47:44 +0200
Subject: [PATCH 02/15] luaA_getopt_number(): also return def if stack top is neither number nor nil
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
luaa.h | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/luaa.h b/luaa.h
index ac99b0e..8c798ce 100644
--- a/luaa.h
+++ b/luaa.h
<at> <at> -135,9 +135,10 <at> <at> static inline lua_Number
luaA_getopt_number(lua_State *L, int idx, const char *name, lua_Number def)
{
lua_getfield(L, idx, name);
- lua_Number n = luaL_optnumber(L, -1, def);
+ if (lua_isnil(L, -1) || lua_isnumber(L, -1))
+ def = luaL_optnumber(L, -1, def);
lua_pop(L, 1);
- return n;
+ return def;
}
static inline const char *
--
1.6.3.3
From 0b85e6bb1a8ee3f5542b940db224f2c27d653cd0 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Tue, 10 Feb 2009 17:30:57 +0100
Subject: [PATCH 03/15] widgets: add bool widget_geometries(wibox_t *)
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
draw.c | 5 +-
widget.c | 174 ++++++++++++++++++++++++++++++-------------------
widget.h | 3 +-
widgets/graph.c | 10 +--
widgets/imagebox.c | 62 ++----------------
widgets/progressbar.c | 28 +-------
widgets/systray.c | 38 ++++-------
widgets/textbox.c | 42 +++---------
8 files changed, 146 insertions(+), 216 deletions(-)
diff --git a/draw.c b/draw.c
index 686bcfe..4a474c7 100644
--- a/draw.c
+++ b/draw.c
<at> <at> -247,10 +247,7 <at> <at> draw_text(draw_context_t *ctx, draw_text_context_t *data,
pango_layout_set_font_description(ctx->layout, globalconf.font->desc);
x = area.x + margin->left;
- /* + 1 is added for rounding, so that in any case of doubt we rather draw
- * the text 1px lower than too high which usually results in a better type
- * face */
- y = area.y + (ctx->height - ext->height + 1) / 2 + margin->top;
+ y = area.y + margin->top;
/* only honors alignment if enough space */
if(ext->width < area.width)
diff --git a/widget.c b/widget.c
index c2f6430..f1d5bc2 100644
--- a/widget.c
+++ b/widget.c
<at> <at> -129,6 +129,95 <at> <at> luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
}
}
+/** Retrieve a list of widget geometries using a Lua layout function.
+ * \param wibox The wibox.
+ * \return True is everything is ok, false otherwise.
+ * \todo What do we do if there's no layout defined?
+ */
+bool
+widget_geometries(wibox_t *wibox)
+{
+ /* get the layout field of the widget table */
+ if (wibox->widgets_table != LUA_REFNIL)
+ {
+ lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
+ lua_getfield(globalconf.L, -1, "layout");
+ }else
+ lua_pushnil(globalconf.L);
+
+ /* if the layout field is a function */
+ if(lua_isfunction(globalconf.L, -1))
+ {
+ /* Push 1st argument: wibox geometry */
+ area_t geometry = wibox->sw.geometry;
+ geometry.x = 0;
+ geometry.y = 0;
+ /* we need to exchange the width and height of the wibox window if it
+ * isn't at the top or bottom, so the layout function doesn't need to
+ * care about that */
+ if(wibox->sw.orientation != East)
+ {
+ int i = geometry.height;
+ geometry.height = geometry.width;
+ geometry.width = i;
+ }
+ geometry.height -= 2 * wibox->sw.border.width;
+ geometry.width -= 2 * wibox->sw.border.width;
+ luaA_pusharea(globalconf.L, geometry);
+ /* Re-push 2nd argument: widget table */
+ lua_pushvalue(globalconf.L, -3);
+ /* Push 3rd argument: wibox screen */
+ lua_pushnumber(globalconf.L, screen_array_indexof(&globalconf.screens, wibox->screen));
+ /* call the layout function with 3 arguments (wibox geometry, widget
+ * table, screen) and wait for one result */
+ if(lua_pcall(globalconf.L, 3, 1, 0))
+ {
+ warn("error running layout function: %s",
+ lua_tostring(globalconf.L, -1));
+ lua_pop(globalconf.L, 2);
+ return false;
+ }
+
+ lua_insert(globalconf.L, lua_gettop(globalconf.L) - 1);
+ lua_pop(globalconf.L, 1);
+ }
+ else
+ {
+ /* If no layout function has been specified, we just push a table with
+ * geometries onto the stack. These geometries are nothing fancy, they
+ * have x = y = 0 and their height and width set to the widgets demands
+ * or the wibox size, depending on which is less.
+ */
+
+ warn("no layout function defined or layout function invalid, falling back to simple default layout");
+ widget_node_array_t *widgets = &wibox->widgets;
+ widget_node_array_wipe(widgets);
+ widget_node_array_init(widgets);
+
+ lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
+ luaA_table2widgets(globalconf.L, widgets);
+ lua_pop(globalconf.L, 2);
+
+ lua_newtable(globalconf.L);
+ for(int i = 0; i < widgets->len; i++)
+ {
+ lua_pushnumber(globalconf.L, i + 1);
+ widget_t *widget = widgets->tab[i].widget;
+ lua_pushnumber(globalconf.L, screen_array_indexof(&globalconf.screens, wibox->screen));
+ area_t geometry = widget->extents(globalconf.L, widget);
+ lua_pop(globalconf.L, 1);
+ geometry.x = geometry.y = 0;
+ geometry.width = MIN(wibox->sw.geometry.width, geometry.width);
+ geometry.height = MIN(wibox->sw.geometry.height, geometry.height);
+
+ luaA_pusharea(globalconf.L, geometry);
+
+ lua_settable(globalconf.L, -3);
+ }
+ }
+ return true;
+}
+
/** Render a list of widgets.
* \param wibox The wibox.
* \todo Remove GC.
<at> <at> -136,14 +225,17 <at> <at> luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
void
widget_render(wibox_t *wibox)
{
+ lua_State *L = globalconf.L;
draw_context_t *ctx = &wibox->sw.ctx;
- int left = 0, right = 0;
area_t rectangle = { 0, 0, 0, 0 };
color_t col;
rectangle.width = ctx->width;
rectangle.height = ctx->height;
+ if (!widget_geometries(wibox))
+ return;
+
if(ctx->bg.alpha != 0xffff)
{
int x = wibox->sw.geometry.x, y = wibox->sw.geometry.y;
<at> <at> -195,74 +287,23 <at> <at> widget_render(wibox_t *wibox)
widget_node_array_wipe(widgets);
widget_node_array_init(widgets);
- lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
- luaA_table2widgets(globalconf.L, widgets);
-
- /* compute geometry */
- for(int i = 0; i < widgets->len; i++)
- if(widgets->tab[i].widget->align == AlignLeft
- && widgets->tab[i].widget->isvisible)
- {
- widgets->tab[i].geometry = widgets->tab[i].widget->geometry(widgets->tab[i].widget,
- wibox->screen, ctx->height,
- ctx->width - (left + right));
- widgets->tab[i].geometry.x = left;
- left += widgets->tab[i].geometry.width;
- }
+ lua_rawgeti(L, LUA_REGISTRYINDEX, wibox->widgets_table);
+ luaA_table2widgets(L, widgets);
- for(int i = widgets->len - 1; i >= 0; i--)
- if(widgets->tab[i].widget->align == AlignRight && widgets->tab[i].widget->isvisible)
- {
- widgets->tab[i].geometry = widgets->tab[i].widget->geometry(widgets->tab[i].widget,
- wibox->screen, ctx->height,
- ctx->width - (left + right));
- right += widgets->tab[i].geometry.width;
- widgets->tab[i].geometry.x = ctx->width - right;
- }
+ /* get computed geometries */
+ for(unsigned int i = 0; i < lua_objlen(L, -1); i++)
+ {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
- /* save left value */
- int fake_left = left;
+ widgets->tab[i].geometry.x = luaA_getopt_number(L, -1, "x", wibox->sw.geometry.x);
+ widgets->tab[i].geometry.y = luaA_getopt_number(L, -1, "y", wibox->sw.geometry.y);
+ widgets->tab[i].geometry.width = luaA_getopt_number(L, -1, "width", 1);
+ widgets->tab[i].geometry.height = luaA_getopt_number(L, -1, "height", 1);
- /* compute width of flex or fixed aligned widgets */
- int flex = 0;
- for(int i = 0; i < widgets->len; i++)
- if(widgets->tab[i].widget->align & (AlignFlex | AlignFixed)
- && widgets->tab[i].widget->isvisible)
- {
- if(widgets->tab[i].widget->align_supported & AlignFlex
- && widgets->tab[i].widget->align == AlignFlex)
- flex++;
- else
- fake_left += widgets->tab[i].widget->geometry(widgets->tab[i].widget,
- wibox->screen, ctx->height,
- ctx->width - (fake_left + right)).width;
- }
-
- /* now compute everybody together! */
- int flex_rendered = 0;
- for(int i = 0; i < widgets->len; i++)
- if(widgets->tab[i].widget->align & (AlignFlex | AlignFixed)
- && widgets->tab[i].widget->isvisible)
- {
- if(widgets->tab[i].widget->align_supported & AlignFlex
- && widgets->tab[i].widget->align == AlignFlex)
- {
- int width = (ctx->width - (right + fake_left)) / flex;
- /* give last pixels to last flex to be rendered */
- if(flex_rendered == flex - 1)
- width += (ctx->width - (right + fake_left)) % flex;
- widgets->tab[i].geometry = widgets->tab[i].widget->geometry(widgets->tab[i].widget,
- wibox->screen, ctx->height,
- width);
- flex_rendered++;
- }
- else
- widgets->tab[i].geometry = widgets->tab[i].widget->geometry(widgets->tab[i].widget,
- wibox->screen, ctx->height,
- ctx->width - (left + right));
- widgets->tab[i].geometry.x = left;
- left += widgets->tab[i].geometry.width;
- }
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
/* draw background image, only if the background color is not opaque */
if(wibox->bg_image && ctx->bg.alpha != 0xffff)
<at> <at> -276,7 +317,6 <at> <at> widget_render(wibox_t *wibox)
for(int i = 0; i < widgets->len; i++)
if(widgets->tab[i].widget->isvisible)
{
- widgets->tab[i].geometry.y = 0;
widgets->tab[i].widget->draw(widgets->tab[i].widget,
ctx, widgets->tab[i].geometry, wibox);
}
diff --git a/widget.h b/widget.h
index e9d9e7e..fb9c1b2 100644
--- a/widget.h
+++ b/widget.h
<at> <at> -37,7 +37,7 <at> <at> struct widget_t
/** Widget destructor */
widget_destructor_t *destructor;
/** Geometry function for drawing */
- area_t (*geometry)(widget_t *, screen_t *, int, int);
+ area_t (*geometry)(widget_t *, int);
/** Extents function */
area_t (*extents)(lua_State *, widget_t *);
/** Draw function */
<at> <at> -72,6 +72,7 <at> <at> struct widget_node_t
widget_t *widget_getbycoords(orientation_t, widget_node_array_t *, int, int, int16_t *, int16_t *);
void widget_render(wibox_t *);
+bool widget_geometries(wibox_t *);
int luaA_widget_userdata_new(lua_State *, widget_t *);
diff --git a/widgets/graph.c b/widgets/graph.c
index 2ff3048..878a1ac 100644
--- a/widgets/graph.c
+++ b/widgets/graph.c
<at> <at> -148,13 +148,13 <at> <at> graph_plot_get(graph_data_t *d, const char *title)
}
static area_t
-graph_geometry(widget_t *widget, screen_t *screen, int height, int width)
+graph_geometry(widget_t *widget, int screen)
{
area_t geometry;
graph_data_t *d = widget->data;
geometry.x = geometry.y = 0;
- geometry.height = height;
+ geometry.height = d->width;
geometry.width = d->width;
return geometry;
<at> <at> -163,11 +163,7 <at> <at> graph_geometry(widget_t *widget, screen_t *screen, int height, int width)
static area_t
graph_extents(lua_State *L, widget_t *widget)
{
- area_t geometry;
- graph_data_t *d = widget->data;
- geometry.width = geometry.height = d->width;
-
- return geometry;
+ return graph_geometry(widget, 0);
}
/** Draw a graph widget.
diff --git a/widgets/imagebox.c b/widgets/imagebox.c
index 195218d..9895c5c 100644
--- a/widgets/imagebox.c
+++ b/widgets/imagebox.c
<at> <at> -33,37 +33,15 <at> <at> typedef struct
} imagebox_data_t;
static area_t
-imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width)
+imagebox_geometry(widget_t *widget, int screen)
{
area_t geometry;
imagebox_data_t *d = widget->data;
if(d->image)
{
- int iwidth = image_getwidth(d->image);
- int iheight = image_getheight(d->image);
- if(d->resize)
- {
- double ratio = (double) height / iheight;
- geometry.width = ratio * iwidth;
- if(geometry.width > width)
- {
- geometry.width = 0;
- geometry.height = 0;
- }
- else
- geometry.height = height;
- }
- else if(iwidth <= width)
- {
- geometry.width = iwidth;
- geometry.height = height;
- }
- else
- {
- geometry.width = 0;
- geometry.height = 0;
- }
+ geometry.width = image_getwidth(d->image);
+ geometry.height = image_getheight(d->image);
}
else
{
<at> <at> -79,21 +57,7 <at> <at> imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width)
static area_t
imagebox_extents(lua_State *L, widget_t *widget)
{
- area_t geometry = {
- .x = 0,
- .y = 0,
- .width = 0,
- .height = 0
- };
- imagebox_data_t *d = widget->data;
-
- if(d->image)
- {
- geometry.width = image_getwidth(d->image);
- geometry.height = image_getheight(d->image);
- }
-
- return geometry;
+ return imagebox_geometry(widget, 0);
}
/** Draw an image.
<at> <at> -112,22 +76,8 <at> <at> imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p
if(d->bg.initialized)
draw_rectangle(ctx, geometry, 1.0, true, &d->bg);
- int y = geometry.y;
- int iheight = image_getheight(d->image);
- double ratio = d->resize ? (double) geometry.height / iheight : 1;
- switch(d->valign)
- {
- case AlignBottom:
- y += geometry.height - iheight;
- break;
- case AlignCenter:
- y += (geometry.height - iheight) / 2;
- break;
- default:
- break;
- }
-
- draw_image(ctx, geometry.x, y, ratio, d->image);
+ double ratio = d->resize ? (double) geometry.height / image_getheight(d->image) : 1;
+ draw_image(ctx, geometry.x, geometry.y, ratio, d->image);
}
}
diff --git a/widgets/progressbar.c b/widgets/progressbar.c
index 8564dc2..afb48fa 100644
--- a/widgets/progressbar.c
+++ b/widgets/progressbar.c
<at> <at> -133,12 +133,11 <at> <at> progressbar_bar_get(bar_array_t *bars, const char *title)
}
static area_t
-progressbar_geometry(widget_t *widget, screen_t *screen, int height, int width)
+progressbar_geometry(widget_t *widget, int screen)
{
area_t geometry;
progressbar_data_t *d = widget->data;
- geometry.height = height;
if(d->vertical)
{
<at> <at> -157,6 +156,7 <at> <at> progressbar_geometry(widget_t *widget, screen_t *screen, int height, int width)
}
geometry.width = pb_width + 2 * (d->border_width + d->border_padding);
}
+ geometry.height = geometry.width;
geometry.x = geometry.y = 0;
<at> <at> -166,29 +166,7 <at> <at> progressbar_geometry(widget_t *widget, screen_t *screen, int height, int width)
static area_t
progressbar_extents(lua_State *L, widget_t *widget)
{
- area_t geometry;
- progressbar_data_t *d = widget->data;
-
- if (d->vertical)
- {
- int pb_width = (int) ((d->width - 2 * (d->border_width + d->border_padding) * d->bars.len
- - d->gap * (d->bars.len - 1)) / d->bars.len);
- geometry.width = d->bars.len * (pb_width + 2 * (d->border_width + d->border_padding)
- + d->gap) - d->gap;
- }else
- {
- int pb_width = d->width - 2 * (d->border_width + d->border_padding);
- if(d->ticks_count && d->ticks_gap)
- {
- int unit = (pb_width + d->ticks_gap) / d->ticks_count;
- pb_width = unit * d->ticks_count - d->ticks_gap; /* rounded to match ticks... */
- }
- geometry.width = pb_width + 2 * (d->border_width + d->border_padding);
- }
-
- geometry.height = geometry.width;
-
- return geometry;
+ return progressbar_geometry(widget, 0);
}
/** Draw a progressbar.
diff --git a/widgets/systray.c b/widgets/systray.c
index cb3b4a9..0504be8 100644
--- a/widgets/systray.c
+++ b/widgets/systray.c
<at> <at> -25,6 +25,7 <at> <at>
#include "widget.h"
#include "screen.h"
#include "wibox.h"
+#include "structs.h"
#include "common/xembed.h"
#include "common/atoms.h"
<at> <at> -32,36 +33,16 <at> <at>
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
static area_t
-systray_geometry(widget_t *widget, screen_t *screen, int height, int width)
+systray_geometry(widget_t *widget, int screen)
{
area_t geometry;
- int phys_screen = screen_virttophys(screen_array_indexof(&globalconf.screens, screen)), n = 0;
-
- geometry.height = height;
-
- for(int i = 0; i < globalconf.embedded.len; i++)
- if(globalconf.embedded.tab[i].phys_screen == phys_screen)
- n++;
-
- /** \todo use class hints */
- geometry.width = MIN(n * height, width);
-
- geometry.x = geometry.y = 0;
-
- return geometry;
-}
-
-static area_t
-systray_extents(lua_State *L, widget_t *widget)
-{
- area_t geometry;
- int screen = screen_virttophys(luaL_optnumber(L, -1, 1)), n = 0;
+ int phys_screen = screen_virttophys(screen), n = 0;
geometry.height = 0;
int width = 0;
for(int i = 0; i < globalconf.embedded.len; i++)
- if(globalconf.embedded.tab[i].phys_screen == screen)
+ if(globalconf.embedded.tab[i].phys_screen == phys_screen)
{
xcb_get_geometry_cookie_t geo = xcb_get_geometry(globalconf.connection, globalconf.embedded.tab[i].win);
xcb_get_geometry_reply_t *g = xcb_get_geometry_reply(globalconf.connection, geo, NULL);
<at> <at> -73,11 +54,22 <at> <at> systray_extents(lua_State *L, widget_t *widget)
width = g->width;
}
+ /** \todo use class hints */
geometry.width = width * n;
+ geometry.x = geometry.y = 0;
+
return geometry;
}
+static area_t
+systray_extents(lua_State *L, widget_t *widget)
+{
+ int screen = screen_virttophys(luaL_optnumber(L, -1, 1));
+
+ return systray_geometry(widget, screen);
+}
+
static void
systray_draw(widget_t *widget, draw_context_t *ctx,
area_t geometry, wibox_t *p)
diff --git a/widgets/textbox.c b/widgets/textbox.c
index 9fb5f4d..6930ac6 100644
--- a/widgets/textbox.c
+++ b/widgets/textbox.c
<at> <at> -20,6 +20,7 <at> <at>
*/
#include "widget.h"
+#include "wibox.h"
#include "common/tokenize.h"
/** The textbox private data structure */
<at> <at> -53,26 +54,20 <at> <at> typedef struct
} textbox_data_t;
static area_t
-textbox_geometry(widget_t *widget, screen_t *screen, int height, int width)
+textbox_geometry(widget_t *widget, int screen)
{
- area_t geometry;
textbox_data_t *d = widget->data;
+ area_t geometry = d->extents;
+ geometry.width += d->margin.left + d->margin.left;
+ geometry.height += d->margin.bottom + d->margin.top;
- geometry.height = height;
-
- if(d->width)
- geometry.width = d->width;
- else if(widget->align == AlignFlex)
- geometry.width = width;
- else if(d->bg_image)
+ if(d->bg_image)
{
int bgi_height = image_getheight(d->bg_image);
int bgi_width = image_getwidth(d->bg_image);
double ratio = d->bg_resize ? (double) geometry.height / bgi_height : 1;
- geometry.width = MIN(width, MAX(d->extents.width + d->margin.left + d->margin.right,
MAX(d->width, bgi_width * ratio)));
+ geometry.width = MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, bgi_width
* ratio));
}
- else
- geometry.width = MIN(d->extents.width + d->margin.left + d->margin.right, width);
geometry.x = geometry.y = 0;
<at> <at> -82,27 +77,7 <at> <at> textbox_geometry(widget_t *widget, screen_t *screen, int height, int width)
static area_t
textbox_extents(lua_State *L, widget_t *widget)
{
- textbox_data_t *d = widget->data;
- area_t geometry = d->extents;
-
- geometry.width += d->margin.left + d->margin.left;
- geometry.height += d->margin.bottom + d->margin.top;
-
- if(d->bg_image)
- {
- int bgi_height = image_getheight(d->bg_image);
- int bgi_width = image_getwidth(d->bg_image);
- double ratio = d->bg_resize ? (double) geometry.height / bgi_height : 1;
- geometry.width = MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, bgi_width
* ratio));
- }
-
- if (d->data.len == 0)
- {
- geometry.width = 0;
- geometry.height = 0;
- }
-
- return geometry;
+ return textbox_geometry(widget, 0);
}
/** Draw a textbox widget.
<at> <at> -152,6 +127,7 <at> <at> textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p)
}
}
+ geometry.y += (geometry.height - textbox_geometry(widget, ctx->phys_screen).height -
p->sw.border.width + 1) / 2;
draw_text(ctx, &d->data, d->ellip, d->wrap, d->align, &d->margin, geometry, &d->extents);
}
--
1.6.3.3
From e277529f3ec3dd33ae37696179473881d927254a Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Fri, 20 Mar 2009 21:15:38 +0100
Subject: [PATCH 04/15] widgets: get rid of align attribute
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
draw.c | 3 ---
draw.h | 5 ++---
widget.c | 17 ++---------------
widget.h | 4 ----
widgets/textbox.c | 1 -
5 files changed, 4 insertions(+), 26 deletions(-)
diff --git a/draw.c b/draw.c
index 4a474c7..7bcbe25 100644
--- a/draw.c
+++ b/draw.c
<at> <at> -686,7 +686,6 <at> <at> draw_text_extents(draw_text_context_t *data)
/** Transform a string to a alignment_t type.
* Recognized string are flex, fixed, left, center, middle or right.
- * Everything else will be recognized as AlignLeft.
* \param align Atring with align text.
* \param len The string length.
* \return An alignment_t type.
<at> <at> -698,7 +697,6 <at> <at> draw_align_fromstr(const char *align, ssize_t len)
{
case A_TK_CENTER: return AlignCenter;
case A_TK_RIGHT: return AlignRight;
- case A_TK_FLEX: return AlignFlex;
case A_TK_FIXED: return AlignFixed;
case A_TK_TOP: return AlignTop;
case A_TK_BOTTOM: return AlignBottom;
<at> <at> -719,7 +717,6 <at> <at> draw_align_tostr(alignment_t a)
case AlignLeft: return "left";
case AlignCenter: return "center";
case AlignRight: return "right";
- case AlignFlex: return "flex";
case AlignFixed: return "fixed";
case AlignBottom: return "bottom";
case AlignTop: return "top";
diff --git a/draw.h b/draw.h
index 5f7c84b..bbf5128 100644
--- a/draw.h
+++ b/draw.h
<at> <at> -51,9 +51,8 <at> <at> typedef enum
AlignCenter = (1 << 1),
AlignTop = (1 << 2),
AlignBottom = (1 << 3),
- AlignFlex = (1 << 4),
- AlignFixed = (1 << 5),
- AlignMiddle = (1 << 6)
+ AlignFixed = (1 << 4),
+ AlignMiddle = (1 << 5)
} alignment_t;
typedef struct vector_t vector_t;
diff --git a/widget.c b/widget.c
index f1d5bc2..e968457 100644
--- a/widget.c
+++ b/widget.c
<at> <at> -387,14 +387,13 <at> <at> widget_invalidate_bywidget(widget_t *widget)
* \param L The Lua VM state.
*
* \luastack
- * \lparam A table with at least a type value. Optional attributes
- * are: align.
+ * \lparam A table with at least a type value.
* \lreturn A brand new widget.
*/
static int
luaA_widget_new(lua_State *L)
{
- const char *align, *type;
+ const char *type;
widget_t *w;
widget_constructor_t *wc = NULL;
size_t len;
<at> <at> -437,10 +436,6 <at> <at> luaA_widget_new(lua_State *L)
w->type = wc;
- align = luaA_getopt_lstring(L, 2, "align", "left", &len);
- w->align_supported |= AlignLeft | AlignRight | AlignFixed;
- w->align = draw_align_fromstr(align, len);
-
/* Set visible by default. */
w->isvisible = true;
<at> <at> -476,7 +471,6 <at> <at> luaA_widget_buttons(lua_State *L)
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
- * \lfield align The widget alignment.
* \lfield visible The widget visibility.
* \lfield mouse_enter A function to execute when the mouse enter the widget.
* \lfield mouse_leave A function to execute when the mouse leave the widget.
<at> <at> -494,9 +488,6 <at> <at> luaA_widget_index(lua_State *L)
switch((token = a_tokenize(buf, len)))
{
- case A_TK_ALIGN:
- lua_pushstring(L, draw_align_tostr(widget->align));
- return 1;
case A_TK_VISIBLE:
lua_pushboolean(L, widget->isvisible);
return 1;
<at> <at> -533,10 +524,6 <at> <at> luaA_widget_newindex(lua_State *L)
switch((token = a_tokenize(buf, len)))
{
- case A_TK_ALIGN:
- buf = luaL_checklstring(L, 3, &len);
- widget->align = draw_align_fromstr(buf, len);
- break;
case A_TK_VISIBLE:
widget->isvisible = luaA_checkboolean(L, 3);
break;
diff --git a/widget.h b/widget.h
index fb9c1b2..8d9fbb8 100644
--- a/widget.h
+++ b/widget.h
<at> <at> -48,10 +48,6 <at> <at> struct widget_t
int (*newindex)(lua_State *, awesome_token_t);
/** Mouse over event handler */
luaA_ref mouse_enter, mouse_leave;
- /** Alignement */
- alignment_t align;
- /** Supported alignment */
- alignment_t align_supported;
/** Misc private data */
void *data;
/** Button bindings */
diff --git a/widgets/textbox.c b/widgets/textbox.c
index 6930ac6..d943af4 100644
--- a/widgets/textbox.c
+++ b/widgets/textbox.c
<at> <at> -372,7 +372,6 <at> <at> luaA_textbox_newindex(lua_State *L, awesome_token_t token)
widget_t *
widget_textbox(widget_t *w)
{
- w->align_supported |= AlignFlex;
w->draw = textbox_draw;
w->index = luaA_textbox_index;
w->newindex = luaA_textbox_newindex;
--
1.6.3.3
From 5639d9320483f0e7242ff20f3dae684ca4b5ee28 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Fri, 29 May 2009 01:31:57 +0200
Subject: [PATCH 05/15] systray: don't crap up on odd-sized windows
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
widgets/systray.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/widgets/systray.c b/widgets/systray.c
index 0504be8..bd53ef6 100644
--- a/widgets/systray.c
+++ b/widgets/systray.c
<at> <at> -32,32 +32,27 <at> <at>
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
+typedef struct
+{
+ /* systray height */
+ int height;
+} systray_data_t;
+
static area_t
systray_geometry(widget_t *widget, int screen)
{
area_t geometry;
- int phys_screen = screen_virttophys(screen), n = 0;
-
- geometry.height = 0;
- int width = 0;
+ int phys_screen = screen_virttophys(screen), n = 0;
+ systray_data_t *d = widget->data;
for(int i = 0; i < globalconf.embedded.len; i++)
if(globalconf.embedded.tab[i].phys_screen == phys_screen)
- {
- xcb_get_geometry_cookie_t geo = xcb_get_geometry(globalconf.connection, globalconf.embedded.tab[i].win);
- xcb_get_geometry_reply_t *g = xcb_get_geometry_reply(globalconf.connection, geo, NULL);
-
n++;
- if(g->height > geometry.height)
- geometry.height = g->height;
- if(g->width > width)
- width = g->width;
- }
/** \todo use class hints */
- geometry.width = width * n;
-
- geometry.x = geometry.y = 0;
+ geometry.width = d->height * n;
+ geometry.height = d->height;
+ geometry.x = geometry.y = 0;
return geometry;
}
<at> <at> -87,6 +82,9 <at> <at> systray_draw(widget_t *widget, draw_context_t *ctx,
break;
}
+ systray_data_t *d = widget->data;
+ d->height = p->sw.geometry.height;
+
/* set wibox orientation */
/** \todo stop setting that property on each redraw */
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
<at> <at> -105,6 +103,9 <at> <at> widget_systray(widget_t *w)
w->geometry = systray_geometry;
w->extents = systray_extents;
+ systray_data_t *d = w->data = p_new(systray_data_t, 1);
+ d->height = 0;
+
return w;
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
--
1.6.3.3
From ef534b0e17f4f187c0ed75122c038152262fcd9d Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 2 Jul 2009 02:04:59 +0200
Subject: [PATCH 06/15] awful.util: add table.keys
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/util.lua.in | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/lib/awful/util.lua.in b/lib/awful/util.lua.in
index 23fa2c6..43dc095 100644
--- a/lib/awful/util.lua.in
+++ b/lib/awful/util.lua.in
<at> <at> -12,6 +12,8 <at> <at> local loadstring = loadstring
local loadfile = loadfile
local debug = debug
local print = print
+local pairs = pairs
+local ipairs = ipairs
local type = type
local rtable = table
local pairs = pairs
<at> <at> -282,4 +284,18 <at> <at> function linewrap(text, width, indent)
end)
end
+--- Get a sorted table with all integer keys from a table
+-- <at> param t the table for which the keys to get
+-- <at> return A table with keys
+function table.keys(t)
+ local keys = { }
+ for k, _ in pairs(t) do
+ rtable.insert(keys, k)
+ end
+ rtable.sort(keys, function (a, b)
+ return type(a) == type(b) and a < b or false
+ end)
+ return keys
+end
+
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
--
1.6.3.3
From 372b071f34f38b924860fe19b697e03c942af954 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 2 Jul 2009 02:05:29 +0200
Subject: [PATCH 07/15] awful.util: add table.keys_filtered
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/util.lua.in | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/lib/awful/util.lua.in b/lib/awful/util.lua.in
index 43dc095..ad43f6e 100644
--- a/lib/awful/util.lua.in
+++ b/lib/awful/util.lua.in
<at> <at> -298,4 +298,22 <at> <at> function table.keys(t)
return keys
end
+--- Filter a tables keys for certain content types
+-- <at> param t The table to retrieve the keys for
+-- <at> param ... the types to look for
+-- <at> return A filtered table with keys
+function table.keys_filter(t, ...)
+ local keys = table.keys(t)
+ local keys_filtered = { }
+ for _, k in pairs(keys) do
+ for _, et in pairs(arg) do
+ if type(t[k]) == et then
+ rtable.insert(keys_filtered, k)
+ break
+ end
+ end
+ end
+ return keys_filtered
+end
+
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
--
1.6.3.3
From b51b0af6829dee0b7f769395f99cfbcdc568a7df Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 2 Jul 2009 02:05:42 +0200
Subject: [PATCH 08/15] awful.util: add table.reverse
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/util.lua.in | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/lib/awful/util.lua.in b/lib/awful/util.lua.in
index ad43f6e..9f0cdc4 100644
--- a/lib/awful/util.lua.in
+++ b/lib/awful/util.lua.in
<at> <at> -316,4 +316,22 <at> <at> function table.keys_filter(t, ...)
return keys_filtered
end
+--- Reverse a table
+-- <at> param t the table to reverse
+-- <at> return the reversed table
+function table.reverse(t)
+ local tr = { }
+ -- reverse all elements with integer keys
+ for _, v in ipairs(t) do
+ rtable.insert(tr, 1, v)
+ end
+ -- add the remaining elements
+ for k, v in pairs(t) do
+ if type(v) ~= "number" then
+ tr[k] = v
+ end
+ end
+ return tr
+end
+
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
--
1.6.3.3
From 44d5af5c5595c2d40eb5bc10a4d6898e28294ffa Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 25 Jun 2009 01:15:07 +0200
Subject: [PATCH 09/15] awful.util: add table.clone
This is useful because tables get passed by reference instead of by
value, so we might end up modifying tables where we don't want it.
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/util.lua.in | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/lib/awful/util.lua.in b/lib/awful/util.lua.in
index 9f0cdc4..861a0e8 100644
--- a/lib/awful/util.lua.in
+++ b/lib/awful/util.lua.in
<at> <at> -334,4 +334,15 <at> <at> function table.reverse(t)
return tr
end
+--- Clone a table
+-- <at> param t the table to clone
+-- <at> return a clone of t
+function table.clone(t)
+ local c = { }
+ for k, v in pairs(t) do
+ c[k] = v
+ end
+ return c
+end
+
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
--
1.6.3.3
From aa6b9fff7f89dabc9802920f3acff846f507c302 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 2 Jul 2009 02:10:32 +0200
Subject: [PATCH 10/15] awful.widget: add layouts
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/widget/init.lua.in | 1 +
lib/awful/widget/layout/horizontal.lua.in | 159 +++++++++++++++++++++++++++++
lib/awful/widget/layout/init.lua.in | 7 ++
lib/awful/widget/layout/vertical.lua.in | 93 +++++++++++++++++
4 files changed, 260 insertions(+), 0 deletions(-)
create mode 100644 lib/awful/widget/layout/horizontal.lua.in
create mode 100644 lib/awful/widget/layout/init.lua.in
create mode 100644 lib/awful/widget/layout/vertical.lua.in
diff --git a/lib/awful/widget/init.lua.in b/lib/awful/widget/init.lua.in
index 6d4b51c..db39ed5 100644
--- a/lib/awful/widget/init.lua.in
+++ b/lib/awful/widget/init.lua.in
<at> <at> -12,6 +12,7 <at> <at> require("awful.widget.prompt")
require("awful.widget.progressbar")
require("awful.widget.graph")
require("awful.widget.layoutbox")
+require("awful.widget.layout")
--- Widget module for awful
module("awful.widget")
diff --git a/lib/awful/widget/layout/horizontal.lua.in b/lib/awful/widget/layout/horizontal.lua.in
new file mode 100644
index 0000000..cbdff21
--- /dev/null
+++ b/lib/awful/widget/layout/horizontal.lua.in
<at> <at> -0,0 +1,159 <at> <at>
+-------------------------------------------------
+-- <at> author Gregor Best <farhaven <at> googlemail.com>
+-- <at> copyright 2009 Gregor Best
+-- <at> release <at> AWESOME_VERSION <at>
+-------------------------------------------------
+
+-- Grab environment
+local ipairs = ipairs
+local type = type
+local table = table
+local math = math
+local util = require("awful.util")
+
+--- Horizontal widget layout
+module("awful.widget.layout.horizontal")
+
+local function horizontal(direction, bounds, widgets, screen)
+ local geometries = { }
+
+ if direction == "rightleft" then -- reverse widget table
+ widgets = util.table.reverse(widgets)
+ end
+
+ -- we are only interested in tables and widgets
+ local keys = util.table.keys_filter(widgets, "table", "widget")
+
+ for _, k in ipairs(keys) do
+ local v = widgets[k]
+ if type(v) == "table" then
+ local layout = v["layout"] or function (...) return horizontal(direction, ...) end
+ local g = layout(bounds, v, screen)
+ if direction == "rightleft" then
+ g = util.table.reverse(g)
+ end
+ bounds = g.free
+ for _, v in ipairs(g) do
+ table.insert(geometries, v)
+ end
+ elseif type(v) == "widget" then
+ local g
+ if v.visible then
+ g = v:extents(screen)
+ else
+ g = {
+ ["width"] = 0,
+ ["height"] = 0,
+ }
+ end
+ g.ratio = 1
+ if g.height > 0 then
+ g.ratio = g.width / g.height
+ end
+ if g.width > bounds.width then
+ g.width = bounds.width
+ end
+ g.height = bounds.height
+ g.y = bounds.y
+
+ if v.resize and g.width > 0 then
+ g.width = math.floor(g.height * g.ratio)
+ end
+
+ if direction == "leftright" then
+ g.x = bounds.x
+ bounds.x = bounds.x + g.width
+ else
+ g.x = bounds.x + bounds.width - g.width
+ end
+ bounds.width = bounds.width - g.width
+
+ table.insert(geometries, g)
+ end
+ end
+
+ if direction == "rightleft" then -- reverse geometries table
+ geometries = util.table.reverse(geometries)
+ end
+
+ geometries.free = util.table.clone(bounds)
+
+ return geometries
+end
+
+function flex(bounds, widgets, screen)
+ local geometries = {
+ free = util.table.clone(bounds)
+ }
+ geometries.free.width = 0
+
+ -- we are only interested in tables and widgets
+ local keys = util.table.keys_filter(widgets, "table", "widget")
+ local nelements = 0
+
+ for _, k in ipairs(keys) do
+ local v = widgets[k]
+ if type(v) == "table" then
+ nelements = nelements + 1
+ elseif type(v) == "widget" then
+ local g = v:extents()
+ if v.resize and g.width > 0 and g.height > 0 then
+ bounds.width = bounds.width - bounds.height
+ elseif g.width > 0 and g.height > 0 then
+ nelements = nelements + 1
+ end
+ end
+ end
+
+ nelements = (nelements == 0) and 1 or nelements
+
+ local x = bounds.x
+ local width = math.floor(bounds.width / nelements)
+
+ for _, k in ipairs(util.table.keys(widgets)) do
+ local v = widgets[k]
+ if type(v) == "table" then
+ local layout = v.layout or flex
+ local g = layout(bounds, v, screen)
+ for _, v in ipairs(g) do
+ table.insert(geometries, v)
+ end
+ bounds = g.free
+ elseif type(v) == "widget" then
+ local g = v:extents(screen)
+ g.resize = v.resize
+
+ if v.resize and g.width > 0 and g.height > 0 then
+ g.width = bounds.height
+ g.height = bounds.height
+ g.x = x
+ g.y = bounds.y
+ elseif g.width > 0 and g.height > 0 then
+ g.x = x
+ g.y = bounds.y
+ g.width = width
+ g.height = bounds.height
+ else
+ g.x = 0
+ g.y = 0
+ g.width = 0
+ g.height = 0
+ end
+ x = x + g.width
+
+ table.insert(geometries, g)
+ end
+ end
+
+ return geometries
+end
+
+function leftright(...)
+ return horizontal("leftright", ...)
+end
+
+function rightleft(...)
+ return horizontal("rightleft", ...)
+end
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/lib/awful/widget/layout/init.lua.in b/lib/awful/widget/layout/init.lua.in
new file mode 100644
index 0000000..f8d1d7b
--- /dev/null
+++ b/lib/awful/widget/layout/init.lua.in
<at> <at> -0,0 +1,7 <at> <at>
+require("awful.widget.layout.horizontal")
+require("awful.widget.layout.vertical")
+
+-- Widget layouts
+module("awful.widget.layout")
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/lib/awful/widget/layout/vertical.lua.in b/lib/awful/widget/layout/vertical.lua.in
new file mode 100644
index 0000000..fa74ada
--- /dev/null
+++ b/lib/awful/widget/layout/vertical.lua.in
<at> <at> -0,0 +1,93 <at> <at>
+-------------------------------------------------
+-- <at> author Gregor Best <farhaven <at> googlemail.com>
+-- <at> copyright 2009 Gregor Best
+-- <at> release <at> AWESOME_VERSION <at>
+-------------------------------------------------
+
+-- Grab environment
+local ipairs = ipairs
+local type = type
+local table = table
+local math = math
+local util = require("awful.util")
+
+--- Vertical widget layout
+module("awful.widget.layout.vertical")
+
+local function vertical(direction, bounds, widgets, screen)
+ local geometries = {
+ free = util.table.clone(bounds)
+ }
+
+ if direction == "bottomup" then -- reverse widget table
+ widgets = util.table.reverse(widgets)
+ end
+
+ -- we are only interested in tables and widgets
+ local keys = util.table.keys_filter(widgets, "table", "widget")
+ local nelements = #keys
+ local height = math.floor(bounds.height / nelements)
+
+ for _, k in ipairs(keys) do
+ local v = widgets[k]
+ if type(v) == "table" then
+ local layout = v["layout"] or function (...) return vertical(direction, ...) end
+ -- we need to modify the height a bit because vertical layouts always span the
+ -- whole height
+ bounds.height = height
+ local g = layout(bounds, v, screen)
+ for _, v in ipairs(g) do
+ table.insert(geometries, v)
+ end
+ bounds = g.free
+ geometries.free = util.table.clone(g.free)
+ elseif type(v) == "widget" then
+ local g
+ if v.visible then
+ g = v:extents(screen)
+ else
+ g = {
+ ["width"] = 0,
+ ["height"] = 0
+ }
+ end
+
+ g.ratio = 1
+ if g.height > 0 and g.width > 0 then
+ g.ratio = g.width / g.height
+ end
+ g.height = height
+ if v.resize then
+ g.width = g.height * g.ratio
+ end
+ g.width = math.min(g.width, bounds.width)
+ geometries.free.x = bounds.x + math.max(geometries.free.x - bounds.x, g.width)
+ geometries.free.width = bounds.width - geometries.free.x
+ g.x = bounds.x
+
+ if direction == "topdown" then
+ g.y = bounds.y
+ bounds.y = bounds.y + g.height
+ else
+ g.y = bounds.y + bounds.height - g.height
+ end
+ bounds.height = bounds.height - g.height
+
+ table.insert(geometries, g)
+ end
+ end
+
+ if direction == "bottomup" then
+ geometries = util.table.reverse(geometries)
+ end
+
+ return geometries
+end
+
+function topdown(...)
+ return vertical("topdown", ...)
+end
+
+function bottomup(...)
+ return vertical("bottomup", ...)
+end
--
1.6.3.3
From c358e0546555d290d55710862d983c798ff44d27 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Tue, 10 Mar 2009 19:31:28 +0100
Subject: [PATCH 11/15] awesomerc.lua: add support for widget layouts
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
awesomerc.lua.in | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/awesomerc.lua.in b/awesomerc.lua.in
index 4783c2f..beead93 100644
--- a/awesomerc.lua.in
+++ b/awesomerc.lua.in
<at> <at> -172,13 +172,22 <at> <at> for s = 1, screen.count() do
-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", screen = s })
-- Add widgets to the wibox - order matters
- mywibox[s].widgets = { mylauncher,
- mytaglist[s],
- mytasklist[s],
- mypromptbox[s],
- mytextbox,
- mylayoutbox[s],
- s == 1 and mysystray or nil }
+ mywibox[s].widgets = {
+ mylauncher,
+ mytaglist[s],
+ mypromptbox[s],
+ {
+ mytextbox,
+ mylayoutbox[s],
+ s == 1 and mysystray or nil,
+ layout = awful.widget.layout.horizontal.rightleft
+ },
+ {
+ mytasklist[s],
+ layout = awful.widget.layout.horizontal.flex
+ },
+ layout = awful.widget.layout.horizontal.leftright
+ }
end
-- }}}
--
1.6.3.3
From 4576c634464f38d523a4b81ec9b1a5faff26b7ae Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Tue, 10 Mar 2009 20:25:56 +0100
Subject: [PATCH 12/15] naughty: add support for widget layouts
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/naughty.lua.in | 25 ++++++++++++++++++++-----
1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/lib/naughty.lua.in b/lib/naughty.lua.in
index c8a049c..ce17024 100644
--- a/lib/naughty.lua.in
+++ b/lib/naughty.lua.in
<at> <at> -20,6 +20,7 <at> <at> local button = require("awful.button")
local util = require("awful.util")
local wibox = require("awful.wibox")
local bt = require("beautiful")
+local layout = require("awful.widget.layout")
--- Notification library
module("naughty")
<at> <at> -378,18 +379,32 <at> <at> function notify(args)
notification.width = width + 2 * (border_width or 0)
-- position the wibox
- local offset = get_offset(screen, notification.position, nil, notification.width, notification.height)
- notification.box:geometry({ width = width,
- height = height,
+ if iconbox and iconbox.image.height > textbox:extents()["height"] then
+ notification.height = iconbox.image.height + (2 * config.border_width)
+ else
+ notification.height = textbox:extents()["height"] + (2 * config.border_width)
+ end
+ notification.width = (iconbox and iconbox:extents()["width"] or 0) + textbox:extents()["width"] +
(2 * config.border_width)
+
+ if capi.screen[screen].workarea.width < notification.width then
+ notification.width = capi.screen[screen].workarea.width - (2 * config.border_width) - (2 * config.padding)
+ end
+ if capi.screen[screen].workarea.height < notification.height then
+ notification.height = capi.screen[screen].workarea.height - (2 * config.border_width) - (2 * config.padding)
+ end
+
+ local offset = get_offset(screen, notification.position, notification.idx, notification.width, notification.height)
+ notification.box.ontop = ontop
+ notification.box:geometry({ width = notification.width,
+ height = notification.height,
x = offset.x,
y = offset.y })
- notification.box.ontop = ontop
notification.box.opacity = opacity
notification.box.screen = screen
notification.idx = offset.idx
-- populate widgets
- notification.box.widgets = { iconbox, textbox }
+ notification.box.widgets = { iconbox, textbox, ["layout"] = layout.horizontal.leftright }
-- insert the notification to the table
table.insert(notifications[screen][notification.position], notification)
--
1.6.3.3
From 0da1afe5441620af49fe9b54078a207212ba4db9 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Tue, 10 Mar 2009 20:31:41 +0100
Subject: [PATCH 13/15] awful.menu: add support for widget layouts
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/menu.lua.in | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/awful/menu.lua.in b/lib/awful/menu.lua.in
index 9f8f40a..c7e17e4 100644
--- a/lib/awful/menu.lua.in
+++ b/lib/awful/menu.lua.in
<at> <at> -22,6 +22,7 <at> <at> local capi =
}
local util = require("awful.util")
local tags = require("awful.tag")
+local layout = require("awful.widget.layout")
local awbeautiful = require("beautiful")
local awibox = require("awful.wibox")
local tonumber = tonumber
<at> <at> -180,7 +181,7 <at> <at> local function add_item(data, num, item_info)
)
-- Create the item label widget
- local label = widget({ type = "textbox", align = "left" })
+ local label = widget({ type = "textbox" })
label.text = item_info[1]
label:margin({ left = data.h + 2 })
-- Set icon if needed
<at> <at> -206,7 +207,7 <at> <at> local function add_item(data, num, item_info)
-- Create the submenu icon widget
local submenu
if type(item_info[2]) == "table" then
- submenu = widget({ type = "imagebox", align = "right" })
+ submenu = widget({ type = "imagebox" })
submenu.image = data.theme.submenu_icon and image(data.theme.submenu_icon)
submenu:buttons(bindings)
<at> <at> -214,7 +215,17 <at> <at> local function add_item(data, num, item_info)
end
-- Add widgets to the wibox
- item.widgets = { label, submenu }
+ item.widgets = {
+ {
+ label,
+ ["layout"] = layout.horizontal.leftright
+ },
+ {
+ submenu,
+ ["layout"] = layout.horizontal.rightleft
+ },
+ ["layout"] = layout.horizontal.leftright
+ }
item.ontop = true
<at> <at> -254,7 +265,7 <at> <at> local function set_coords(menu, screen_idx)
local screen_w = s_geometry.x + s_geometry.width
local screen_h = s_geometry.y + s_geometry.height
- local i_h = menu.h - menu.theme.border_width
+ local i_h = menu.h + menu.theme.border_width
local m_h = (i_h * #menu.items) + menu.theme.border_width
if menu.parent then
<at> <at> -290,7 +301,7 <at> <at> function show(menu, keygrabber)
width = menu.w,
height = menu.h,
x = menu.x,
- y = menu.y + (num - 1) * (menu.h - menu.theme.border_width)
+ y = menu.y + (num - 1) * (menu.h + menu.theme.border_width)
})
wibox.screen = screen_index
end
--
1.6.3.3
From f3ef5010cfceaaecf0d959a1888463137aba81c8 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Fri, 20 Mar 2009 21:08:12 +0100
Subject: [PATCH 14/15] invaders: add support for widget layouts
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/invaders.lua.in | 46 +++++++++++++++++++++++++++-------------------
1 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/lib/invaders.lua.in b/lib/invaders.lua.in
index 25a256a..00bcaaa 100644
--- a/lib/invaders.lua.in
+++ b/lib/invaders.lua.in
<at> <at> -375,16 +375,9 <at> <at> function game.quit()
end
function game.highscore_show ()
- gamedata.highscore.window:geometry({ height = 140,
- width = 200,
- x = gamedata.field.x + math.floor(gamedata.field.w / 2) - 100,
- y = gamedata.field.y + math.floor(gamedata.field.h / 2) - 55 })
- gamedata.highscore.window.screen = gamedata.screen
-
gamedata.highscore.table = widget({ type = "textbox" })
- gamedata.highscore.window.widgets = gamedata.highscore.table
- gamedata.highscore.table.text = " Highscores:\n"
+ gamedata.highscore.table.text = "\tHighscores:\t\n"
for i = 1, 5 do
gamedata.highscore.table.text = gamedata.highscore.table.text .. "\n\t" .. gamedata.highscore[i]
<at> <at> -392,6 +385,13 <at> <at> function game.highscore_show ()
gamedata.highscore.table.text = gamedata.highscore.table.text .. "\n\n Press Q to quit"
+ gamedata.highscore.window:geometry(gamedata.highscore.table:extents())
+ gamedata.highscore.window:geometry({ x = gamedata.field.x + math.floor(gamedata.field.w / 2) - 100,
+ y = gamedata.field.y + math.floor(gamedata.field.h / 2) - 55 })
+ gamedata.highscore.window.screen = gamedata.screen
+
+ gamedata.highscore.window.widgets = gamedata.highscore.table
+
local fh = io.open(gamedata.cachedir.."/highscore_invaders", "w")
if not fh then
<at> <at> -494,23 +494,31 <at> <at> function run(args)
gamedata.field.background.screen = gamedata.screen
end
+ gamedata.field.status = widget({ type = "textbox" })
+ gamedata.field.status.text = gamedata.score.." | "..gamedata.round .. " "
+
+ gamedata.field.caption = widget({ type = "textbox" })
+ gamedata.field.caption.text = " Awesome Invaders"
+
gamedata.field.north = wibox({ bg = gamedata.btheme.bg_focus or "#333333",
fg = gamedata.btheme.fg_focus or "#FFFFFF" })
gamedata.field.north:geometry({ width = gamedata.field.w + 10,
- height = 15,
+ height = gamedata.field.caption:extents()["height"],
x = gamedata.field.x - 5,
- y = gamedata.field.y - 15 })
+ y = gamedata.field.y - gamedata.field.caption:extents()["height"] })
gamedata.field.north.screen = gamedata.screen
- gamedata.field.status = widget({ type = "textbox",
- align = "right" })
- gamedata.field.status.text = gamedata.score.." | "..gamedata.round .. " "
-
- gamedata.field.caption = widget({ type = "textbox",
- align = "left" })
- gamedata.field.caption.text = " Awesome Invaders"
-
- gamedata.field.north.widgets = { gamedata.field.caption, gamedata.field.status }
+ gamedata.field.north.widgets = {
+ {
+ gamedata.field.caption,
+ ["layout"] = awful.widget.layout.horizontal.leftright
+ },
+ {
+ gamedata.field.status,
+ ["layout"] = awful.widget.layout.horizontal.rightleft
+ },
+ ["layout"] = awful.widget.layout.horizontal.rightleft
+ }
gamedata.field.south = wibox({ bg = gamedata.btheme.bg_focus or "#333333",
fg = gamedata.btheme.fg_focus or "#FFFFFF" })
--
1.6.3.3
From 4f7e897a1e49b6012552519fccaadb985e2ee182 Mon Sep 17 00:00:00 2001
From: Gregor Best <farhaven <at> googlemail.com>
Date: Thu, 2 Jul 2009 01:41:26 +0200
Subject: [PATCH 15/15] titlebar: add widget layout support
Signed-off-by: Gregor Best <farhaven <at> googlemail.com>
---
lib/awful/titlebar.lua.in | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/lib/awful/titlebar.lua.in b/lib/awful/titlebar.lua.in
index e1a90ee..c94dfd8 100644
--- a/lib/awful/titlebar.lua.in
+++ b/lib/awful/titlebar.lua.in
<at> <at> -24,6 +24,7 <at> <at> local util = require("awful.util")
local widget = require("awful.widget")
local mouse = require("awful.mouse")
local client = require("awful.client")
+local layout = require("awful.widget.layout")
--- Titlebar module for awful
module("awful.titlebar")
<at> <at> -93,8 +94,8 <at> <at> function add(c, args)
-- data[c].button_sets for late updates and add the
-- individual buttons to the array part of the widget
-- list
- local widget_list = { appicon = appicon, title = title }
- local iw = #widget_list
+ local widget_list = { layout = layout.horizontal.rightleft }
+ local iw = 1
local is = 1
data[c].button_sets = {}
for i = 1, #button_groups do
<at> <at> -109,7 +110,18 <at> <at> function add(c, args)
end
end
- tb.widgets = widget_list
+ tb.widgets = {
+ {
+ appicon = appicon,
+ layout = layout.horizontal.leftright
+ },
+ widget_list,
+ {
+ title = title,
+ layout = layout.horizontal.flex
+ },
+ layout = layout.horizontal.leftright
+ }
c.titlebar = tb
update(c)
<at> <at> -122,13 +134,13 <at> <at> function update(c, prop)
if type(c) == "client" and c.titlebar and data[c] then
local widgets = c.titlebar.widgets
if prop == "name" then
- if widgets.title then
- widgets.title.text = "<span font_desc='" .. data[c].font ..
+ if widgets[3].title then
+ widgets[3].title.text = "<span font_desc='" .. data[c].font ..
"'> ".. util.escape(c.name) .. " </span>"
end
elseif prop == "icon" then
- if widgets.appicon then
- widgets.appicon.image = c.icon
+ if widgets[1].appicon then
+ widgets[1].appicon.image = c.icon
end
end
if capi.client.focus == c then
<at> <at> -387,11 +399,11 <at> <at> local floating_buttons = button_group("floating",
{ idx = "n/a", img = "normal_active", action = floating_update },
{ idx = "f/a", img = "focus_active", action = floating_update })
-button_groups = { ontop_buttons,
+button_groups = { close_buttons,
+ ontop_buttons,
sticky_buttons,
maximized_buttons,
- floating_buttons,
- close_buttons }
+ floating_buttons }
-- Register standards hooks
hooks.focus.register(update)
--
--
1.6.3.3