dante4d | 1 Jul 01:25 2009
Picon

Awesome systray support in Java

Hello,

I just started writing some Java app and wanted to use systray icon. However, Java tells me that systray is not supported here. Which is weird, because I already used Java systray in awesome before.. Below, I copied some code snippets from debugging. I think the way to go is to enrich XToolkit class so that it recognizes awesome wm and know's it's tray capable...

Here's what I do (I follow sun.com example):

        // FIXME Awesome supports tray, but JRE doesn't detect it as tray capable wm.
        if (SystemTray.isSupported()) {
            SystemTray tray = SystemTray.getSystemTray();

And isSupported() returns false, so I debug and step in:

    public static boolean isSupported() {
        if (Toolkit.getDefaultToolkit() instanceof SunToolkit) {

            return ((SunToolkit)Toolkit.getDefaultToolkit()).isTraySupported();

        } else if (Toolkit.getDefaultToolkit() instanceof HeadlessToolkit) {

            return ((HeadlessToolkit)Toolkit.getDefaultToolkit()).isTraySupported();
        }
        return false;
    }

This get's called:

            return ((SunToolkit)Toolkit.getDefaultToolkit()).isTraySupported();

So I step into isTraySupported():

    public boolean isTraySupported() {
        int wm = XWM.getWMID();
        if (wm == XWM.METACITY_WM || wm == XWM.KDE2_WM)
        {
            return true;
        }
        return false;
    }

This get's called:

        int wm = XWM.getWMID();

And returns XWM.OTHER_WM - 3. That is not equal XWM.METACITY_WM or XWM.KDE2_WM, so false is returned. I wonder why it worked a few months ago and now doesn't...

Anyway, I question myself how should I proceed?

  1. Probably, I could trick Java into thinking I run Metacity WM (which is a nasty hack I'd say)...
  2. I can do something so the JRE code gets updated and recognizes awesome as systray capable WM, but that's probably a long way to go. But I believe it's the right one...
  3. I can use some other way to obtain SystemTray instance...
Here is the whole method that gets WMID:

    static int getWMID() {
        if (insLog.isLoggable(Level.FINEST)) {
            insLog.finest("awt_wmgr = " + awt_wmgr);
        }
        /*
         * Ideally, we should support cases when a different WM is started
         * during a Java app lifetime.
         */

        if (awt_wmgr != XWM.UNDETERMINED_WM) {
            return awt_wmgr;
        }

        XSetWindowAttributes substruct = new XSetWindowAttributes();
        XToolkit.awtLock();
        try {
            if (isNoWM()) {
                awt_wmgr = XWM.NO_WM;
                return awt_wmgr;
            }

            // Initialize _NET protocol - used to detect Window Manager.
            // Later, WM will initialize its own version of protocol
            XNETProtocol l_net_protocol = g_net_protocol = new XNETProtocol();
            l_net_protocol.detect();
            if (log.isLoggable(Level.FINE) && l_net_protocol.active()) {
                log.fine("_NET_WM_NAME is " + l_net_protocol.getWMName());
            }
            XWINProtocol win = g_win_protocol = new XWINProtocol();
            win.detect();

            /* actual check for IceWM to follow below */
            boolean doIsIceWM = prepareIsIceWM(); /* and let IceWM to act */

            /*
             * Ok, some WM is out there.  Check which one by testing for
             * "distinguishing" atoms.
             */
            if (isEnlightenment()) {
                awt_wmgr = XWM.ENLIGHTEN_WM;
            } else if (isMetacity()) {
                awt_wmgr = XWM.METACITY_WM;
            } else if (isSawfish()) {
                awt_wmgr = XWM.SAWFISH_WM;
            } else if (isKDE2()) {
                awt_wmgr =XWM.KDE2_WM;
            } else if (isCompiz()) {
                awt_wmgr = XWM.COMPIZ_WM;
            } else if (isLookingGlass()) {
                awt_wmgr = LG3D_WM;
            } else if (doIsIceWM && isIceWM()) {
                awt_wmgr = XWM.ICE_WM;
            }
            /*
             * We don't check for legacy WM when we already know that WM
             * supports WIN or _NET wm spec.
             */
            else if (l_net_protocol.active()) {
                awt_wmgr = XWM.OTHER_WM;
            } else if (win.active()) {
                awt_wmgr = XWM.OTHER_WM;
            }
            /*
             * Check for legacy WMs.
             */
            else if (isCDE()) { /* XXX: must come before isMotif */
                awt_wmgr = XWM.CDE_WM;
            } else if (isMotif()) {
                awt_wmgr = XWM.MOTIF_WM;
            } else if (isOpenLook()) {
                awt_wmgr = XWM.OPENLOOK_WM;
            } else {
                awt_wmgr = XWM.OTHER_WM;
            }

            return awt_wmgr;
        } finally {
            XToolkit.awtUnlock();
            substruct.dispose();
        }
    }

Regards,
David
Julien Danjou | 1 Jul 07:45 2009

Re: Awesome systray support in Java

At 1246404341 time_t, dante4d wrote:
> So I step into isTraySupported():
> 
>     public boolean isTraySupported() {
>         int wm = XWM.getWMID();
>         if (wm == XWM.METACITY_WM || wm == XWM.KDE2_WM)
>         {
>             return true;
>         }
>         return false;
>     }

For god's sake, how can this guys be so lame. That's fucking impressive.

> *Anyway, I question myself how should I proceed?
> *
> 
>    1. *Probably, I could trick Java into thinking I run Metacity WM (which
>    is a nasty hack I'd say)...*

Yes, probably the simpler way.

>    2. *I can do something so the JRE code gets updated and recognizes
>    awesome as systray capable WM, but that's probably a long way to go. But I
>    believe it's the right one...*

I don't know which versino of JRE you use, but it might be possible that
it's fixed this 1.7. I heard that the reparenting problem is also fixed
in this version, but I did not test.

>    3. *I can use some other way to obtain SystemTray instance...*

Probably. In fact, if the check would return true, you probably get the
SystemTray.

4. Stop using Java.

Cheers,
--

-- 
Julien Danjou
// ᐰ <julien <at> danjou.info>   http://julien.danjou.info
// 9A0D 5FD9 EB42 22F6 8974  C95C A462 B51E C2FE E5CD
// Life is life. Lalalalala.
dante4d | 1 Jul 12:17 2009
Picon

Re: Awesome systray support in Java

Hi,

Yes, probably the simpler way.

Well, but I have no idea how to do that. JRE calls some X methods using JNI to check the underlying WM...

I don't know which versino of JRE you use, but it might be possible that
it's fixed this 1.7. I heard that the reparenting problem is also fixed
in this version, but I did not test.

Always the latest stable packages from Arch repository... I think it's still 1.6 (openjdk6 package), I will check for version 1.7 and see what it brings.

Probably. In fact, if the check would return true, you probably get the
SystemTray.

That's not true. SystmTray itself calls the isTraySupported() method and throws some exception if it returns false. I would have to override standard SystemTray class. If it would be so straightforward, I would not be writing this in the first place...

4. Stop using Java.
 
Nothing else is reasonably portable IMHO.

Ok, so then I have to check further how JRE identifies the WM and tells if it's tray capable and if it's fixed in 1.7.

Regards,
David

On Wed, Jul 1, 2009 at 7:45 AM, Julien Danjou <julien <at> danjou.info> wrote:
At 1246404341 time_t, dante4d wrote:
> So I step into isTraySupported():
>
>     public boolean isTraySupported() {
>         int wm = XWM.getWMID();
>         if (wm == XWM.METACITY_WM || wm == XWM.KDE2_WM)
>         {
>             return true;
>         }
>         return false;
>     }

For god's sake, how can this guys be so lame. That's fucking impressive.

> *Anyway, I question myself how should I proceed?
> *
>
>    1. *Probably, I could trick Java into thinking I run Metacity WM (which
>    is a nasty hack I'd say)...*

Yes, probably the simpler way.

>    2. *I can do something so the JRE code gets updated and recognizes
>    awesome as systray capable WM, but that's probably a long way to go. But I
>    believe it's the right one...*

I don't know which versino of JRE you use, but it might be possible that
it's fixed this 1.7. I heard that the reparenting problem is also fixed
in this version, but I did not test.

>    3. *I can use some other way to obtain SystemTray instance...*

Probably. In fact, if the check would return true, you probably get the
SystemTray.

4. Stop using Java.

Cheers,
--
Julien Danjou
// ᐰ <julien <at> danjou.info>   http://julien.danjou.info
// 9A0D 5FD9 EB42 22F6 8974  C95C A462 B51E C2FE E5CD
// Life is life. Lalalalala.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkpK990ACgkQpGK1HsL+5c0eHgCdH5GMpPqa3YnJgePT3ykJtozp
sgAAmwe/9N9q13RbGoFK6k+cRfnIm5Iu
=xJaZ
-----END PGP SIGNATURE-----


awesome | 1 Jul 12:19 2009

[awesome bugs] #545 - strange with smplayer playlist window

THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.

The following task has a new comment added:

FS#545 - strange with smplayer playlist window
User who did this - lego (lego)

----------
I solve it by adding 
      if c.role == "playlistdock" then
		capi.client.lower()
      end
in awful.hooks.manage.register
----------

More information can be found at the following URL:
http://awesome.naquadah.org/bugs/index.php?do=details&task_id=545#comment1292

You are receiving this message because you have requested it from the Flyspray bugtracking system.  If you
did not expect this message or don't want to receive mails in future, you can change your notification
settings at the URL shown above.

--

-- 
To unsubscribe, send mail to awesome-devel-unsubscribe <at> naquadah.org.

Julien Danjou | 1 Jul 12:22 2009

Re: Awesome systray support in Java

At 1246443420 time_t, dante4d wrote:
> Well, but I have no idea how to do that. JRE calls some X methods using JNI
> to check the underlying WM...

You can change the wm name. There's a tool in dwm utils IIRC to do that.

> Nothing else is reasonably portable IMHO.

Troll spotted.

Cheers,
--

-- 
Julien Danjou
// ᐰ <julien <at> danjou.info>   http://julien.danjou.info
// 9A0D 5FD9 EB42 22F6 8974  C95C A462 B51E C2FE E5CD
// There is nothing under this line.
awesome | 1 Jul 13:07 2009

[awesome bugs] #547 - evince: F5 not working in Presentation Mode

THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.

A new Flyspray task has been opened.  Details are below. 

User who did this - Michal Nowak (mnowak) 

Attached to Project - awesome
Summary - evince: F5 not working in Presentation Mode
Task Type - Bug Report
Category - Core
Status - Unconfirmed
Assigned To - 
Operating System - All
Severity - Low
Priority - Normal
Reported Version - 3.3.1
Due in Version - Undecided
Due Date - Undecided
Details - https://bugzilla.redhat.com/show_bug.cgi?id=490973

Description of problem:

Go to Presentation Mode (via F5 key) and try to get back via the same key -
it's not working. Fullscreen - F11 - is fine here.

ewman ~ $ evince Documents/Noc_kejkliru_2009-1.pdf 

<< now press F5 >>

(evince:5399): Gdk-CRITICAL **: gdk_x11_atom_to_xatom_for_display: assertion
`atom != GDK_NONE' failed

<< now press F5 >>

(evince:5399): Gdk-CRITICAL **: gdk_x11_atom_to_xatom_for_display: assertion
`atom != GDK_NONE' failed

Version-Release number of selected component (if applicable):

evince-2.26.2-1.fc11.x86_64

How reproducible:

always

I believe this is happening in Awesome only.

More information can be found at the following URL:
http://awesome.naquadah.org/bugs/index.php?do=details&task_id=547

You are receiving this message because you have requested it from the Flyspray bugtracking system.  If you
did not expect this message or don't want to receive mails in future, you can change your notification
settings at the URL shown above.

--

-- 
To unsubscribe, send mail to awesome-devel-unsubscribe <at> naquadah.org.

Uli Schlachter | 1 Jul 13:23 2009
Picon

Re: Awesome systray support in Java


dante4d wrote:
>> 4. Stop using Java.
> Nothing else is reasonably portable IMHO.

Except gtk and kde and lots of other toolkits.
Oh and these aren't known for their sucky WM interactions...
--
"Do you know that books smell like nutmeg or some spice from a foreign land?"
                                                  -- Faber in Fahrenheit 451
awesome | 1 Jul 16:07 2009

[awesome bugs] #547 - evince: F5 not working in Presentation Mode

THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.

The following task has a new comment added:

FS#547 - evince: F5 not working in Presentation Mode
User who did this - Julien Danjou (jd)

----------
Both presentation and fullscreen mode works fine here with evince 2.22.2 and awesome 3.1.
----------

More information can be found at the following URL:
http://awesome.naquadah.org/bugs/index.php?do=details&task_id=547#comment1293

You are receiving this message because you have requested it from the Flyspray bugtracking system.  If you
did not expect this message or don't want to receive mails in future, you can change your notification
settings at the URL shown above.

--

-- 
To unsubscribe, send mail to awesome-devel-unsubscribe <at> naquadah.org.

Romain Chossart | 1 Jul 21:36 2009
Picon

awful.client.swap.bydirection() calls mouse focus hook

Hi,

Version :
awesome v3.3-108-g290cd49 (Stellar)
 • Build: Jul  1 2009 04:40:53 for i686 by gcc version 4.4.0 (sitaktif <at> mickey)
 • D-Bus support: ✔

Description of the problem :
The awful.client.swap.bydirection() calls awful.hooks.mouse_enters hook.

Reproduce :
(note: my mouse focuses clients on "over", not on "click")
put this line in the awful.hooks.tags.register hook :
    naughty.notify({ title = 'hook called !', text = client.focus.id,
timeout = 3 }) ;
and notice it is called when you call e.g. awful.client.swap.bydirection("left")

Dirty temporary bugfix :
http://sitaktif.kollok.org/code/rc.lua (using a global var to
determine if the hook call comes from one of the
"awful.client.swap.bydirection" keybindings.

Remarks :
I think it is not relevant to call this hook, as we get a "random"
behaviour depending on the location of the mouse. However, it may be
the desired effect (but it is unlikely to be the case imho).

Cheers,

--
Sitaktif

--

-- 
To unsubscribe, send mail to awesome-devel-unsubscribe <at> naquadah.org.

Gregor Best | 2 Jul 02:39 2009
Picon

Re: [Draft] Introduction of Widget Layouts

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


Gmane