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 <madman2003@gmail.com> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
5f8b34b909
commit
6e199bbd76
|
@ -393,7 +393,7 @@ awful.hooks.arrange.register(function (screen)
|
||||||
-- Uncomment if you want mouse warping
|
-- Uncomment if you want mouse warping
|
||||||
--[[
|
--[[
|
||||||
if client.focus then
|
if client.focus then
|
||||||
local c_c = client.focus:fullgeometry()
|
local c_c = client.focus:geometry()
|
||||||
local m_c = mouse.coords()
|
local m_c = mouse.coords()
|
||||||
|
|
||||||
if m_c.x < c_c.x or m_c.x >= c_c.x + c_c.width or
|
if m_c.x < c_c.x or m_c.x >= c_c.x + c_c.width or
|
||||||
|
|
129
client.c
129
client.c
|
@ -174,8 +174,8 @@ client_ban(client_t *c)
|
||||||
{
|
{
|
||||||
/* Move all clients out of the physical viewport into negative coordinate space. */
|
/* Move all clients out of the physical viewport into negative coordinate space. */
|
||||||
/* They will all be put on top of each other. */
|
/* They will all be put on top of each other. */
|
||||||
uint32_t request[2] = { - (c->geometry.width + 2 * c->border),
|
uint32_t request[2] = { - (c->geometries.internal.width + 2 * c->border),
|
||||||
- (c->geometry.height + 2 * c->border) };
|
- (c->geometries.internal.height + 2 * c->border) };
|
||||||
|
|
||||||
xcb_configure_window(globalconf.connection, c->win,
|
xcb_configure_window(globalconf.connection, c->win,
|
||||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
||||||
|
@ -475,8 +475,13 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen,
|
||||||
c->win = w;
|
c->win = w;
|
||||||
c->geometry.x = wgeom->x;
|
c->geometry.x = wgeom->x;
|
||||||
c->geometry.y = wgeom->y;
|
c->geometry.y = wgeom->y;
|
||||||
c->geometry.width = wgeom->width;
|
c->geometry.width = wgeom->width + 2 * wgeom->border_width;
|
||||||
c->geometry.height = wgeom->height;
|
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);
|
client_setborder(c, wgeom->border_width);
|
||||||
if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie)))
|
if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie)))
|
||||||
c->icon = image_ref(&icon);
|
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)
|
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)
|
&& c->size_hints.width_inc && c->size_hints.height_inc)
|
||||||
{
|
{
|
||||||
geometry.width -= (geometry.width - basew) % c->size_hints.width_inc;
|
uint16_t t1 = geometry.width, t2 = geometry.height;
|
||||||
geometry.height -= (geometry.height - baseh) % c->size_hints.height_inc;
|
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;
|
return geometry;
|
||||||
|
@ -690,42 +698,52 @@ void
|
||||||
client_resize(client_t *c, area_t geometry, bool hints)
|
client_resize(client_t *c, area_t geometry, bool hints)
|
||||||
{
|
{
|
||||||
int new_screen;
|
int new_screen;
|
||||||
|
area_t geometry_internal;
|
||||||
area_t area;
|
area_t area;
|
||||||
|
|
||||||
if(hints)
|
|
||||||
geometry = client_geometry_hints(c, geometry);
|
|
||||||
|
|
||||||
if(geometry.width <= 0 || geometry.height <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* offscreen appearance fixes */
|
/* offscreen appearance fixes */
|
||||||
area = display_area_get(c->phys_screen, NULL,
|
area = display_area_get(c->phys_screen, NULL,
|
||||||
&globalconf.screens[c->screen].padding);
|
&globalconf.screens[c->screen].padding);
|
||||||
|
|
||||||
if(geometry.x > area.width)
|
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)
|
if(geometry.y > area.height)
|
||||||
geometry.y = area.height - geometry.height - 2 * c->border;
|
geometry.y = area.height - geometry.height;
|
||||||
if(geometry.x + geometry.width + 2 * c->border < 0)
|
if(geometry.x + geometry.width < 0)
|
||||||
geometry.x = 0;
|
geometry.x = 0;
|
||||||
if(geometry.y + geometry.height + 2 * c->border < 0)
|
if(geometry.y + geometry.height < 0)
|
||||||
geometry.y = 0;
|
geometry.y = 0;
|
||||||
|
|
||||||
if(c->geometry.x != geometry.x
|
/* Real client geometry, please keep it contained to C code at the very least. */
|
||||||
|| c->geometry.y != geometry.y
|
geometry_internal = titlebar_geometry_remove(c->titlebar, c->border, geometry);
|
||||||
|| c->geometry.width != geometry.width
|
|
||||||
|| c->geometry.height != geometry.height)
|
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
|
/* Values to configure a window is an array where values are
|
||||||
* stored according to 'value_mask' */
|
* stored according to 'value_mask' */
|
||||||
uint32_t values[4];
|
uint32_t values[4];
|
||||||
|
|
||||||
c->geometry.x = values[0] = geometry.x;
|
c->geometries.internal.x = values[0] = geometry_internal.x;
|
||||||
c->geometry.y = values[1] = geometry.y;
|
c->geometries.internal.y = values[1] = geometry_internal.y;
|
||||||
c->geometry.width = values[2] = geometry.width;
|
c->geometries.internal.width = values[2] = geometry_internal.width;
|
||||||
c->geometry.height = values[3] = geometry.height;
|
c->geometries.internal.height = values[3] = geometry_internal.height;
|
||||||
|
|
||||||
|
/* Also store geometry including border and titlebar. */
|
||||||
|
c->geometry = geometry;
|
||||||
|
|
||||||
titlebar_update_geometry(c);
|
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. */
|
/* This at least doesn't break expectations about events. */
|
||||||
if (c->isbanned)
|
if (c->isbanned)
|
||||||
{
|
{
|
||||||
geometry.x = values[0] = - (geometry.width + 2 * c->border);
|
geometry.x = values[0] = - (geometry_internal.width + 2 * c->border);
|
||||||
geometry.y = values[1] = - (geometry.height + 2 * c->border);
|
geometry.y = values[1] = - (geometry_internal.height + 2 * c->border);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_configure_window(globalconf.connection, c->win,
|
xcb_configure_window(globalconf.connection, c->win,
|
||||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
|
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
|
||||||
| XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
| XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
values);
|
values);
|
||||||
window_configure(c->win, geometry, c->border);
|
window_configure(c->win, geometry_internal, c->border);
|
||||||
|
|
||||||
screen_client_moveto(c, new_screen, true, false);
|
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].wiboxes,
|
||||||
&globalconf.screens[c->screen].padding,
|
&globalconf.screens[c->screen].padding,
|
||||||
true);
|
true);
|
||||||
/* Remove space needed for titlebar and border. */
|
|
||||||
geometry = titlebar_geometry_remove(c->titlebar,
|
|
||||||
c->border,
|
|
||||||
geometry);
|
|
||||||
geometry.y = c->geometry.y;
|
geometry.y = c->geometry.y;
|
||||||
geometry.height = c->geometry.height;
|
geometry.height = c->geometry.height;
|
||||||
c->geometries.max.x = c->geometry.x;
|
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].wiboxes,
|
||||||
&globalconf.screens[c->screen].padding,
|
&globalconf.screens[c->screen].padding,
|
||||||
true);
|
true);
|
||||||
/* Remove space needed for titlebar and border. */
|
|
||||||
geometry = titlebar_geometry_remove(c->titlebar,
|
|
||||||
c->border,
|
|
||||||
geometry);
|
|
||||||
geometry.x = c->geometry.x;
|
geometry.x = c->geometry.x;
|
||||||
geometry.width = c->geometry.width;
|
geometry.width = c->geometry.width;
|
||||||
c->geometries.max.y = c->geometry.y;
|
c->geometries.max.y = c->geometry.y;
|
||||||
|
@ -1006,12 +1016,12 @@ client_unban(client_t *c)
|
||||||
if(c->isbanned)
|
if(c->isbanned)
|
||||||
{
|
{
|
||||||
/* Move the client back where it belongs. */
|
/* 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_configure_window(globalconf.connection, c->win,
|
||||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
||||||
request);
|
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.
|
/* Do this manually because the system doesn't know we moved the toolbar.
|
||||||
* Note that !isvisible titlebars are unmapped and for fullscreen it'll
|
* Note that !isvisible titlebars are unmapped and for fullscreen it'll
|
||||||
|
@ -1347,11 +1357,13 @@ luaA_client_unmanage(lua_State *L)
|
||||||
|
|
||||||
/** Return client geometry.
|
/** Return client geometry.
|
||||||
* \param L The Lua VM state.
|
* \param L The Lua VM state.
|
||||||
* \param full Use titlebar also.
|
|
||||||
* \return The number of elements pushed on stack.
|
* \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
|
static int
|
||||||
luaA_client_handlegeom(lua_State *L, bool full)
|
luaA_client_geometry(lua_State *L)
|
||||||
{
|
{
|
||||||
client_t **c = luaA_checkudata(L, 1, "client");
|
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);
|
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);
|
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 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.
|
/** Client newindex.
|
||||||
* \param L The Lua VM state.
|
* \param L The Lua VM state.
|
||||||
* \return The number of elements pushed on stack.
|
* \return The number of elements pushed on stack.
|
||||||
|
@ -1955,7 +1931,6 @@ const struct luaL_reg awesome_client_meta[] =
|
||||||
{
|
{
|
||||||
{ "isvisible", luaA_client_isvisible },
|
{ "isvisible", luaA_client_isvisible },
|
||||||
{ "geometry", luaA_client_geometry },
|
{ "geometry", luaA_client_geometry },
|
||||||
{ "fullgeometry", luaA_client_fullgeometry },
|
|
||||||
{ "buttons", luaA_client_buttons },
|
{ "buttons", luaA_client_buttons },
|
||||||
{ "tags", luaA_client_tags },
|
{ "tags", luaA_client_tags },
|
||||||
{ "kill", luaA_client_kill },
|
{ "kill", luaA_client_kill },
|
||||||
|
|
|
@ -72,6 +72,14 @@ typedef struct
|
||||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#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 ssizeof(foo) (ssize_t)sizeof(foo)
|
||||||
#define countof(foo) (ssizeof(foo) / ssizeof(foo[0]))
|
#define countof(foo) (ssizeof(foo) / ssizeof(foo[0]))
|
||||||
|
|
||||||
|
|
|
@ -52,10 +52,7 @@ local function fair(screen, orientation)
|
||||||
g.y = wa.y + cell * g.height
|
g.y = wa.y + cell * g.height
|
||||||
end
|
end
|
||||||
|
|
||||||
g.width = g.width - 2 * c.border_width
|
c:geometry(g)
|
||||||
g.height = g.height - 2 * c.border_width
|
|
||||||
|
|
||||||
c:fullgeometry(g)
|
|
||||||
|
|
||||||
cell = cell + 1
|
cell = cell + 1
|
||||||
if cell == cells then
|
if cell == cells then
|
||||||
|
|
|
@ -55,10 +55,10 @@ local function magnifier(_, screen)
|
||||||
else
|
else
|
||||||
geometry.x = area.x
|
geometry.x = area.x
|
||||||
geometry.y = area.y
|
geometry.y = area.y
|
||||||
geometry.width = area.width - 2 * focus.border_width
|
geometry.width = area.width
|
||||||
geometry.height = area.height - 2 * focus.border_width
|
geometry.height = area.height
|
||||||
end
|
end
|
||||||
focus:fullgeometry(geometry)
|
focus:geometry(geometry)
|
||||||
focus:raise()
|
focus:raise()
|
||||||
|
|
||||||
if #cls - 1 > 0 then
|
if #cls - 1 > 0 then
|
||||||
|
@ -69,11 +69,7 @@ local function magnifier(_, screen)
|
||||||
|
|
||||||
for k, c in ipairs(cls) do
|
for k, c in ipairs(cls) do
|
||||||
if c ~= focus then
|
if c ~= focus then
|
||||||
geometry.height = geometry.height - 2 * c.border_width
|
c:geometry(geometry)
|
||||||
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
|
|
||||||
geometry.y = geometry.y + geometry.height
|
geometry.y = geometry.y + geometry.height
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,11 +27,7 @@ local function fmax(screen, fs)
|
||||||
|
|
||||||
for k, c in pairs(client.visible(screen)) do
|
for k, c in pairs(client.visible(screen)) do
|
||||||
if not client.floating.get(c) then
|
if not client.floating.get(c) then
|
||||||
area.width = area.width - 2 * c.border_width
|
c:geometry(area)
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,8 +87,8 @@ local function tile(_, screen, position)
|
||||||
geometry.y = wa.y
|
geometry.y = wa.y
|
||||||
end
|
end
|
||||||
|
|
||||||
geometry.width = mw - 2 * c.border_width
|
geometry.width = mw
|
||||||
geometry.height = mh - 2 * c.border_width
|
geometry.height = mh
|
||||||
|
|
||||||
-- Slave windows
|
-- Slave windows
|
||||||
else
|
else
|
||||||
|
@ -98,52 +98,52 @@ local function tile(_, screen, position)
|
||||||
|
|
||||||
if position == "right" or position == "left" then
|
if position == "right" or position == "left" then
|
||||||
if otherwin <= real_ncol 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
|
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
|
else
|
||||||
geometry.height = math.floor(wa.height / win_by_col) - 2 * c.border_width
|
geometry.height = math.floor(wa.height / win_by_col)
|
||||||
end
|
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
|
if otherwin <= real_ncol then
|
||||||
geometry.y = wa.y
|
geometry.y = wa.y
|
||||||
else
|
else
|
||||||
geometry.y = wa.y + ((i - 1 - nmaster) % win_by_col) *
|
geometry.y = wa.y + ((i - 1 - nmaster) % win_by_col) *
|
||||||
(geometry.height + 2 * c.border_width)
|
geometry.height
|
||||||
end
|
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
|
if position == "right" then
|
||||||
geometry.x = geometry.x + mw
|
geometry.x = geometry.x + mw
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if otherwin <= real_ncol then
|
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
|
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
|
else
|
||||||
geometry.width = math.floor(wa.width / win_by_col) - 2 * c.border_width
|
geometry.width = math.floor(wa.width / win_by_col)
|
||||||
end
|
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
|
if otherwin <= real_ncol then
|
||||||
geometry.x = wa.x
|
geometry.x = wa.x
|
||||||
else
|
else
|
||||||
geometry.x = wa.x + ((i - 1 - nmaster) % win_by_col) *
|
geometry.x = wa.x + ((i - 1 - nmaster) % win_by_col) *
|
||||||
(geometry.width + 2 * c.border_width)
|
geometry.width
|
||||||
end
|
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
|
if position == "bottom" then
|
||||||
geometry.y = geometry.y + mh
|
geometry.y = geometry.y + mh
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
c:fullgeometry(geometry)
|
c:geometry(geometry)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -199,19 +199,19 @@ local function set_coords(menu, screen_idx)
|
||||||
menu.w = menu.parent.w
|
menu.w = menu.parent.w
|
||||||
menu.h = menu.parent.h
|
menu.h = menu.parent.h
|
||||||
|
|
||||||
local p_w = (menu.h + menu.theme.border_width) * (menu.num - 1)
|
local p_w = menu.h * (menu.num - 1)
|
||||||
local m_h = menu.theme.border_width + (menu.h + menu.theme.border_width) * #menu.items
|
local m_h = menu.h * #menu.items
|
||||||
local m_w = menu.w + menu.theme.border_width
|
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.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
|
else
|
||||||
local m_coords = capi.mouse.coords()
|
local m_coords = capi.mouse.coords()
|
||||||
|
|
||||||
menu.y = m_coords.y < s_geometry.y and s_geometry.y or m_coords.y
|
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
|
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_h = menu.h * #menu.items
|
||||||
local m_w = menu.w + menu.theme.border_width*2
|
local m_w = menu.w
|
||||||
menu.y = menu.y + m_h > screen_h and screen_h - m_h or menu.y
|
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
|
menu.x = menu.x + m_w > screen_w and screen_w - m_w or menu.x
|
||||||
end
|
end
|
||||||
|
@ -227,7 +227,7 @@ function show(menu)
|
||||||
width = menu.w,
|
width = menu.w,
|
||||||
height = menu.h,
|
height = menu.h,
|
||||||
x = menu.x,
|
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
|
item.screen = screen_index
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,8 +86,8 @@ end
|
||||||
function client.snap(c, snap, x, y, fixed_x, fixed_y)
|
function client.snap(c, snap, x, y, fixed_x, fixed_y)
|
||||||
local snap = snap or 8
|
local snap = snap or 8
|
||||||
local c = c or client.focus
|
local c = c or client.focus
|
||||||
local cur_geom = c:fullgeometry()
|
local cur_geom = c:geometry()
|
||||||
local geom = c:fullgeometry()
|
local geom = c:geometry()
|
||||||
geom.x = x or geom.x
|
geom.x = x or geom.x
|
||||||
geom.y = y or geom.y
|
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
|
for k, snapper in ipairs(aclient.visible(c.screen)) do
|
||||||
if snapper ~= c then
|
if snapper ~= c then
|
||||||
geom = snap_outside(geom, snapper:fullgeometry(), snap)
|
geom = snap_outside(geom, snapper:geometry(), snap)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ function client.move(c, snap)
|
||||||
|
|
||||||
c:raise()
|
c:raise()
|
||||||
|
|
||||||
local orig = c:fullgeometry()
|
local orig = c:geometry()
|
||||||
local m_c = capi.mouse.coords()
|
local m_c = capi.mouse.coords()
|
||||||
local dist_x = m_c.x - orig.x
|
local dist_x = m_c.x - orig.x
|
||||||
local dist_y = m_c.y - orig.y
|
local dist_y = m_c.y - orig.y
|
||||||
|
@ -134,7 +134,7 @@ function client.move(c, snap)
|
||||||
|
|
||||||
local function ug(c, prop)
|
local function ug(c, prop)
|
||||||
if prop == "geometry" then
|
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 })
|
capi.mouse.coords({ x = g.x + dist_x, y = g.y + dist_y })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -147,7 +147,7 @@ function client.move(c, snap)
|
||||||
if lay == layout.suit.floating or aclient.floating.get(c) then
|
if lay == layout.suit.floating or aclient.floating.get(c) then
|
||||||
local x = mouse.x - dist_x
|
local x = mouse.x - dist_x
|
||||||
local y = mouse.y - dist_y
|
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
|
if layout.get(c.screen) ~= layout.suit.floating and not aclient.floating.get(c) then
|
||||||
hooks.property.register(ug)
|
hooks.property.register(ug)
|
||||||
end
|
end
|
||||||
|
@ -389,9 +389,9 @@ local function client_resize_floating(c, corner, fixed_x, fixed_y)
|
||||||
end
|
end
|
||||||
if ng.width <= 0 then ng.width = nil end
|
if ng.width <= 0 then ng.width = nil end
|
||||||
if ng.height <= 0 then ng.height = nil end
|
if ng.height <= 0 then ng.height = nil end
|
||||||
if fixed_x then ng.width = width end
|
if fixed_x then ng.width = g.width ng.x = g.x end
|
||||||
if fixed_y then ng.height = height end
|
if fixed_y then ng.height = g.height ng.y = g.y end
|
||||||
c:geometry({ width = ng.width, height = ng.height })
|
c:geometry(ng)
|
||||||
-- Get real geometry that has been applied
|
-- Get real geometry that has been applied
|
||||||
-- in case we honor size hints
|
-- in case we honor size hints
|
||||||
-- XXX: This should be rewritten when size
|
-- XXX: This should be rewritten when size
|
||||||
|
|
|
@ -101,7 +101,7 @@ end
|
||||||
--- Place the client without it being outside the screen.
|
--- Place the client without it being outside the screen.
|
||||||
-- @param c The client.
|
-- @param c The client.
|
||||||
function no_offscreen(c)
|
function no_offscreen(c)
|
||||||
local geometry = c:fullgeometry()
|
local geometry = c:geometry()
|
||||||
local screen_geometry = capi.screen[c.screen].workarea
|
local screen_geometry = capi.screen[c.screen].workarea
|
||||||
|
|
||||||
if geometry.x + geometry.width > screen_geometry.x + screen_geometry.width then
|
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
|
geometry.y = screen_geometry.y
|
||||||
end
|
end
|
||||||
|
|
||||||
c:fullgeometry(geometry)
|
c:geometry(geometry)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Place the client where there's place available with minimum overlap.
|
--- Place the client where there's place available with minimum overlap.
|
||||||
|
@ -126,10 +126,9 @@ function no_overlap(c)
|
||||||
local layout = layout.get()
|
local layout = layout.get()
|
||||||
local areas = { capi.screen[c.screen].workarea }
|
local areas = { capi.screen[c.screen].workarea }
|
||||||
local geometry = c:geometry()
|
local geometry = c:geometry()
|
||||||
local fullgeometry = c:fullgeometry()
|
|
||||||
for i, cl in pairs(cls) do
|
for i, cl in pairs(cls) do
|
||||||
if cl ~= c and (client.get.floating(cl) or layout == layout.suit.floating) then
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,8 +136,8 @@ function no_overlap(c)
|
||||||
local found = false
|
local found = false
|
||||||
local new = { x = geometry.x, y = geometry.y, width = 0, height = 0 }
|
local new = { x = geometry.x, y = geometry.y, width = 0, height = 0 }
|
||||||
for i, r in ipairs(areas) do
|
for i, r in ipairs(areas) do
|
||||||
if r.width >= fullgeometry.width
|
if r.width >= geometry.width
|
||||||
and r.height >= fullgeometry.height
|
and r.height >= geometry.height
|
||||||
and r.width * r.height > new.width * new.height then
|
and r.width * r.height > new.width * new.height then
|
||||||
found = true
|
found = true
|
||||||
new = r
|
new = r
|
||||||
|
|
|
@ -113,12 +113,12 @@ function add(c, args)
|
||||||
closef = closef, close = close }
|
closef = closef, close = close }
|
||||||
|
|
||||||
-- Store old geometry (including borders)
|
-- Store old geometry (including borders)
|
||||||
local old_geom = c:fullgeometry()
|
local old_geom = c:geometry()
|
||||||
|
|
||||||
c.titlebar = tb
|
c.titlebar = tb
|
||||||
|
|
||||||
-- Resize the client so the same amount of space is occupied as before.
|
-- 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)
|
||||||
update(c, "geometry")
|
update(c, "geometry")
|
||||||
|
@ -142,10 +142,10 @@ function update(c, prop)
|
||||||
if data[c].width then
|
if data[c].width then
|
||||||
if c.titlebar.position == "top"
|
if c.titlebar.position == "top"
|
||||||
or c.titlebar.position == "bottom" then
|
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 })
|
c.titlebar:geometry({ width = w })
|
||||||
else
|
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 })
|
c.titlebar:geometry({ height = w })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -167,11 +167,11 @@ end
|
||||||
--- Remove a titlebar from a client.
|
--- Remove a titlebar from a client.
|
||||||
-- @param c The client.
|
-- @param c The client.
|
||||||
function remove(c)
|
function remove(c)
|
||||||
local old_geom = c:fullgeometry()
|
local old_geom = c:geometry()
|
||||||
c.titlebar = nil
|
c.titlebar = nil
|
||||||
data[c] = nil
|
data[c] = nil
|
||||||
-- Resize the client so the same amount of space is occupied as before.
|
-- Resize the client so the same amount of space is occupied as before.
|
||||||
c:fullgeometry(old_geom)
|
c:geometry(old_geom)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register standards hooks
|
-- Register standards hooks
|
||||||
|
|
|
@ -159,20 +159,20 @@ local function get_offset(screen, position, idx, width, height)
|
||||||
if position:match("left") then
|
if position:match("left") then
|
||||||
v.x = ws.x + config.padding
|
v.x = ws.x + config.padding
|
||||||
else
|
else
|
||||||
v.x = ws.x + ws.width - (width + config.border_width*2 + config.padding)
|
v.x = ws.x + ws.width - (width + config.padding)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- calculate existing popups' height
|
-- calculate existing popups' height
|
||||||
local existing = 0
|
local existing = 0
|
||||||
for i = 1, idx-1, 1 do
|
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
|
end
|
||||||
|
|
||||||
-- calculate y
|
-- calculate y
|
||||||
if position:match("top") then
|
if position:match("top") then
|
||||||
v.y = ws.y + config.padding + existing
|
v.y = ws.y + config.padding + existing
|
||||||
else
|
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
|
end
|
||||||
|
|
||||||
-- if positioned outside workarea, destroy oldest popup and recalculate
|
-- if positioned outside workarea, destroy oldest popup and recalculate
|
||||||
|
|
|
@ -162,6 +162,8 @@ struct client_t
|
||||||
area_t fullscreen;
|
area_t fullscreen;
|
||||||
/** Client geometry when (un)-max */
|
/** Client geometry when (un)-max */
|
||||||
area_t max;
|
area_t max;
|
||||||
|
/** Internal geometry (matching X11 protocol) */
|
||||||
|
area_t internal;
|
||||||
} geometries;
|
} geometries;
|
||||||
/** Strut */
|
/** Strut */
|
||||||
strut_t strut;
|
strut_t strut;
|
||||||
|
|
62
swindow.c
62
swindow.c
|
@ -48,14 +48,14 @@ simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s)
|
||||||
xcb_create_pixmap(globalconf.connection,
|
xcb_create_pixmap(globalconf.connection,
|
||||||
s->root_depth,
|
s->root_depth,
|
||||||
sw->ctx.pixmap, s->root,
|
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,
|
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);
|
sw->ctx.pixmap, &fg, &bg);
|
||||||
break;
|
break;
|
||||||
case East:
|
case East:
|
||||||
draw_context_init(&sw->ctx, phys_screen,
|
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);
|
sw->pixmap, &fg, &bg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,13 @@ simplewindow_init(simple_window_t *sw,
|
||||||
sw->geometry.width = geometry.width;
|
sw->geometry.width = geometry.width;
|
||||||
sw->geometry.height = geometry.height;
|
sw->geometry.height = geometry.height;
|
||||||
sw->border.width = border_width;
|
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->orientation = orientation;
|
||||||
sw->ctx.fg = *fg;
|
sw->ctx.fg = *fg;
|
||||||
sw->ctx.bg = *bg;
|
sw->ctx.bg = *bg;
|
||||||
|
@ -102,14 +109,14 @@ simplewindow_init(simple_window_t *sw,
|
||||||
|
|
||||||
sw->window = xcb_generate_id(globalconf.connection);
|
sw->window = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_window(globalconf.connection, s->root_depth, sw->window, s->root,
|
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,
|
border_width, XCB_COPY_FROM_PARENT, s->root_visual,
|
||||||
XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
|
XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
|
||||||
create_win_val);
|
create_win_val);
|
||||||
|
|
||||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root,
|
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;
|
sw->ctx.phys_screen = phys_screen;
|
||||||
simplewindow_draw_context_update(sw, s);
|
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 };
|
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.x = sw->geometries.internal.x = x;
|
||||||
sw->geometry.y = y;
|
sw->geometry.y = sw->geometries.internal.y = y;
|
||||||
xcb_configure_window(globalconf.connection, sw->window,
|
xcb_configure_window(globalconf.connection, sw->window,
|
||||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
|
||||||
move_win_vals);
|
move_win_vals);
|
||||||
|
@ -171,19 +178,25 @@ simplewindow_move(simple_window_t *sw, int x, int y)
|
||||||
void
|
void
|
||||||
simplewindow_resize(simple_window_t *sw, int w, int h)
|
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);
|
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
||||||
uint32_t resize_win_vals[2];
|
uint32_t resize_win_vals[2];
|
||||||
|
|
||||||
sw->geometry.width = resize_win_vals[0] = w;
|
sw->geometries.internal.width = resize_win_vals[0] = iw;
|
||||||
sw->geometry.height = resize_win_vals[1] = h;
|
sw->geometries.internal.height = resize_win_vals[1] = ih;
|
||||||
|
sw->geometry.width = w;
|
||||||
|
sw->geometry.height = h;
|
||||||
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
||||||
/* orientation != East */
|
/* orientation != East */
|
||||||
if(sw->pixmap != sw->ctx.pixmap)
|
if(sw->pixmap != sw->ctx.pixmap)
|
||||||
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
||||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, w, h);
|
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, iw, ih);
|
||||||
xcb_configure_window(globalconf.connection, sw->window,
|
xcb_configure_window(globalconf.connection, sw->window,
|
||||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
resize_win_vals);
|
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.
|
/** Move and resize a window in one call.
|
||||||
* \param sw The simple window to move and resize.
|
* \param sw The simple window to move and resize.
|
||||||
* \param geom The new gometry.
|
* \param geom The new geometry.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
simplewindow_moveresize(simple_window_t *sw, area_t geom)
|
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;
|
uint32_t moveresize_win_vals[4], mask_vals = 0;
|
||||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen);
|
||||||
|
|
||||||
if(sw->geometry.x != 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->geometries.internal.x = moveresize_win_vals[0] = geom_internal.x;
|
||||||
sw->geometry.y = moveresize_win_vals[1] = geom.y;
|
sw->geometries.internal.y = moveresize_win_vals[1] = geom_internal.y;
|
||||||
mask_vals |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_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)
|
if(mask_vals)
|
||||||
{
|
{
|
||||||
sw->geometry.width = moveresize_win_vals[2] = geom.width;
|
sw->geometries.internal.width = moveresize_win_vals[2] = geom_internal.width;
|
||||||
sw->geometry.height = moveresize_win_vals[3] = geom.height;
|
sw->geometries.internal.height = moveresize_win_vals[3] = geom_internal.height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sw->geometry.width = moveresize_win_vals[0] = geom.width;
|
sw->geometries.internal.width = moveresize_win_vals[0] = geom_internal.width;
|
||||||
sw->geometry.height = moveresize_win_vals[1] = geom.height;
|
sw->geometries.internal.height = moveresize_win_vals[1] = geom_internal.height;
|
||||||
}
|
}
|
||||||
mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
mask_vals |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
xcb_free_pixmap(globalconf.connection, sw->pixmap);
|
||||||
|
@ -226,10 +243,13 @@ simplewindow_moveresize(simple_window_t *sw, area_t geom)
|
||||||
if(sw->pixmap != sw->ctx.pixmap)
|
if(sw->pixmap != sw->ctx.pixmap)
|
||||||
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
xcb_free_pixmap(globalconf.connection, sw->ctx.pixmap);
|
||||||
sw->pixmap = xcb_generate_id(globalconf.connection);
|
sw->pixmap = xcb_generate_id(globalconf.connection);
|
||||||
xcb_create_pixmap(globalconf.connection, s->root_depth, sw->pixmap, s->root, 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);
|
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);
|
xcb_configure_window(globalconf.connection, sw->window, mask_vals, moveresize_win_vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ typedef struct simple_window_t
|
||||||
xcb_gcontext_t gc;
|
xcb_gcontext_t gc;
|
||||||
/** The window geometry. */
|
/** The window geometry. */
|
||||||
area_t geometry;
|
area_t geometry;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/** Internal geometry (matching X11 protocol) */
|
||||||
|
area_t internal;
|
||||||
|
} geometries;
|
||||||
/** The window border */
|
/** The window border */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
34
titlebar.c
34
titlebar.c
|
@ -64,83 +64,83 @@ client_getbytitlebarwin(xcb_window_t win)
|
||||||
void
|
void
|
||||||
titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res)
|
||||||
{
|
{
|
||||||
int width, x_offset = 0, y_offset = 0;
|
int height, width, x_offset = 0, y_offset = 0;
|
||||||
|
|
||||||
switch(c->titlebar->position)
|
switch(c->titlebar->position)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
case Top:
|
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)
|
switch(c->titlebar->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->sw.border.width;
|
x_offset = geometry.width - width;
|
||||||
break;
|
break;
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
x_offset = (geometry.width - width) / 2;
|
x_offset = (geometry.width - width) / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res->x = geometry.x + x_offset;
|
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->width = width;
|
||||||
res->height = c->titlebar->sw.geometry.height;
|
res->height = c->titlebar->sw.geometry.height;
|
||||||
break;
|
break;
|
||||||
case Bottom:
|
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)
|
switch(c->titlebar->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->sw.border.width;
|
x_offset = geometry.width - width;
|
||||||
break;
|
break;
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
x_offset = (geometry.width - width) / 2;
|
x_offset = (geometry.width - width) / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res->x = geometry.x + x_offset;
|
res->x = geometry.x + x_offset;
|
||||||
res->y = geometry.y + geometry.height + c->border;
|
res->y = geometry.y + geometry.height - c->titlebar->sw.geometry.height;
|
||||||
res->width = width;
|
res->width = width;
|
||||||
res->height = c->titlebar->sw.geometry.height;
|
res->height = c->titlebar->sw.geometry.height;
|
||||||
break;
|
break;
|
||||||
case Left:
|
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)
|
switch(c->titlebar->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->sw.border.width;
|
y_offset = geometry.height - height;
|
||||||
break;
|
break;
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
y_offset = (geometry.height - width) / 2;
|
y_offset = (geometry.height - height) / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res->x = geometry.x - c->titlebar->sw.geometry.width + c->border;
|
res->x = geometry.x;
|
||||||
res->y = geometry.y + y_offset;
|
res->y = geometry.y + y_offset;
|
||||||
res->width = c->titlebar->sw.geometry.width;
|
res->width = c->titlebar->sw.geometry.width;
|
||||||
res->height = width;
|
res->height = height;
|
||||||
break;
|
break;
|
||||||
case Right:
|
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)
|
switch(c->titlebar->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->sw.border.width;
|
y_offset = geometry.height - height;
|
||||||
break;
|
break;
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
y_offset = (geometry.height - width) / 2;
|
y_offset = (geometry.height - height) / 2;
|
||||||
break;
|
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->y = geometry.y + y_offset;
|
||||||
res->width = c->titlebar->sw.geometry.width;
|
res->width = c->titlebar->sw.geometry.width;
|
||||||
res->height = width;
|
res->height = height;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
titlebar.h
28
titlebar.h
|
@ -51,18 +51,18 @@ titlebar_geometry_add(wibox_t *t, int border, area_t geometry)
|
||||||
switch(t->position)
|
switch(t->position)
|
||||||
{
|
{
|
||||||
case Top:
|
case Top:
|
||||||
geometry.y -= t->sw.geometry.height + 2 * t->sw.border.width;
|
geometry.y -= t->sw.geometry.height;
|
||||||
geometry.height += t->sw.geometry.height + 2 * t->sw.border.width;
|
geometry.height += t->sw.geometry.height;
|
||||||
break;
|
break;
|
||||||
case Bottom:
|
case Bottom:
|
||||||
geometry.height += t->sw.geometry.height + 2 * t->sw.border.width;
|
geometry.height += t->sw.geometry.height;
|
||||||
break;
|
break;
|
||||||
case Left:
|
case Left:
|
||||||
geometry.x -= t->sw.geometry.width + 2 * t->sw.border.width;
|
geometry.x -= t->sw.geometry.width;
|
||||||
geometry.width += t->sw.geometry.width + 2 * t->sw.border.width;
|
geometry.width += t->sw.geometry.width;
|
||||||
break;
|
break;
|
||||||
case Right:
|
case Right:
|
||||||
geometry.width += t->sw.geometry.width + 2 * t->sw.border.width;
|
geometry.width += t->sw.geometry.width;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -92,26 +92,26 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t geometry)
|
||||||
switch(t->position)
|
switch(t->position)
|
||||||
{
|
{
|
||||||
case Top:
|
case Top:
|
||||||
geometry.y += t->sw.geometry.height + 2 * t->sw.border.width;
|
geometry.y += t->sw.geometry.height;
|
||||||
geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width;
|
unsigned_subtract(geometry.height, t->sw.geometry.height);
|
||||||
break;
|
break;
|
||||||
case Bottom:
|
case Bottom:
|
||||||
geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width;
|
unsigned_subtract(geometry.height, t->sw.geometry.height);
|
||||||
break;
|
break;
|
||||||
case Left:
|
case Left:
|
||||||
geometry.x += t->sw.geometry.width + 2 * t->sw.border.width;
|
geometry.x += t->sw.geometry.width;
|
||||||
geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width;
|
unsigned_subtract(geometry.width, t->sw.geometry.width);
|
||||||
break;
|
break;
|
||||||
case Right:
|
case Right:
|
||||||
geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width;
|
unsigned_subtract(geometry.width, t->sw.geometry.width);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adding a border to a client only changes width and height, x and y are including border. */
|
/* Adding a border to a client only changes width and height, x and y are including border. */
|
||||||
geometry.width -= 2 * border;
|
unsigned_subtract(geometry.width, 2*border);
|
||||||
geometry.height -= 2 * border;
|
unsigned_subtract(geometry.height, 2*border);
|
||||||
|
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
14
wibox.c
14
wibox.c
|
@ -366,9 +366,9 @@ wibox_position_update(wibox_t *wibox)
|
||||||
switch(wibox->position)
|
switch(wibox->position)
|
||||||
{
|
{
|
||||||
case Right:
|
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.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)
|
switch(wibox->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -383,13 +383,13 @@ wibox_position_update(wibox_t *wibox)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Left:
|
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.width = wibox->sw.geometry.width > 0 ? wibox->sw.geometry.width : 1.5 * globalconf.font->height;
|
||||||
wingeom.x = area.x;
|
wingeom.x = area.x;
|
||||||
switch(wibox->align)
|
switch(wibox->align)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
wingeom.y = (area.y + area.height) - wingeom.height - 2 * wibox->sw.border.width;
|
wingeom.y = (area.y + area.height) - wingeom.height;
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
wingeom.y = area.y;
|
wingeom.y = area.y;
|
||||||
|
@ -400,8 +400,8 @@ wibox_position_update(wibox_t *wibox)
|
||||||
break;
|
break;
|
||||||
case Bottom:
|
case Bottom:
|
||||||
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height;
|
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.y = (area.y + area.height) - wingeom.height - 2 * wibox->sw.border.width;
|
wingeom.y = (area.y + area.height) - wingeom.height;
|
||||||
wingeom.x = area.x;
|
wingeom.x = area.x;
|
||||||
switch(wibox->align)
|
switch(wibox->align)
|
||||||
{
|
{
|
||||||
|
@ -417,7 +417,7 @@ wibox_position_update(wibox_t *wibox)
|
||||||
break;
|
break;
|
||||||
case Top:
|
case Top:
|
||||||
wingeom.height = wibox->sw.geometry.height > 0 ? wibox->sw.geometry.height : 1.5 * globalconf.font->height;
|
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.x = area.x;
|
||||||
wingeom.y = area.y;
|
wingeom.y = area.y;
|
||||||
switch(wibox->align)
|
switch(wibox->align)
|
||||||
|
|
Loading…
Reference in New Issue