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.wibox")
|
||||||
require("awful.startup_notification")
|
require("awful.startup_notification")
|
||||||
require("awful.tooltip")
|
require("awful.tooltip")
|
||||||
|
require("awful.ewmh")
|
||||||
|
|
||||||
--- AWesome Functions very UsefuL
|
--- AWesome Functions very UsefuL
|
||||||
module("awful")
|
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)
|
if(c->fullscreen != s)
|
||||||
{
|
{
|
||||||
area_t geometry;
|
|
||||||
|
|
||||||
/* become fullscreen! */
|
/* become fullscreen! */
|
||||||
if(s)
|
if(s)
|
||||||
{
|
{
|
||||||
|
@ -767,103 +765,43 @@ client_set_fullscreen(lua_State *L, int cidx, bool s)
|
||||||
client_set_below(L, cidx, false);
|
client_set_below(L, cidx, false);
|
||||||
client_set_above(L, cidx, false);
|
client_set_above(L, cidx, false);
|
||||||
client_set_ontop(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
|
int abs_cidx = luaA_absindex(L, cidx); \
|
||||||
{
|
lua_pushboolean(L, s);
|
||||||
geometry = c->geometries.fullscreen;
|
luaA_object_emit_signal(L, abs_cidx, "request::fullscreen", 1);
|
||||||
c->fullscreen = false;
|
c->fullscreen = s;
|
||||||
window_set_border_width(L, cidx, c->border_width_fs);
|
|
||||||
}
|
|
||||||
client_resize(c, geometry, false);
|
|
||||||
stack_windows();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
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 L The Lua VM state.
|
||||||
* \param cidx The client index.
|
* \param cidx The client index.
|
||||||
* \param s The maximized status.
|
* \param s The maximized status.
|
||||||
*/
|
*/
|
||||||
void
|
#define DO_FUNCTION_CLIENT_MAXIMIZED(type) \
|
||||||
client_set_maximized_horizontal(lua_State *L, int cidx, bool s)
|
void \
|
||||||
{
|
client_set_maximized_##type(lua_State *L, int cidx, bool s) \
|
||||||
client_t *c = luaA_checkudata(L, cidx, &client_class);
|
{ \
|
||||||
|
client_t *c = luaA_checkudata(L, cidx, &client_class); \
|
||||||
if(c->maximized_horizontal != s)
|
if(c->maximized_##type != s) \
|
||||||
{
|
{ \
|
||||||
area_t geometry;
|
int abs_cidx = luaA_absindex(L, cidx); \
|
||||||
|
if(s) \
|
||||||
if((c->maximized_horizontal = s))
|
client_set_fullscreen(L, abs_cidx, false); \
|
||||||
{
|
lua_pushboolean(L, s); \
|
||||||
/* remove fullscreen mode */
|
luaA_object_emit_signal(L, abs_cidx, "request::maximized_" #type, 1); \
|
||||||
client_set_fullscreen(L, cidx, false);
|
c->maximized_##type = s; \
|
||||||
|
stack_windows(); \
|
||||||
geometry = screen_area_get(c->screen, true);
|
ewmh_client_update_hints(c); \
|
||||||
geometry.y = c->geometry.y;
|
luaA_object_emit_signal(L, abs_cidx, "property::maximized_" #type, 0); \
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
DO_FUNCTION_CLIENT_MAXIMIZED(vertical)
|
||||||
|
DO_FUNCTION_CLIENT_MAXIMIZED(horizontal)
|
||||||
/** Set a client vertically maximized.
|
#undef DO_FUNCTION_CLIENT_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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set a client above, or not.
|
/** Set a client above, or not.
|
||||||
* \param L The Lua VM state.
|
* \param L The Lua VM state.
|
||||||
|
|
|
@ -70,15 +70,6 @@ struct client_t
|
||||||
char *class, *instance;
|
char *class, *instance;
|
||||||
/** Window geometry */
|
/** Window geometry */
|
||||||
area_t 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 */
|
/** True if the client is sticky */
|
||||||
bool sticky;
|
bool sticky;
|
||||||
/** Has urgency hint */
|
/** 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;
|
area_t new_geometry = c->geometry;
|
||||||
|
|
||||||
if(c->fullscreen)
|
new_geometry.x = to.x + new_geometry.x - from.x;
|
||||||
{
|
new_geometry.y = to.y + new_geometry.y - from.y;
|
||||||
new_geometry = to;
|
|
||||||
area_t new_f_geometry = c->geometries.fullscreen;
|
|
||||||
|
|
||||||
new_f_geometry.x = to.x + new_f_geometry.x - from.x;
|
/* resize the client if it doesn't fit the new screen */
|
||||||
new_f_geometry.y = to.y + new_f_geometry.y - from.x;
|
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 */
|
/* make sure the client is still on the screen */
|
||||||
if(new_f_geometry.width > to.width)
|
if(new_geometry.x + new_geometry.width > to.x + to.width)
|
||||||
new_f_geometry.width = to.width;
|
new_geometry.x = to.x + to.width - new_geometry.width;
|
||||||
if(new_f_geometry.height > to.height)
|
if(new_geometry.y + new_geometry.height > to.y + to.height)
|
||||||
new_f_geometry.height = 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 */
|
/* move / resize the client */
|
||||||
client_resize(c, new_geometry, false);
|
client_resize(c, new_geometry, false);
|
||||||
luaA_object_push(globalconf.L, c);
|
luaA_object_push(globalconf.L, c);
|
||||||
|
|
Loading…
Reference in New Issue