client: implements maximized and fullscreen requests with Lua
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
434a6e5275
commit
38edc58097
|
@ -0,0 +1,112 @@
|
|||
---------------------------------------------------------------------------
|
||||
-- @author Julien Danjou <julien@danjou.info>
|
||||
-- @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
|
|
@ -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")
|
||||
|
|
114
objects/client.c
114
objects/client.c
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
48
screen.c
48
screen.c
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue