From 38edc5809755b4623b30bcb1838360d29d86b789 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 5 Oct 2009 17:13:29 +0200 Subject: [PATCH] client: implements maximized and fullscreen requests with Lua Signed-off-by: Julien Danjou --- lib/awful/ewmh.lua.in | 112 +++++++++++++++++++++++++++++++++++++++++ lib/awful/init.lua.in | 1 + objects/client.c | 114 ++++++++++-------------------------------- objects/client.h | 9 ---- screen.c | 48 +++++------------- 5 files changed, 151 insertions(+), 133 deletions(-) create mode 100644 lib/awful/ewmh.lua.in diff --git a/lib/awful/ewmh.lua.in b/lib/awful/ewmh.lua.in new file mode 100644 index 00000000..cfac2179 --- /dev/null +++ b/lib/awful/ewmh.lua.in @@ -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 diff --git a/lib/awful/init.lua.in b/lib/awful/init.lua.in index 38e8b542..9f4e1732 100644 --- a/lib/awful/init.lua.in +++ b/lib/awful/init.lua.in @@ -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") diff --git a/objects/client.c b/objects/client.c index cba7f882..909c0f45 100644 --- a/objects/client.c +++ b/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. diff --git a/objects/client.h b/objects/client.h index 784b72a3..9baa2f86 100644 --- a/objects/client.h +++ b/objects/client.h @@ -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 */ diff --git a/screen.c b/screen.c index 8c655aeb..ab8a18cb 100644 --- a/screen.c +++ b/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);