On 12/11/2008 09:50 PM, Maarten Maathuis wrote:
On 12/11/2008 10:39 AM, Julien Danjou wrote:
At 1228953600 time_t, Maarten Maathuis wrote:
The first 5 are fixes for various problems.

Subject: [PATCH] client: compensate for titlebars when maximizing.

Merged into:
     client: maximize belongs to client internal

Subject: [PATCH] titlebar: resize client when adding/removing so total size remains the same

Stacked into next.

Subject: [PATCH] client: can't assume resizes kill maximized state, because of titlebars.

Merged into:
     client: maximize belongs to client internal
because it's true. But I think we should rewrite it so it handles
titlebar, because currently it seems bad to me to let the flag and then
the window think it's maximized if it's not any more.

Subject: [PATCH] titlebar: fix geometry calculations

Stacked into next.

Subject: [PATCH] mouse: prevent resizes of maximized windows

Stacked into next.

The 6th is a bit larger and kills of the X11 concept of geometry
altogether, in favor of a definition that always include border and
titlebar. I left the widget stuff alone, but the client and swindow
stuff should be converted. Noone is ever interested in the size of a
window without it's border, so why even expose it, it creates only
confusion (especially the fact that x and y are including border and
width and height without).

I tested it, but it has some problem on restart, at least with my dual
screen.
I've ended up having a window belonging to the right screen which was
banned but shown in the left screen (the problem is then probably related
to ban).

However, I really like the idea. I'd rather
s/geometry_inside/geometries.internal/g maybe.

Here is an improved version, i hope it fixes your issue.

Discovered one extra issue, this is the corrected patch.

Kudos for doing such an ungrateful job, Maarten.

Cheers,


>From 1cdb48fdc04533392fb6af217368f6050274dd9a Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2...@gmail.com>
Date: Fri, 12 Dec 2008 00:01:43 +0100
Subject: [PATCH] client, swindow: switch to a more convient definition of 
geometry
   - In many places i see people correcting for border width and titlebars.
   - This new definition is the equivilant of what used to be fullgeometry.
   - The internal geometry is now contained to a few functions that few people 
ever touch.
   - This should avoid confusion and make code easier.
   - Also protect against several unsigned overflows.

Signed-off-by: Maarten Maathuis <madman2...@gmail.com>
---
 awesomerc.lua.in                       |    2 +-
 client.c                               |  129 +++++++++++++-------------------
 common/util.h                          |    8 ++
 lib/awful/layout/suit/fair.lua.in      |    5 +-
 lib/awful/layout/suit/magnifier.lua.in |   12 +--
 lib/awful/layout/suit/max.lua.in       |    6 +-
 lib/awful/layout/suit/tile.lua.in      |   30 ++++----
 lib/awful/menu.lua.in                  |   14 ++--
 lib/awful/mouse.lua.in                 |   35 ++-------
 lib/awful/placement.lua.in             |   11 +--
 lib/awful/titlebar.lua.in              |   12 ++--
 lib/naughty.lua.in                     |    6 +-
 structs.h                              |    2 +
 swindow.c                              |   62 ++++++++++-----
 swindow.h                              |    5 +
 titlebar.c                             |   34 ++++----
 titlebar.h                             |   28 ++++----
 wibox.c                                |   14 ++--
 18 files changed, 198 insertions(+), 217 deletions(-)

diff --git a/awesomerc.lua.in b/awesomerc.lua.in
index 70f834f..a4086a4 100644
--- a/awesomerc.lua.in
+++ b/awesomerc.lua.in
@@ -393,7 +393,7 @@ awful.hooks.arrange.register(function (screen)
     -- Uncomment if you want mouse warping
     --[[
     if client.focus then
-        local c_c = client.focus:fullgeometry()
+        local c_c = client.focus:geometry()
         local m_c = mouse.coords()
 
         if m_c.x < c_c.x or m_c.x >= c_c.x + c_c.width or
diff --git a/client.c b/client.c
index 029bac1..26d6636 100644
--- a/client.c
+++ b/client.c
@@ -174,8 +174,8 @@ client_ban(client_t *c)
     {
         /* Move all clients out of the physical viewport into negative 
coordinate space. */
         /* They will all be put on top of each other. */
-        uint32_t request[2] = { - (c->geometry.width + 2 * c->border),
-                                - (c->geometry.height + 2 * c->border) };
+        uint32_t request[2] = { - (c->geometries.internal.width + 2 * 
c->border),
+                                - (c->geometries.internal.height + 2 * 
c->border) };
 
         xcb_configure_window(globalconf.connection, c->win,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
@@ -475,8 +475,13 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t 
*wgeom, int phys_screen,
     c->win = w;
     c->geometry.x = wgeom->x;
     c->geometry.y = wgeom->y;
-    c->geometry.width = wgeom->width;
-    c->geometry.height = wgeom->height;
+    c->geometry.width = wgeom->width + 2 * wgeom->border_width;
+    c->geometry.height = wgeom->height + 2 * wgeom->border_width;
+    /* Also set internal geometry (client_ban() needs it). */
+    c->geometries.internal.x = wgeom->x;
+    c->geometries.internal.y = wgeom->y;
+    c->geometries.internal.width = wgeom->width;
+    c->geometries.internal.height = wgeom->height;
     client_setborder(c, wgeom->border_width);
     if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie)))
         c->icon = image_ref(&icon);
@@ -674,8 +679,11 @@ client_geometry_hints(client_t *c, area_t geometry)
     if(c->size_hints.flags & (XCB_SIZE_HINT_P_RESIZE_INC | 
XCB_SIZE_HINT_BASE_SIZE)
        && c->size_hints.width_inc && c->size_hints.height_inc)
     {
-        geometry.width -= (geometry.width - basew) % c->size_hints.width_inc;
-        geometry.height -= (geometry.height - baseh) % 
c->size_hints.height_inc;
+        uint16_t t1 = geometry.width, t2 = geometry.height;
+        unsigned_subtract(t1, basew);
+        unsigned_subtract(t2, baseh);
+        geometry.width -= t1 % c->size_hints.width_inc;
+        geometry.height -= t2 % c->size_hints.height_inc;
     }
 
     return geometry;
@@ -690,42 +698,52 @@ void
 client_resize(client_t *c, area_t geometry, bool hints)
 {
     int new_screen;
+    area_t geometry_internal;
     area_t area;
 
-    if(hints)
-        geometry = client_geometry_hints(c, geometry);
-
-    if(geometry.width <= 0 || geometry.height <= 0)
-        return;
-
     /* offscreen appearance fixes */
     area = display_area_get(c->phys_screen, NULL,
                             &globalconf.screens[c->screen].padding);
 
     if(geometry.x > area.width)
-        geometry.x = area.width - geometry.width - 2 * c->border;
+        geometry.x = area.width - geometry.width;
     if(geometry.y > area.height)
-        geometry.y = area.height - geometry.height - 2 * c->border;
-    if(geometry.x + geometry.width + 2 * c->border < 0)
+        geometry.y = area.height - geometry.height;
+    if(geometry.x + geometry.width < 0)
         geometry.x = 0;
-    if(geometry.y + geometry.height + 2 * c->border < 0)
+    if(geometry.y + geometry.height < 0)
         geometry.y = 0;
 
-    if(c->geometry.x != geometry.x
-       || c->geometry.y != geometry.y
-       || c->geometry.width != geometry.width
-       || c->geometry.height != geometry.height)
+    /* Real client geometry, please keep it contained to C code at the very 
least. */
+    geometry_internal = titlebar_geometry_remove(c->titlebar, c->border, 
geometry);
+
+    if(hints)
+        geometry_internal = client_geometry_hints(c, geometry_internal);
+
+    if(geometry_internal.width == 0 || geometry_internal.height == 0)
+        return;
+
+    /* Also let client hints propegate to the "official" geometry. */
+    geometry = titlebar_geometry_add(c->titlebar, c->border, 
geometry_internal);
+
+    if(c->geometries.internal.x != geometry_internal.x
+       || c->geometries.internal.y != geometry_internal.y
+       || c->geometries.internal.width != geometry_internal.width
+       || c->geometries.internal.height != geometry_internal.height)
     {
-        new_screen = screen_getbycoord(c->screen, geometry.x, geometry.y);
+        new_screen = screen_getbycoord(c->screen, geometry_internal.x, 
geometry_internal.y);
 
         /* Values to configure a window is an array where values are
          * stored according to 'value_mask' */
         uint32_t values[4];
 
-        c->geometry.x = values[0] = geometry.x;
-        c->geometry.y = values[1] = geometry.y;
-        c->geometry.width = values[2] = geometry.width;
-        c->geometry.height = values[3] = geometry.height;
+        c->geometries.internal.x = values[0] = geometry_internal.x;
+        c->geometries.internal.y = values[1] = geometry_internal.y;
+        c->geometries.internal.width = values[2] = geometry_internal.width;
+        c->geometries.internal.height = values[3] = geometry_internal.height;
+
+        /* Also store geometry including border and titlebar. */
+        c->geometry = geometry;
 
         titlebar_update_geometry(c);
 
@@ -734,15 +752,15 @@ client_resize(client_t *c, area_t geometry, bool hints)
         /* This at least doesn't break expectations about events. */
         if (c->isbanned)
         {
-            geometry.x = values[0] = - (geometry.width + 2 * c->border);
-            geometry.y = values[1] = - (geometry.height + 2 * c->border);
+            geometry.x = values[0] = - (geometry_internal.width + 2 * 
c->border);
+            geometry.y = values[1] = - (geometry_internal.height + 2 * 
c->border);
         }
 
         xcb_configure_window(globalconf.connection, c->win,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
                              | XCB_CONFIG_WINDOW_WIDTH | 
XCB_CONFIG_WINDOW_HEIGHT,
                              values);
-        window_configure(c->win, geometry, c->border);
+        window_configure(c->win, geometry_internal, c->border);
 
         screen_client_moveto(c, new_screen, true, false);
 
@@ -846,10 +864,6 @@ client_setmaxhoriz(client_t *c, bool s)
                                        &globalconf.screens[c->screen].wiboxes,
                                        &globalconf.screens[c->screen].padding,
                                        true);
-            /* Remove space needed for titlebar and border. */
-            geometry = titlebar_geometry_remove(c->titlebar,
-                                        c->border,
-                                        geometry);
             geometry.y = c->geometry.y;
             geometry.height = c->geometry.height;
             c->geometries.max.x = c->geometry.x;
@@ -890,10 +904,6 @@ client_setmaxvert(client_t *c, bool s)
                                        &globalconf.screens[c->screen].wiboxes,
                                        &globalconf.screens[c->screen].padding,
                                        true);
-            /* Remove space needed for titlebar and border. */
-            geometry = titlebar_geometry_remove(c->titlebar,
-                                        c->border,
-                                        geometry);
             geometry.x = c->geometry.x;
             geometry.width = c->geometry.width;
             c->geometries.max.y = c->geometry.y;
@@ -1006,12 +1016,12 @@ client_unban(client_t *c)
     if(c->isbanned)
     {
         /* Move the client back where it belongs. */
-        uint32_t request[2] = { c->geometry.x, c->geometry.y };
+        uint32_t request[2] = { c->geometries.internal.x, 
c->geometries.internal.y };
 
         xcb_configure_window(globalconf.connection, c->win,
                               XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                               request);
-        window_configure(c->win, c->geometry, c->border);
+        window_configure(c->win, c->geometries.internal, c->border);
 
         /* Do this manually because the system doesn't know we moved the 
toolbar.
          * Note that !isvisible titlebars are unmapped and for fullscreen it'll
@@ -1347,11 +1357,13 @@ luaA_client_unmanage(lua_State *L)
 
 /** Return client geometry.
  * \param L The Lua VM state.
- * \param full Use titlebar also.
  * \return The number of elements pushed on stack.
+ * \luastack
+ * \lparam A table with new coordinates, or none.
+ * \lreturn A table with client coordinates.
  */
 static int
-luaA_client_handlegeom(lua_State *L, bool full)
+luaA_client_geometry(lua_State *L)
 {
     client_t **c = luaA_checkudata(L, 1, "client");
 
@@ -1373,48 +1385,12 @@ luaA_client_handlegeom(lua_State *L, bool full)
             geometry.height = luaA_getopt_number(L, 2, "height", 
(*c)->geometry.height);
         }
 
-        if(full)
-            geometry = titlebar_geometry_remove((*c)->titlebar,
-                                                (*c)->border,
-                                                geometry);
-
         client_resize(*c, geometry, (*c)->size_hints_honor);
     }
 
-    if(full)
-        return luaA_pusharea(L, titlebar_geometry_add((*c)->titlebar,
-                                                      (*c)->border,
-                                                      (*c)->geometry));
-
     return luaA_pusharea(L, (*c)->geometry);
 }
 
-/** Return client geometry.
- * \param L The Lua VM state.
- * \return The number of elements pushed on stack.
- * \luastack
- * \lparam A table with new coordinates, or none.
- * \lreturn A table with client coordinates.
- */
-static int
-luaA_client_geometry(lua_State *L)
-{
-    return luaA_client_handlegeom(L, false);
-}
-
-/** Return client geometry, using also titlebar and border width.
- * \param L The Lua VM state.
- * \return The number of elements pushed on stack.
- * \luastack
- * \lparam A table with new coordinates, or none.
- * \lreturn A table with client coordinates.
- */
-static int
-luaA_client_fullgeometry(lua_State *L)
-{
-    return luaA_client_handlegeom(L, true);
-}
-
 /** Client newindex.
  * \param L The Lua VM state.
  * \return The number of elements pushed on stack.
@@ -1955,7 +1931,6 @@ const struct luaL_reg awesome_client_meta[] =
 {
     { "isvisible", luaA_client_isvisible },
     { "geometry", luaA_client_geometry },
-    { "fullgeometry", luaA_client_fullgeometry },
     { "buttons", luaA_client_buttons },
     { "tags", luaA_client_tags },
     { "kill", luaA_client_kill },
diff --git a/common/util.h b/common/util.h
index 483c096..61042bd 100644
--- a/common/util.h
+++ b/common/util.h
@@ -72,6 +72,14 @@ typedef struct
 #define MAX(a,b) ((a) < (b) ? (b) : (a))
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 
+#define unsigned_subtract(a, b)  \
+    do {                                            \
+        if (b > a)                                  \
+            a = 0;                                  \
+        else                                         \
+            a -= b;                                 \
+    } while (0)
+
 #define ssizeof(foo)            (ssize_t)sizeof(foo)
 #define countof(foo)            (ssizeof(foo) / ssizeof(foo[0]))
 
diff --git a/lib/awful/layout/suit/fair.lua.in 
b/lib/awful/layout/suit/fair.lua.in
index 6b879fb..9b078e6 100644
--- a/lib/awful/layout/suit/fair.lua.in
+++ b/lib/awful/layout/suit/fair.lua.in
@@ -52,10 +52,7 @@ local function fair(screen, orientation)
                 g.y = wa.y + cell * g.height
             end
 
-            g.width = g.width - 2 * c.border_width
-            g.height = g.height - 2 * c.border_width
-
-            c:fullgeometry(g)
+            c:geometry(g)
 
             cell = cell + 1
             if cell == cells then
diff --git a/lib/awful/layout/suit/magnifier.lua.in 
b/lib/awful/layout/suit/magnifier.lua.in
index 72f2763..062ac8f 100644
--- a/lib/awful/layout/suit/magnifier.lua.in
+++ b/lib/awful/layout/suit/magnifier.lua.in
@@ -55,10 +55,10 @@ local function magnifier(_, screen)
     else
         geometry.x = area.x
         geometry.y = area.y
-        geometry.width = area.width - 2 * focus.border_width
-        geometry.height = area.height - 2 * focus.border_width
+        geometry.width = area.width
+        geometry.height = area.height
     end
-    focus:fullgeometry(geometry)
+    focus:geometry(geometry)
     focus:raise()
 
     if #cls - 1 > 0 then
@@ -69,11 +69,7 @@ local function magnifier(_, screen)
 
         for k, c in ipairs(cls) do
             if c ~= focus then
-                geometry.height = geometry.height - 2 * c.border_width
-                geometry.width = geometry.width - 2 * c.border_width
-                c:fullgeometry(geometry)
-                geometry.height = geometry.height + 2 * c.border_width
-                geometry.width = geometry.width + 2 * c.border_width
+                c:geometry(geometry)
                 geometry.y = geometry.y + geometry.height
             end
         end
diff --git a/lib/awful/layout/suit/max.lua.in b/lib/awful/layout/suit/max.lua.in
index cc95cf5..f3455c7 100644
--- a/lib/awful/layout/suit/max.lua.in
+++ b/lib/awful/layout/suit/max.lua.in
@@ -27,11 +27,7 @@ local function fmax(screen, fs)
 
     for k, c in pairs(client.visible(screen)) do
         if not client.floating.get(c) then
-            area.width = area.width - 2 * c.border_width
-            area.height = area.height - 2 * c.border_width
-            c:fullgeometry(area)
-            area.width = area.width + 2 * c.border_width
-            area.height = area.height + 2 * c.border_width
+            c:geometry(area)
         end
     end
 end
diff --git a/lib/awful/layout/suit/tile.lua.in 
b/lib/awful/layout/suit/tile.lua.in
index e703f10..701f73b 100644
--- a/lib/awful/layout/suit/tile.lua.in
+++ b/lib/awful/layout/suit/tile.lua.in
@@ -87,8 +87,8 @@ local function tile(_, screen, position)
                 geometry.y = wa.y
             end
 
-            geometry.width = mw - 2 * c.border_width
-            geometry.height = mh - 2 * c.border_width
+            geometry.width = mw
+            geometry.height = mh
 
         -- Slave windows
         else
@@ -98,52 +98,52 @@ local function tile(_, screen, position)
 
             if position == "right" or position == "left" then
                 if otherwin <= real_ncol then
-                    geometry.height = wa.height - 2 * c.border_width
+                    geometry.height = wa.height
                 elseif (otherwin % win_by_col) ~= 0 and (current_col == 
real_ncol - 1) then
-                    geometry.height = math.floor(wa.height / (otherwin % 
win_by_col)) - 2 * c.border_width
+                    geometry.height = math.floor(wa.height / (otherwin % 
win_by_col))
                 else
-                    geometry.height = math.floor(wa.height / win_by_col) - 2 * 
c.border_width
+                    geometry.height = math.floor(wa.height / win_by_col)
                 end
 
-                geometry.width = math.floor((wa.width - mw) / real_ncol) - 2 * 
c.border_width
+                geometry.width = math.floor((wa.width - mw) / real_ncol)
 
                 if otherwin <= real_ncol then
                     geometry.y = wa.y
                 else
                     geometry.y = wa.y + ((i - 1 - nmaster) % win_by_col) *
-                                        (geometry.height + 2 * c.border_width)
+                                        geometry.height
                 end
-                geometry.x = wa.x + current_col * (geometry.width + 2 * 
c.border_width)
+                geometry.x = wa.x + current_col * geometry.width
 
                 if position == "right" then
                     geometry.x = geometry.x + mw
                 end
             else
                 if otherwin <= real_ncol then
-                    geometry.width = wa.width - 2 * c.border_width
+                    geometry.width = wa.width
                 elseif (otherwin % win_by_col) ~= 0 and (current_col == 
real_ncol - 1) then
-                    geometry.width = math.floor(wa.width / (otherwin % 
win_by_col)) - 2 * c.border_width
+                    geometry.width = math.floor(wa.width / (otherwin % 
win_by_col))
                 else
-                    geometry.width = math.floor(wa.width / win_by_col) - 2 * 
c.border_width
+                    geometry.width = math.floor(wa.width / win_by_col) 
                 end
 
-                geometry.height = math.floor((wa.height - mh) /  real_ncol) - 
2 * c.border_width
+                geometry.height = math.floor((wa.height - mh) /  real_ncol)
 
                 if otherwin <= real_ncol then
                     geometry.x = wa.x
                 else
                     geometry.x = wa.x + ((i - 1 - nmaster) % win_by_col) *
-                                        (geometry.width + 2 * c.border_width)
+                                        geometry.width
                 end
 
-                geometry.y = wa.y + current_col * (geometry.height + 2 * 
c.border_width)
+                geometry.y = wa.y + current_col * geometry.height
 
                 if position == "bottom" then
                     geometry.y = geometry.y + mh
                 end
             end
         end
-        c:fullgeometry(geometry)
+        c:geometry(geometry)
     end
 end
 
diff --git a/lib/awful/menu.lua.in b/lib/awful/menu.lua.in
index 0949dc5..6a19df1 100644
--- a/lib/awful/menu.lua.in
+++ b/lib/awful/menu.lua.in
@@ -199,19 +199,19 @@ local function set_coords(menu, screen_idx)
         menu.w = menu.parent.w
         menu.h = menu.parent.h
 
-        local p_w = (menu.h + menu.theme.border_width) * (menu.num - 1)
-        local m_h = menu.theme.border_width + (menu.h + 
menu.theme.border_width) * #menu.items
-        local m_w = menu.w + menu.theme.border_width
+        local p_w = menu.h * (menu.num - 1)
+        local m_h = menu.h * #menu.items
+        local m_w = menu.w
         menu.y = menu.parent.y + p_w + m_h > screen_h and screen_h - m_h or 
menu.parent.y + p_w
-        menu.x = menu.parent.x + menu.w*2 + menu.theme.border_width > screen_w 
and menu.parent.x - m_w or menu.parent.x + m_w
+        menu.x = menu.parent.x + menu.w > screen_w and menu.parent.x - m_w or 
menu.parent.x + m_w
     else
         local m_coords = capi.mouse.coords()
 
         menu.y = m_coords.y < s_geometry.y and s_geometry.y or m_coords.y
         menu.x = m_coords.x < s_geometry.x and s_geometry.x or m_coords.x
 
-        local m_h = menu.theme.border_width + (menu.h + 
menu.theme.border_width) * #menu.items
-        local m_w = menu.w + menu.theme.border_width*2
+        local m_h = menu.h * #menu.items
+        local m_w = menu.w
         menu.y = menu.y + m_h > screen_h and screen_h - m_h or menu.y
         menu.x = menu.x + m_w > screen_w and screen_w - m_w or menu.x
     end
@@ -227,7 +227,7 @@ function show(menu)
             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
         })
         item.screen = screen_index
     end
diff --git a/lib/awful/mouse.lua.in b/lib/awful/mouse.lua.in
index 79bb004..81a02a2 100644
--- a/lib/awful/mouse.lua.in
+++ b/lib/awful/mouse.lua.in
@@ -86,8 +86,8 @@ end
 function client.snap(c, snap, x, y, fixed_x, fixed_y)
     local snap = snap or 8
     local c = c or client.focus
-    local cur_geom = c:fullgeometry()
-    local geom = c:fullgeometry()
+    local cur_geom = c:geometry()
+    local geom = c:geometry()
     geom.x = x or geom.x
     geom.y = y or geom.y
 
@@ -96,7 +96,7 @@ function client.snap(c, snap, x, y, fixed_x, fixed_y)
 
     for k, snapper in ipairs(aclient.visible(c.screen)) do
         if snapper ~= c then
-            geom = snap_outside(geom, snapper:fullgeometry(), snap)
+            geom = snap_outside(geom, snapper:geometry(), snap)
         end
     end
 
@@ -124,7 +124,7 @@ function client.move(c, snap)
 
     c:raise()
 
-    local orig = c:fullgeometry()
+    local orig = c:geometry()
     local m_c = capi.mouse.coords()
     local dist_x = m_c.x - orig.x
     local dist_y = m_c.y - orig.y
@@ -134,7 +134,7 @@ function client.move(c, snap)
 
     local function ug(c, prop)
         if prop == "geometry" then
-            local g = c:fullgeometry()
+            local g = c:geometry()
             capi.mouse.coords({ x = g.x + dist_x, y = g.y + dist_y })
         end
     end
@@ -147,7 +147,7 @@ function client.move(c, snap)
                                       if lay == layout.suit.floating or 
aclient.floating.get(c) then
                                           local x = mouse.x - dist_x
                                           local y = mouse.y - dist_y
-                                          c:fullgeometry(client.snap(c, snap, 
x, y, fixed_x, fixed_y))
+                                          c:geometry(client.snap(c, snap, x, 
y, fixed_x, fixed_y))
                                           if layout.get(c.screen) ~= 
layout.suit.floating and not aclient.floating.get(c) then
                                               hooks.property.register(ug)
                                           end
@@ -389,26 +389,9 @@ local function client_resize_floating(c, corner, fixed_x, 
fixed_y)
                                       end
                                       if ng.width <= 0 then ng.width = nil end
                                       if ng.height <= 0 then ng.height = nil 
end
-                                      if fixed_x then ng.width = width end
-                                      if fixed_y then ng.height = height end
-                                      c:geometry({ width = ng.width, height = 
ng.height })
-                                      -- Get real geometry that has been 
applied
-                                      -- in case we honor size hints
-                                      -- XXX: This should be rewritten when 
size
-                                      -- hints are available from Lua.
-                                      local rg = c:geometry()
-
-                                      if corner == "bottom_right" then
-                                          ng = {}
-                                      elseif corner == "bottom_left" then
-                                          ng = { x = (g.x + g.width) - 
rg.width  }
-                                      elseif corner == "top_left" then
-                                          ng = { x = (g.x + g.width) - 
rg.width,
-                                                 y = (g.y + g.height) - 
rg.height }
-                                      else
-                                          ng = { y = (g.y + g.height) - 
rg.height }
-                                      end
-                                      c:geometry({ x = ng.x, y = ng.y })
+                                      if fixed_x then ng.width = g.width ng.x 
= g.x end
+                                      if fixed_y then ng.height = g.height 
ng.y = g.y end
+                                      c:geometry(ng)
                                       return true
                                   end
                               end
diff --git a/lib/awful/placement.lua.in b/lib/awful/placement.lua.in
index f75fed5..56217f5 100644
--- a/lib/awful/placement.lua.in
+++ b/lib/awful/placement.lua.in
@@ -101,7 +101,7 @@ end
 --- Place the client without it being outside the screen.
 -- @param c The client.
 function no_offscreen(c)
-    local geometry = c:fullgeometry()
+    local geometry = c:geometry()
     local screen_geometry = capi.screen[c.screen].workarea
 
     if geometry.x + geometry.width > screen_geometry.x + screen_geometry.width 
then
@@ -116,7 +116,7 @@ function no_offscreen(c)
         geometry.y = screen_geometry.y
     end
 
-    c:fullgeometry(geometry)
+    c:geometry(geometry)
 end
 
 --- Place the client where there's place available with minimum overlap.
@@ -126,10 +126,9 @@ function no_overlap(c)
     local layout = layout.get()
     local areas = { capi.screen[c.screen].workarea }
     local geometry = c:geometry()
-    local fullgeometry = c:fullgeometry()
     for i, cl in pairs(cls) do
         if cl ~= c and (client.get.floating(cl) or layout == 
layout.suit.floating) then
-            areas = area_remove(areas, cl:fullgeometry())
+            areas = area_remove(areas, cl:geometry())
         end
     end
 
@@ -137,8 +136,8 @@ function no_overlap(c)
     local found = false
     local new = { x = geometry.x, y = geometry.y, width = 0, height = 0 }
     for i, r in ipairs(areas) do
-        if r.width >= fullgeometry.width
-           and r.height >= fullgeometry.height
+        if r.width >= geometry.width
+           and r.height >= geometry.height
            and r.width * r.height > new.width * new.height then
             found = true
             new = r
diff --git a/lib/awful/titlebar.lua.in b/lib/awful/titlebar.lua.in
index 93b8927..b2de82d 100644
--- a/lib/awful/titlebar.lua.in
+++ b/lib/awful/titlebar.lua.in
@@ -113,12 +113,12 @@ function add(c, args)
                    closef = closef, close = close }
 
     -- Store old geometry (including borders)
-    local old_geom = c:fullgeometry()
+    local old_geom = c:geometry()
 
     c.titlebar = tb
 
     -- Resize the client so the same amount of space is occupied as before.
-    c:fullgeometry(old_geom)
+    c:geometry(old_geom)
 
     update(c)
     update(c, "geometry")
@@ -142,10 +142,10 @@ function update(c, prop)
             if data[c].width then
                 if c.titlebar.position == "top"
                     or c.titlebar.position == "bottom" then
-                    local w = math.min(data[c].width, c:geometry().width + 2 * 
c.border_width)
+                    local w = math.min(data[c].width, c:geometry().width)
                     c.titlebar:geometry({ width = w })
                 else
-                    local w = math.min(data[c].width, c:geometry().height + 2 
* c.border_width)
+                    local w = math.min(data[c].width, c:geometry().height)
                     c.titlebar:geometry({ height = w })
                 end
             end
@@ -167,11 +167,11 @@ end
 --- Remove a titlebar from a client.
 -- @param c The client.
 function remove(c)
-    local old_geom = c:fullgeometry()
+    local old_geom = c:geometry()
     c.titlebar = nil
     data[c] = nil
     -- Resize the client so the same amount of space is occupied as before.
-    c:fullgeometry(old_geom)
+    c:geometry(old_geom)
 end
 
 -- Register standards hooks
diff --git a/lib/naughty.lua.in b/lib/naughty.lua.in
index 49f7275..2b9c056 100644
--- a/lib/naughty.lua.in
+++ b/lib/naughty.lua.in
@@ -145,20 +145,20 @@ local function get_offset(screen, position, idx, width, 
height)
     if position:match("left") then
         v.x = ws.x + config.padding
     else
-        v.x = ws.x + ws.width - (width + config.border_width*2 + 
config.padding)
+        v.x = ws.x + ws.width - (width + config.padding)
     end
 
     -- calculate existing popups' height
     local existing = 0
     for i = 1, idx-1, 1 do
-        existing = existing + notifications[screen][position][i].height + 
config.spacing + config.border_width*2
+        existing = existing + notifications[screen][position][i].height + 
config.spacing
     end
 
     -- calculate y
     if position:match("top") then
         v.y = ws.y + config.padding + existing
     else
-        v.y = ws.y + ws.height - (config.padding + config.border_width*2 + 
height + existing)
+        v.y = ws.y + ws.height - (config.padding + height + existing)
     end
 
     -- if positioned outside workarea, destroy oldest popup and recalculate
diff --git a/structs.h b/structs.h
index 13ef6dd..d64e8db 100644
--- a/structs.h
+++ b/structs.h
@@ -162,6 +162,8 @@ struct client_t
         area_t fullscreen;
         /** Client geometry when (un)-max */
         area_t max;
+        /** Internal geometry (matching X11 protocol) */
+        area_t internal;
     } geometries;
     /** Strut */
     strut_t strut;
diff --git a/swindow.c b/swindow.c
index 3352259..00a8718 100644
--- a/swindow.c
+++ b/swindow.c
@@ -48,14 +48,14 @@ simplewindow_draw_context_update(simple_window_t *sw, 
xcb_screen_t *s)
         xcb_create_pixmap(globalconf.connection,
                           s->root_depth,
                           sw->ctx.pixmap, s->root,
-                          sw->geometry.height, sw->geometry.width);
+                          sw->geometry.height, sw->geometries.internal.width);
         draw_context_init(&sw->ctx, phys_screen,
-                          sw->geometry.height, sw->geometry.width,
+                          sw->geometry.height, sw->geometries.internal.width,
                           sw->ctx.pixmap, &fg, &bg);
         break;
       case East:
         draw_context_init(&sw->ctx, phys_screen,
-                          sw->geometry.width, sw->geometry.height,
+                          sw->geometries.internal.width, 
sw->geometries.internal.height,
                           sw->pixmap, &fg, &bg);
         break;
     }
@@ -88,6 +88,13 @@ simplewindow_init(simple_window_t *sw,
     sw->geometry.width = geometry.width;
     sw->geometry.height = geometry.height;
     sw->border.width = border_width;
+
+    /* The real protocol window. */
+    sw->geometries.internal.x = geometry.x;
+    sw->geometries.internal.y = geometry.y;
+    sw->geometries.internal.width = geometry.width - 2*border_width;
+    sw->geometries.internal.height = geometry.height - 2*border_width;
+
     sw->orientation = orientation;
     sw->ctx.fg = *fg;
     sw->ctx.bg = *bg;
@@ -102,14 +109,14 @@ simplewindow_init(simple_window_t *sw,
 
     sw->window = xcb_generate_id(globalconf.connection);
     xcb_create_window(globalconf.connection, s->root_depth, sw->window, 
s->root,
-                      geometry.x, geometry.y, geometry.width, geometry.height,
+                      sw->geometries.internal.x, sw->geometries.internal.y, 
sw->geometries.internal.width, sw->geometries.internal.height,
                       border_width, XCB_COPY_FROM_PARENT, s->root_visual,
                       XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | 
XCB_CW_EVENT_MASK,
                       create_win_val);
 
     sw->pixmap = xcb_generate_id(globalconf.connection);
     xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, 
s->root,
-                      geometry.width, geometry.height);
+                      sw->geometries.internal.width, 
sw->geometries.internal.height);
 
     sw->ctx.phys_screen = phys_screen;
     simplewindow_draw_context_update(sw, s);
@@ -153,10 +160,10 @@ simplewindow_move(simple_window_t *sw, int x, int y)
 {
     const uint32_t move_win_vals[] = { x, y };
 
-    if(x != sw->geometry.x || y != sw->geometry.y)
+    if(x != sw->geometries.internal.x || y != sw->geometries.internal.y)
     {
-        sw->geometry.x = x;
-        sw->geometry.y = y;
+        sw->geometry.x = sw->geometries.internal.x = x;
+        sw->geometry.y = sw->geometries.internal.y = y;
         xcb_configure_window(globalconf.connection, sw->window,
                              XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
                              move_win_vals);
@@ -171,19 +178,25 @@ simplewindow_move(simple_window_t *sw, int x, int y)
 void
 simplewindow_resize(simple_window_t *sw, int w, int h)
 {
-    if(w > 0 && h > 0 && (sw->geometry.width != w || sw->geometry.height != h))
+    int iw = w - 2 * sw->border.width;
+    int ih = h - 2 * sw->border.width;
+
+    if(iw > 0 && ih > 0 && 
+        (sw->geometries.internal.width != iw || sw->geometries.internal.height 
!= ih))
     {
         xcb_screen_t *s = xutil_screen_get(globalconf.connection, 
sw->ctx.phys_screen);
         uint32_t resize_win_vals[2];
 
-        sw->geometry.width = resize_win_vals[0] = w;
-        sw->geometry.height = resize_win_vals[1] = h;
+        sw->geometries.internal.width = resize_win_vals[0] = iw;
+        sw->geometries.internal.height = resize_win_vals[1] = ih;
+        sw->geometry.width = w;
+        sw->geometry.height = h;
         xcb_free_pixmap(globalconf.connection, sw->pixmap);
         /* orientation != East */
         if(sw->pixmap != sw->ctx.pixmap)
             xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
         sw->pixmap = xcb_generate_id(globalconf.connection);
-        xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, 
s->root, w, h);
+        xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, 
s->root, iw, ih);
         xcb_configure_window(globalconf.connection, sw->window,
                              XCB_CONFIG_WINDOW_WIDTH | 
XCB_CONFIG_WINDOW_HEIGHT,
                              resize_win_vals);
@@ -193,7 +206,7 @@ simplewindow_resize(simple_window_t *sw, int w, int h)
 
 /** Move and resize a window in one call.
  * \param sw The simple window to move and resize.
- * \param geom The new gometry.
+ * \param geom The new geometry.
  */
 void
 simplewindow_moveresize(simple_window_t *sw, area_t geom)
@@ -201,10 +214,14 @@ simplewindow_moveresize(simple_window_t *sw, area_t geom)
     uint32_t moveresize_win_vals[4], mask_vals = 0;
     xcb_screen_t *s = xutil_screen_get(globalconf.connection, 
sw->ctx.phys_screen);
 
-    if(sw->geometry.x != geom.x || sw->geometry.y != geom.y)
+    area_t geom_internal = geom;
+    geom_internal.width -= 2 * sw->border.width;
+    geom_internal.height -= 2* sw->border.width;
+
+    if(sw->geometries.internal.x != geom_internal.x || 
sw->geometries.internal.y != geom_internal.y)
     {
-        sw->geometry.x = moveresize_win_vals[0] = geom.x;
-        sw->geometry.y = moveresize_win_vals[1] = geom.y;
+        sw->geometries.internal.x = moveresize_win_vals[0] = geom_internal.x;
+        sw->geometries.internal.y = moveresize_win_vals[1] = geom_internal.y;
         mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
     }
 
@@ -212,13 +229,13 @@ simplewindow_moveresize(simple_window_t *sw, area_t geom)
     {
         if(mask_vals)
         {
-            sw->geometry.width = moveresize_win_vals[2] = geom.width;
-            sw->geometry.height = moveresize_win_vals[3] = geom.height;
+            sw->geometries.internal.width = moveresize_win_vals[2] = 
geom_internal.width;
+            sw->geometries.internal.height = moveresize_win_vals[3] = 
geom_internal.height;
         }
         else
         {
-            sw->geometry.width = moveresize_win_vals[0] = geom.width;
-            sw->geometry.height = moveresize_win_vals[1] = geom.height;
+            sw->geometries.internal.width = moveresize_win_vals[0] = 
geom_internal.width;
+            sw->geometries.internal.height = moveresize_win_vals[1] = 
geom_internal.height;
         }
         mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
         xcb_free_pixmap(globalconf.connection, sw->pixmap);
@@ -226,10 +243,13 @@ simplewindow_moveresize(simple_window_t *sw, area_t geom)
         if(sw->pixmap != sw->ctx.pixmap)
             xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
         sw->pixmap = xcb_generate_id(globalconf.connection);
-        xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, 
s->root, geom.width, geom.height);
+        xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, 
s->root, geom_internal.width, geom_internal.height);
         simplewindow_draw_context_update(sw, s);
     }
 
+    /* Also save geometry including border. */
+    sw->geometry = geom;
+
     xcb_configure_window(globalconf.connection, sw->window, mask_vals, 
moveresize_win_vals);
 }
 
diff --git a/swindow.h b/swindow.h
index 49f142d..9176200 100644
--- a/swindow.h
+++ b/swindow.h
@@ -36,6 +36,11 @@ typedef struct simple_window_t
     xcb_gcontext_t gc;
     /** The window geometry. */
     area_t geometry;
+    struct
+    {
+        /** Internal geometry (matching X11 protocol) */
+        area_t internal;
+    } geometries;
     /** The window border */
     struct
     {
diff --git a/titlebar.c b/titlebar.c
index 510b65e..45b3414 100644
--- a/titlebar.c
+++ b/titlebar.c
@@ -64,83 +64,83 @@ client_getbytitlebarwin(xcb_window_t win)
 void
 titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
 {
-    int width, x_offset = 0, y_offset = 0;
+    int height, width, x_offset = 0, y_offset = 0;
 
     switch(c->titlebar->position)
     {
       default:
         return;
       case Top:
-        width = MAX(1, geometry.width + 2 * c->border - 2 * 
c->titlebar->sw.border.width);
+        width = MAX(1, geometry.width);
         switch(c->titlebar->align)
         {
           default:
             break;
           case AlignRight:
-            x_offset = 2 * c->border + geometry.width - width - 2 * 
c->titlebar->sw.border.width;
+            x_offset = geometry.width - width;
             break;
           case AlignCenter:
             x_offset = (geometry.width - width) / 2;
             break;
         }
         res->x = geometry.x + x_offset;
-        res->y = geometry.y - c->titlebar->sw.geometry.height - 2 * 
c->titlebar->sw.border.width + c->border;
+        res->y = geometry.y;
         res->width = width;
         res->height = c->titlebar->sw.geometry.height;
         break;
       case Bottom:
-        width = MAX(1, geometry.width + 2 * c->border - 2 * 
c->titlebar->sw.border.width);
+        width = MAX(1, geometry.width);
         switch(c->titlebar->align)
         {
           default:
             break;
           case AlignRight:
-            x_offset = 2 * c->border + geometry.width - width - 2 * 
c->titlebar->sw.border.width;
+            x_offset = geometry.width - width;
             break;
           case AlignCenter:
             x_offset = (geometry.width - width) / 2;
             break;
         }
         res->x = geometry.x + x_offset;
-        res->y = geometry.y + geometry.height + c->border;
+        res->y = geometry.y + geometry.height - 
c->titlebar->sw.geometry.height;
         res->width = width;
         res->height = c->titlebar->sw.geometry.height;
         break;
       case Left:
-        width = MAX(1, geometry.height + 2 * c->border - 2 * 
c->titlebar->sw.border.width);
+        height = MAX(1, geometry.height);
         switch(c->titlebar->align)
         {
           default:
             break;
           case AlignRight:
-            y_offset = 2 * c->border + geometry.height - width - 2 * 
c->titlebar->sw.border.width;
+            y_offset = geometry.height - height;
             break;
           case AlignCenter:
-            y_offset = (geometry.height - width) / 2;
+            y_offset = (geometry.height - height) / 2;
             break;
         }
-        res->x = geometry.x - c->titlebar->sw.geometry.width + c->border;
+        res->x = geometry.x;
         res->y = geometry.y + y_offset;
         res->width = c->titlebar->sw.geometry.width;
-        res->height = width;
+        res->height = height;
         break;
       case Right:
-        width = MAX(1, geometry.height + 2 * c->border - 2 * 
c->titlebar->sw.border.width);
+        height = MAX(1, geometry.height);
         switch(c->titlebar->align)
         {
           default:
             break;
           case AlignRight:
-            y_offset = 2 * c->border + geometry.height - width - 2 * 
c->titlebar->sw.border.width;
+            y_offset = geometry.height - height;
             break;
           case AlignCenter:
-            y_offset = (geometry.height - width) / 2;
+            y_offset = (geometry.height - height) / 2;
             break;
         }
-        res->x = geometry.x + geometry.width + c->border;
+        res->x = geometry.x + geometry.width - c->titlebar->sw.geometry.width;
         res->y = geometry.y + y_offset;
         res->width = c->titlebar->sw.geometry.width;
-        res->height = width;
+        res->height = height;
         break;
     }
 }
diff --git a/titlebar.h b/titlebar.h
index 0adbf3d..dd8e9b9 100644
--- a/titlebar.h
+++ b/titlebar.h
@@ -51,18 +51,18 @@ titlebar_geometry_add(wibox_t *t, int border, area_t 
geometry)
         switch(t->position)
         {
           case Top:
-            geometry.y -= t->sw.geometry.height + 2 * t->sw.border.width;
-            geometry.height += t->sw.geometry.height + 2 * t->sw.border.width;
+            geometry.y -= t->sw.geometry.height;
+            geometry.height += t->sw.geometry.height;
             break;
           case Bottom:
-            geometry.height += t->sw.geometry.height + 2 * t->sw.border.width;
+            geometry.height += t->sw.geometry.height;
             break;
           case Left:
-            geometry.x -= t->sw.geometry.width + 2 * t->sw.border.width;
-            geometry.width += t->sw.geometry.width + 2 * t->sw.border.width;
+            geometry.x -= t->sw.geometry.width;
+            geometry.width += t->sw.geometry.width;
             break;
           case Right:
-            geometry.width += t->sw.geometry.width + 2 * t->sw.border.width;
+            geometry.width += t->sw.geometry.width;
             break;
           default:
             break;
@@ -92,26 +92,26 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t 
geometry)
         switch(t->position)
         {
           case Top:
-            geometry.y += t->sw.geometry.height + 2 * t->sw.border.width;
-            geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width;
+            geometry.y += t->sw.geometry.height;
+            unsigned_subtract(geometry.height, t->sw.geometry.height);
             break;
           case Bottom:
-            geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width;
+            unsigned_subtract(geometry.height, t->sw.geometry.height);
             break;
           case Left:
-            geometry.x += t->sw.geometry.width + 2 * t->sw.border.width;
-            geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width;
+            geometry.x += t->sw.geometry.width;
+            unsigned_subtract(geometry.width, t->sw.geometry.width);
             break;
           case Right:
-            geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width;
+            unsigned_subtract(geometry.width, t->sw.geometry.width);
             break;
           default:
             break;
         }
 
     /* Adding a border to a client only changes width and height, x and y are 
including border. */
-    geometry.width -= 2 * border;
-    geometry.height -= 2 * border;
+    unsigned_subtract(geometry.width, 2*border);
+    unsigned_subtract(geometry.height, 2*border);
 
     return geometry;
 }
diff --git a/wibox.c b/wibox.c
index 9a460de..9c0f8b5 100644
--- a/wibox.c
+++ b/wibox.c
@@ -366,9 +366,9 @@ wibox_position_update(wibox_t *wibox)
     switch(wibox->position)
     {
       case Right:
-        wingeom.height = area.height - 2 * wibox->sw.border.width;
+        wingeom.height = area.height;
         wingeom.width = wibox->sw.geometry.width > 0 ? 
wibox->sw.geometry.width : 1.5 * globalconf.font->height;
-        wingeom.x = area.x + area.width - wingeom.width - 2 * 
wibox->sw.border.width;
+        wingeom.x = area.x + area.width - wingeom.width;
         switch(wibox->align)
         {
           default:
@@ -383,13 +383,13 @@ wibox_position_update(wibox_t *wibox)
         }
         break;
       case Left:
-        wingeom.height = area.height - 2 * wibox->sw.border.width;
+        wingeom.height = area.height;
         wingeom.width = wibox->sw.geometry.width > 0 ? 
wibox->sw.geometry.width : 1.5 * globalconf.font->height;
         wingeom.x = area.x;
         switch(wibox->align)
         {
           default:
-            wingeom.y = (area.y + area.height) - wingeom.height - 2 * 
wibox->sw.border.width;
+            wingeom.y = (area.y + area.height) - wingeom.height;
             break;
           case AlignRight:
             wingeom.y = area.y;
@@ -400,8 +400,8 @@ wibox_position_update(wibox_t *wibox)
         break;
       case Bottom:
         wingeom.height = wibox->sw.geometry.height > 0 ? 
wibox->sw.geometry.height : 1.5 * globalconf.font->height;
-        wingeom.width = area.width - 2 * wibox->sw.border.width;
-        wingeom.y = (area.y + area.height) - wingeom.height - 2 * 
wibox->sw.border.width;
+        wingeom.width = area.width;
+        wingeom.y = (area.y + area.height) - wingeom.height;
         wingeom.x = area.x;
         switch(wibox->align)
         {
@@ -417,7 +417,7 @@ wibox_position_update(wibox_t *wibox)
         break;
       case Top:
         wingeom.height = wibox->sw.geometry.height > 0 ? 
wibox->sw.geometry.height : 1.5 * globalconf.font->height;
-        wingeom.width = area.width - 2 * wibox->sw.border.width;
+        wingeom.width = area.width;
         wingeom.x = area.x;
         wingeom.y = area.y;
         switch(wibox->align)
-- 
1.6.0.4

Reply via email to