Move size-hints handling to lua
The C core now completely ignores size hints and let's lua handle them. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
4e31c72497
commit
eff4474c6d
2
event.c
2
event.c
|
@ -287,7 +287,7 @@ event_handle_configurerequest(xcb_configure_request_event_t *ev)
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!client_resize(c, geometry, false))
|
if(!client_resize(c, geometry))
|
||||||
/* ICCCM 4.1.5 / 4.2.3, if nothing was changed, send an event saying so */
|
/* ICCCM 4.1.5 / 4.2.3, if nothing was changed, send an event saying so */
|
||||||
xwindow_configure(c->window, geometry, c->border_width);
|
xwindow_configure(c->window, geometry, c->border_width);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- @author Uli Schlachter
|
||||||
|
-- @copyright 2011 Uli Schlachter
|
||||||
|
-- @release @AWESOME_VERSION@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local client = client
|
||||||
|
local math = math
|
||||||
|
|
||||||
|
--- Implements ICCCM handling.
|
||||||
|
module("awful.icccm")
|
||||||
|
|
||||||
|
-- Make sure we don't get into an endless loop
|
||||||
|
local size_hints_lock = false
|
||||||
|
|
||||||
|
function apply_size_hints(c)
|
||||||
|
if size_hints_lock then return end
|
||||||
|
if not c.size_hints_honor then return end
|
||||||
|
-- Fullscreen clients don't get size hints applied!
|
||||||
|
if c.fullscreen then return end
|
||||||
|
|
||||||
|
size_hints_lock = true
|
||||||
|
|
||||||
|
local geom = c:geometry()
|
||||||
|
local hints = c.size_hints
|
||||||
|
|
||||||
|
local basew, baseh
|
||||||
|
local real_basew, real_baseh = 0, 0
|
||||||
|
if hints.base_width then
|
||||||
|
basew, baseh = hints.base_width, hints.base_height
|
||||||
|
real_basew, real_baseh = basew, baseh
|
||||||
|
elseif hints.min_width then
|
||||||
|
-- Base size is substituted with min size if not specified
|
||||||
|
basew, baseh = hints.min_width, hints.min_height
|
||||||
|
else
|
||||||
|
basew, baseh = 0, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle the size aspect ratio
|
||||||
|
|
||||||
|
if hints.min_aspect_den then
|
||||||
|
-- Apply the size aspect
|
||||||
|
if hints.min_aspect_den > 0 and hints.max_aspect_den > 0 and
|
||||||
|
geom.height > real_baseh and geom.width > real_basew then
|
||||||
|
-- ICCCM mandates:
|
||||||
|
-- If a base size is provided along with the aspect ratio fields, the
|
||||||
|
-- base size should be subtracted from the window size prior to checking
|
||||||
|
-- that the aspect ratio falls in range. If a base size is not provided,
|
||||||
|
-- nothing should be subtracted from the window size. (The minimum size
|
||||||
|
-- is not to be used in place of the base size for this purpose.)
|
||||||
|
local dx = geom.width - real_basew
|
||||||
|
local dy = geom.height - real_baseh
|
||||||
|
local ratio = dx / dy
|
||||||
|
local min = hints.min_aspect_num / hints.min_aspect_den
|
||||||
|
local max = hints.max_aspect_num / hints.max_aspect_den
|
||||||
|
|
||||||
|
if max > 0 and min > 0 and ratio > 0 then
|
||||||
|
if ratio < min then
|
||||||
|
-- dx is lower than allowed, make dy lower to compensate this
|
||||||
|
-- (+ 0.5 to force proper rounding).
|
||||||
|
dy = dx / min + 0.5
|
||||||
|
geom.width = dx + real_basew
|
||||||
|
geom.height = dy + real_baseh
|
||||||
|
elseif ratio > max then
|
||||||
|
-- dx is too high, lower it (+0.5 for proper rounding)
|
||||||
|
dx = dy * max + 0.5
|
||||||
|
geom.width = dx + real_basew
|
||||||
|
geom.height = dy + real_baseh;
|
||||||
|
end
|
||||||
|
-- Make sure these are integers
|
||||||
|
geom.width = math.floor(geom.width)
|
||||||
|
geom.height = math.floor(geom.height)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle the minimum size
|
||||||
|
local minw, minh
|
||||||
|
if hints.min_width then
|
||||||
|
minw, minh = hints.min_width, hints.min_height
|
||||||
|
elseif hints.base_width then
|
||||||
|
-- min size is substituted with base size if not specified
|
||||||
|
minw, minh = hints.base_width, hints.base_height
|
||||||
|
else
|
||||||
|
minw, minh = 0, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if minw ~= nil and minw > 0 and geom.width < minw then
|
||||||
|
geom.width = minw
|
||||||
|
end
|
||||||
|
if minh ~= nil and minh > 0 and geom.height < minh then
|
||||||
|
geom.height = minh
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle the maximum size
|
||||||
|
if hints.max_width ~= nil and hints.max_width > 0 and hints.max_width < geom.width then
|
||||||
|
geom.width = hints.max_width
|
||||||
|
end
|
||||||
|
if hints.max_height ~= nil and hints.max_height > 0 and hints.max_height < geom.height then
|
||||||
|
geom.height = hints.max_height
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle the size increment
|
||||||
|
if hints.width_inc and hints.width_inc > 0 then
|
||||||
|
function apply_inc(size, inc, base)
|
||||||
|
local i = size - base
|
||||||
|
if i < 0 then i = 0 end
|
||||||
|
-- Round size down to a multiple of inc, ignoring the base size
|
||||||
|
return size - math.fmod(i, inc)
|
||||||
|
end
|
||||||
|
geom.width = apply_inc(geom.width, hints.width_inc, basew)
|
||||||
|
geom.height = apply_inc(geom.height, hints.height_inc, baseh)
|
||||||
|
end
|
||||||
|
|
||||||
|
c:geometry(geom)
|
||||||
|
|
||||||
|
size_hints_lock = false
|
||||||
|
end
|
||||||
|
|
||||||
|
client.connect_signal("property::width", apply_size_hints)
|
||||||
|
client.connect_signal("property::height", apply_size_hints)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -22,6 +22,7 @@ require("awful.wibox")
|
||||||
require("awful.startup_notification")
|
require("awful.startup_notification")
|
||||||
require("awful.tooltip")
|
require("awful.tooltip")
|
||||||
require("awful.ewmh")
|
require("awful.ewmh")
|
||||||
|
require("awful.icccm")
|
||||||
|
|
||||||
--- AWesome Functions very UsefuL
|
--- AWesome Functions very UsefuL
|
||||||
module("awful")
|
module("awful")
|
||||||
|
|
111
objects/client.c
111
objects/client.c
|
@ -533,110 +533,6 @@ HANDLE_GEOM(height)
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compute client geometry with respect to its geometry hints.
|
|
||||||
* \param c The client.
|
|
||||||
* \param geometry The geometry that the client might receive.
|
|
||||||
* \return The geometry the client must take respecting its hints.
|
|
||||||
*/
|
|
||||||
area_t
|
|
||||||
client_geometry_hints(client_t *c, area_t geometry)
|
|
||||||
{
|
|
||||||
int32_t basew, baseh, minw, minh;
|
|
||||||
int32_t real_basew = 0, real_baseh = 0;
|
|
||||||
|
|
||||||
/* base size is substituted with min size if not specified */
|
|
||||||
if(c->size_hints.flags & XCB_SIZE_HINT_P_SIZE)
|
|
||||||
{
|
|
||||||
basew = c->size_hints.base_width;
|
|
||||||
baseh = c->size_hints.base_height;
|
|
||||||
real_basew = basew;
|
|
||||||
real_baseh = baseh;
|
|
||||||
}
|
|
||||||
else if(c->size_hints.flags & XCB_SIZE_HINT_P_MIN_SIZE)
|
|
||||||
{
|
|
||||||
basew = c->size_hints.min_width;
|
|
||||||
baseh = c->size_hints.min_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
basew = baseh = 0;
|
|
||||||
|
|
||||||
/* min size is substituted with base size if not specified */
|
|
||||||
if(c->size_hints.flags & XCB_SIZE_HINT_P_MIN_SIZE)
|
|
||||||
{
|
|
||||||
minw = c->size_hints.min_width;
|
|
||||||
minh = c->size_hints.min_height;
|
|
||||||
}
|
|
||||||
else if(c->size_hints.flags & XCB_SIZE_HINT_P_SIZE)
|
|
||||||
{
|
|
||||||
minw = c->size_hints.base_width;
|
|
||||||
minh = c->size_hints.base_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
minw = minh = 0;
|
|
||||||
|
|
||||||
if(c->size_hints.flags & XCB_SIZE_HINT_P_ASPECT
|
|
||||||
&& c->size_hints.min_aspect_den > 0
|
|
||||||
&& c->size_hints.max_aspect_den > 0
|
|
||||||
&& geometry.height - real_baseh > 0
|
|
||||||
&& geometry.width - real_basew > 0)
|
|
||||||
{
|
|
||||||
/* ICCCM mandates:
|
|
||||||
* If a base size is provided along with the aspect ratio fields, the
|
|
||||||
* base size should be subtracted from the window size prior to checking
|
|
||||||
* that the aspect ratio falls in range. If a base size is not provided,
|
|
||||||
* nothing should be subtracted from the window size. (The minimum size
|
|
||||||
* is not to be used in place of the base size for this purpose.) */
|
|
||||||
double dx = (double) (geometry.width - real_basew);
|
|
||||||
double dy = (double) (geometry.height - real_baseh);
|
|
||||||
double min = (double) c->size_hints.min_aspect_num / (double) c->size_hints.min_aspect_den;
|
|
||||||
double max = (double) c->size_hints.max_aspect_num / (double) c->size_hints.max_aspect_den;
|
|
||||||
double ratio = dx / dy;
|
|
||||||
if(max > 0 && min > 0 && ratio > 0)
|
|
||||||
{
|
|
||||||
if(ratio < min)
|
|
||||||
{
|
|
||||||
/* dx is lower than allowed, make dy lower to compensate this
|
|
||||||
* (+ 0.5 to force proper rounding). */
|
|
||||||
dy = dx / min + 0.5;
|
|
||||||
geometry.width = (int) dx + real_basew;
|
|
||||||
geometry.height = (int) dy + real_baseh;
|
|
||||||
}
|
|
||||||
else if(ratio > max)
|
|
||||||
{
|
|
||||||
/* dx is too high, lower it (+0.5 for proper rounding) */
|
|
||||||
dx = dy * max + 0.5;
|
|
||||||
geometry.width = (int) dx + real_basew;
|
|
||||||
geometry.height = (int) dy + real_baseh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(minw)
|
|
||||||
geometry.width = MAX(geometry.width, minw);
|
|
||||||
if(minh)
|
|
||||||
geometry.height = MAX(geometry.height, minh);
|
|
||||||
|
|
||||||
if(c->size_hints.flags & XCB_SIZE_HINT_P_MAX_SIZE)
|
|
||||||
{
|
|
||||||
if(c->size_hints.max_width)
|
|
||||||
geometry.width = MIN(geometry.width, c->size_hints.max_width);
|
|
||||||
if(c->size_hints.max_height)
|
|
||||||
geometry.height = MIN(geometry.height, c->size_hints.max_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resize client window.
|
/** Resize client window.
|
||||||
* The sizes given as parameters are with borders!
|
* The sizes given as parameters are with borders!
|
||||||
* \param c Client to resize.
|
* \param c Client to resize.
|
||||||
|
@ -645,7 +541,7 @@ client_geometry_hints(client_t *c, area_t geometry)
|
||||||
* \return true if an actual resize occurred.
|
* \return true if an actual resize occurred.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
client_resize(client_t *c, area_t geometry, bool hints)
|
client_resize(client_t *c, area_t geometry)
|
||||||
{
|
{
|
||||||
area_t area;
|
area_t area;
|
||||||
|
|
||||||
|
@ -661,9 +557,6 @@ client_resize(client_t *c, area_t geometry, bool hints)
|
||||||
if(geometry.y + geometry.height < 0)
|
if(geometry.y + geometry.height < 0)
|
||||||
geometry.y = 0;
|
geometry.y = 0;
|
||||||
|
|
||||||
if(hints && !c->fullscreen)
|
|
||||||
geometry = client_geometry_hints(c, geometry);
|
|
||||||
|
|
||||||
if(geometry.width == 0 || geometry.height == 0)
|
if(geometry.width == 0 || geometry.height == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1284,7 +1177,7 @@ luaA_client_geometry(lua_State *L)
|
||||||
geometry.height = luaA_getopt_number(L, 2, "height", c->geometry.height);
|
geometry.height = luaA_getopt_number(L, 2, "height", c->geometry.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_resize(c, geometry, c->size_hints_honor);
|
client_resize(c, geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return luaA_pusharea(L, c->geometry);
|
return luaA_pusharea(L, c->geometry);
|
||||||
|
|
|
@ -116,8 +116,7 @@ void client_ban(client_t *);
|
||||||
void client_ban_unfocus(client_t *);
|
void client_ban_unfocus(client_t *);
|
||||||
void client_unban(client_t *);
|
void client_unban(client_t *);
|
||||||
void client_manage(xcb_window_t, xcb_get_geometry_reply_t *, bool);
|
void client_manage(xcb_window_t, xcb_get_geometry_reply_t *, bool);
|
||||||
area_t client_geometry_hints(client_t *, area_t);
|
bool client_resize(client_t *, area_t);
|
||||||
bool client_resize(client_t *, area_t, bool);
|
|
||||||
void client_unmanage(client_t *, bool);
|
void client_unmanage(client_t *, bool);
|
||||||
void client_kill(client_t *);
|
void client_kill(client_t *);
|
||||||
void client_set_sticky(lua_State *, int, bool);
|
void client_set_sticky(lua_State *, int, bool);
|
||||||
|
|
2
screen.c
2
screen.c
|
@ -378,7 +378,7 @@ screen_client_moveto(client_t *c, screen_t *new_screen, bool doresize)
|
||||||
new_geometry.y = to.y + to.height - new_geometry.height;
|
new_geometry.y = to.y + to.height - new_geometry.height;
|
||||||
|
|
||||||
/* move / resize the client */
|
/* move / resize the client */
|
||||||
client_resize(c, new_geometry, false);
|
client_resize(c, new_geometry);
|
||||||
luaA_object_push(globalconf.L, c);
|
luaA_object_push(globalconf.L, c);
|
||||||
luaA_object_emit_signal(globalconf.L, -1, "property::screen", 0);
|
luaA_object_emit_signal(globalconf.L, -1, "property::screen", 0);
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
|
|
Loading…
Reference in New Issue