client: implements maximized and fullscreen requests with Lua

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-10-05 17:13:29 +02:00
parent 434a6e5275
commit 38edc58097
5 changed files with 151 additions and 133 deletions

112
lib/awful/ewmh.lua.in Normal file
View File

@ -0,0 +1,112 @@
---------------------------------------------------------------------------
-- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2009 Julien Danjou
-- @release @AWESOME_VERSION@
---------------------------------------------------------------------------
local setmetatable = setmetatable
local client = client
local screen = screen
local ipairs = ipairs
local math = math
--- Implements EWMH requests handling.
module("awful.ewmh")
local data = setmetatable({}, { __mode = 'k' })
local function store_geometry(window, reqtype)
if not data[window] then data[window] = {} end
if not data[window][reqtype] then data[window][reqtype] = {} end
data[window][reqtype] = window:geometry()
data[window][reqtype].screen = window.screen
end
-- Maximize a window horizontally.
-- @param window The window.
-- @param set Set or unset the maximized values.
local function maximized_horizontal(window, set)
if set then
store_geometry(window, "maximized")
local g = screen[window.screen].workarea
window:geometry { width = g.width, x = g.x }
elseif data[window] and data[window].maximized
and data[window].maximized.x
and data[window].maximized.width then
window:geometry { width = data[window].maximized.width,
x = data[window].maximized.x }
end
end
-- Maximize a window vertically.
-- @param window The window.
-- @param set Set or unset the maximized values.
local function maximized_vertical(window, set)
if set then
store_geometry(window, "maximized")
local g = screen[window.screen].workarea
window:geometry { height = g.height, y = g.y }
elseif data[window] and data[window].maximized
and data[window].maximized.y
and data[window].maximized.height then
window:geometry { height = data[window].maximized.height,
y = data[window].maximized.y }
end
end
-- Fullscreen a window.
-- @param window The window.
-- @param set Set or unset the fullscreen values.
local function fullscreen(window, set)
if set then
store_geometry(window, "fullscreen")
data[window].fullscreen.border_width = window.border_width
local g = screen[window.screen].geometry
window:geometry(screen[window.screen].geometry)
window.border_width = 0
elseif data[window] and data[window].fullscreen then
window:geometry(data[window].fullscreen)
window.border_width = data[window].fullscreen.border_width
end
end
local function screen_change(window)
if data[window] then
for _, reqtype in ipairs({ "maximized", "fullscreen" }) do
if data[window][reqtype] then
if data[window][reqtype].width then
data[window][reqtype].width = math.min(data[window][reqtype].width,
screen[window.screen].workarea.width)
end
if data[window][reqtype].height then
data[window][reqtype].height = math.min(data[window][reqtype].height,
screen[window.screen].workarea.height)
end
if data[window][reqtype].screen then
local from = screen[data[window][reqtype].screen].workarea
local to = screen[window.screen].workarea
local new_x, new_y
if data[window][reqtype].x then
new_x = to.x + data[window][reqtype].x - from.x
if new_x > to.x + to.width then new_x = to.x end
data[window][reqtype].x = new_x
end
if data[window][reqtype].y then
new_y = to.y + data[window][reqtype].y - from.y
if new_y > to.y + to.width then new_y = to.y end
data[window][reqtype].y = new_y
end
end
end
end
end
end
client.add_signal("manage", function (c)
c:add_signal("request::maximized_horizontal", maximized_horizontal)
c:add_signal("request::maximized_vertical", maximized_vertical)
c:add_signal("request::fullscreen", fullscreen)
c:add_signal("property::screen", screen_change)
end)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -21,6 +21,7 @@ require("awful.button")
require("awful.wibox")
require("awful.startup_notification")
require("awful.tooltip")
require("awful.ewmh")
--- AWesome Functions very UsefuL
module("awful")

View File

@ -755,8 +755,6 @@ client_set_fullscreen(lua_State *L, int cidx, bool s)
if(c->fullscreen != s)
{
area_t geometry;
/* become fullscreen! */
if(s)
{
@ -767,103 +765,43 @@ client_set_fullscreen(lua_State *L, int cidx, bool s)
client_set_below(L, cidx, false);
client_set_above(L, cidx, false);
client_set_ontop(L, cidx, false);
geometry = screen_area_get(c->screen, false);
c->geometries.fullscreen = c->geometry;
c->border_width_fs = c->border_width;
window_set_border_width(L, cidx, 0);
c->fullscreen = true;
}
else
{
geometry = c->geometries.fullscreen;
c->fullscreen = false;
window_set_border_width(L, cidx, c->border_width_fs);
}
client_resize(c, geometry, false);
int abs_cidx = luaA_absindex(L, cidx); \
lua_pushboolean(L, s);
luaA_object_emit_signal(L, abs_cidx, "request::fullscreen", 1);
c->fullscreen = s;
stack_windows();
ewmh_client_update_hints(c);
luaA_object_emit_signal(L, cidx, "property::fullscreen", 0);
luaA_object_emit_signal(L, abs_cidx, "property::fullscreen", 0);
}
}
/** Set a client horizontally maximized.
/** Set a client horizontally|vertically maximized.
* \param L The Lua VM state.
* \param cidx The client index.
* \param s The maximized status.
*/
void
client_set_maximized_horizontal(lua_State *L, int cidx, bool s)
{
client_t *c = luaA_checkudata(L, cidx, &client_class);
if(c->maximized_horizontal != s)
{
area_t geometry;
if((c->maximized_horizontal = s))
{
/* remove fullscreen mode */
client_set_fullscreen(L, cidx, false);
geometry = screen_area_get(c->screen, true);
geometry.y = c->geometry.y;
geometry.height = c->geometry.height;
c->geometries.max.x = c->geometry.x;
c->geometries.max.width = c->geometry.width;
}
else
{
geometry = c->geometry;
geometry.x = c->geometries.max.x;
geometry.width = c->geometries.max.width;
}
client_resize(c, geometry, c->size_hints_honor);
stack_windows();
ewmh_client_update_hints(c);
luaA_object_emit_signal(L, cidx, "property::maximized_horizontal", 0);
#define DO_FUNCTION_CLIENT_MAXIMIZED(type) \
void \
client_set_maximized_##type(lua_State *L, int cidx, bool s) \
{ \
client_t *c = luaA_checkudata(L, cidx, &client_class); \
if(c->maximized_##type != s) \
{ \
int abs_cidx = luaA_absindex(L, cidx); \
if(s) \
client_set_fullscreen(L, abs_cidx, false); \
lua_pushboolean(L, s); \
luaA_object_emit_signal(L, abs_cidx, "request::maximized_" #type, 1); \
c->maximized_##type = s; \
stack_windows(); \
ewmh_client_update_hints(c); \
luaA_object_emit_signal(L, abs_cidx, "property::maximized_" #type, 0); \
} \
}
}
/** Set a client vertically maximized.
* \param L The Lua VM state.
* \param cidx The client index.
* \param s The maximized status.
*/
void
client_set_maximized_vertical(lua_State *L, int cidx, bool s)
{
client_t *c = luaA_checkudata(L, cidx, &client_class);
if(c->maximized_vertical != s)
{
area_t geometry;
if((c->maximized_vertical = s))
{
/* remove fullscreen mode */
client_set_fullscreen(L, cidx, false);
geometry = screen_area_get(c->screen, true);
geometry.x = c->geometry.x;
geometry.width = c->geometry.width;
c->geometries.max.y = c->geometry.y;
c->geometries.max.height = c->geometry.height;
}
else
{
geometry = c->geometry;
geometry.y = c->geometries.max.y;
geometry.height = c->geometries.max.height;
}
client_resize(c, geometry, c->size_hints_honor);
stack_windows();
ewmh_client_update_hints(c);
luaA_object_emit_signal(L, cidx, "property::maximized_vertical", 0);
}
}
DO_FUNCTION_CLIENT_MAXIMIZED(vertical)
DO_FUNCTION_CLIENT_MAXIMIZED(horizontal)
#undef DO_FUNCTION_CLIENT_MAXIMIZED
/** Set a client above, or not.
* \param L The Lua VM state.

View File

@ -70,15 +70,6 @@ struct client_t
char *class, *instance;
/** Window geometry */
area_t geometry;
struct
{
/** Client geometry when (un)fullscreen */
area_t fullscreen;
/** Client geometry when (un)-max */
area_t max;
} geometries;
/** Pre-fullscreen border width */
int border_width_fs;
/** True if the client is sticky */
bool sticky;
/** Has urgency hint */

View File

@ -373,45 +373,21 @@ screen_client_moveto(client_t *c, screen_t *new_screen, bool doresize)
area_t new_geometry = c->geometry;
if(c->fullscreen)
{
new_geometry = to;
area_t new_f_geometry = c->geometries.fullscreen;
new_geometry.x = to.x + new_geometry.x - from.x;
new_geometry.y = to.y + new_geometry.y - from.y;
new_f_geometry.x = to.x + new_f_geometry.x - from.x;
new_f_geometry.y = to.y + new_f_geometry.y - from.x;
/* resize the client if it doesn't fit the new screen */
if(new_geometry.width > to.width)
new_geometry.width = to.width;
if(new_geometry.height > to.height)
new_geometry.height = to.height;
/* resize the client's original geometry if it doesn't fit the screen */
if(new_f_geometry.width > to.width)
new_f_geometry.width = to.width;
if(new_f_geometry.height > to.height)
new_f_geometry.height = to.height;
/* make sure the client is still on the screen */
if(new_geometry.x + new_geometry.width > to.x + to.width)
new_geometry.x = to.x + to.width - new_geometry.width;
if(new_geometry.y + new_geometry.height > to.y + to.height)
new_geometry.y = to.y + to.height - new_geometry.height;
/* make sure the client is still on the screen */
if(new_f_geometry.x + new_f_geometry.width > to.x + to.width)
new_f_geometry.x = to.x + to.width - new_f_geometry.width;
if(new_f_geometry.y + new_f_geometry.height > to.y + to.height)
new_f_geometry.y = to.y + to.height - new_f_geometry.height;
c->geometries.fullscreen = new_f_geometry;
}
else
{
new_geometry.x = to.x + new_geometry.x - from.x;
new_geometry.y = to.y + new_geometry.y - from.y;
/* resize the client if it doesn't fit the new screen */
if(new_geometry.width > to.width)
new_geometry.width = to.width;
if(new_geometry.height > to.height)
new_geometry.height = to.height;
/* make sure the client is still on the screen */
if(new_geometry.x + new_geometry.width > to.x + to.width)
new_geometry.x = to.x + to.width - new_geometry.width;
if(new_geometry.y + new_geometry.height > to.y + to.height)
new_geometry.y = to.y + to.height - new_geometry.height;
}
/* move / resize the client */
client_resize(c, new_geometry, false);
luaA_object_push(globalconf.L, c);