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);
|
||||
}
|
||||
|
||||
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 */
|
||||
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.tooltip")
|
||||
require("awful.ewmh")
|
||||
require("awful.icccm")
|
||||
|
||||
--- AWesome Functions very UsefuL
|
||||
module("awful")
|
||||
|
|
111
objects/client.c
111
objects/client.c
|
@ -533,110 +533,6 @@ HANDLE_GEOM(height)
|
|||
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.
|
||||
* The sizes given as parameters are with borders!
|
||||
* \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.
|
||||
*/
|
||||
bool
|
||||
client_resize(client_t *c, area_t geometry, bool hints)
|
||||
client_resize(client_t *c, area_t geometry)
|
||||
{
|
||||
area_t area;
|
||||
|
||||
|
@ -661,9 +557,6 @@ client_resize(client_t *c, area_t geometry, bool hints)
|
|||
if(geometry.y + geometry.height < 0)
|
||||
geometry.y = 0;
|
||||
|
||||
if(hints && !c->fullscreen)
|
||||
geometry = client_geometry_hints(c, geometry);
|
||||
|
||||
if(geometry.width == 0 || geometry.height == 0)
|
||||
return false;
|
||||
|
||||
|
@ -1284,7 +1177,7 @@ luaA_client_geometry(lua_State *L)
|
|||
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);
|
||||
|
|
|
@ -116,8 +116,7 @@ void client_ban(client_t *);
|
|||
void client_ban_unfocus(client_t *);
|
||||
void client_unban(client_t *);
|
||||
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);
|
||||
bool client_resize(client_t *, area_t);
|
||||
void client_unmanage(client_t *, bool);
|
||||
void client_kill(client_t *);
|
||||
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;
|
||||
|
||||
/* move / resize the client */
|
||||
client_resize(c, new_geometry, false);
|
||||
client_resize(c, new_geometry);
|
||||
luaA_object_push(globalconf.L, c);
|
||||
luaA_object_emit_signal(globalconf.L, -1, "property::screen", 0);
|
||||
lua_pop(globalconf.L, 1);
|
||||
|
|
Loading…
Reference in New Issue