From 51ddb5639e9c77844c1c5b81c8dcf34f31f5aacf Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 3 Feb 2017 18:30:09 -0500 Subject: [PATCH 01/13] mouse: Handle `maximized` client like `fullscreen` ones. There is already a way to prevent them from moving them, but the next few commits will remove it. There is no reasons to handle this differently from fullscreen clients. --- lib/awful/mouse/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/awful/mouse/init.lua b/lib/awful/mouse/init.lua index 62d8e3b67..0e6812228 100644 --- a/lib/awful/mouse/init.lua +++ b/lib/awful/mouse/init.lua @@ -82,6 +82,7 @@ function mouse.client.move(c, snap, finished_cb) --luacheck: no unused args if not c or c.fullscreen + or c.maximized or c.type == "desktop" or c.type == "splash" or c.type == "dock" then @@ -189,6 +190,7 @@ function mouse.client.resize(c, corner, args) if not c then return end if c.fullscreen + or c.maximized or c.type == "desktop" or c.type == "splash" or c.type == "dock" then From 27173163cb9f2b8f9e5ee237d9799878d4162126 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 3 Feb 2017 18:38:25 -0500 Subject: [PATCH 02/13] client: Apply the whole geometry before emitting the signals This resolve a possible race condition where the size could be invalid when queried from a signal callback. Fix #1456 --- objects/client.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/objects/client.c b/objects/client.c index a4ae587c5..334bbc729 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1426,8 +1426,6 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at * (Else, reparent could cause an UnmapNotify) */ xcb_change_window_attributes(globalconf.connection, w, XCB_CW_EVENT_MASK, select_input_val); - luaA_object_emit_signal(L, -1, "property::window", 0); - /* The frame window gets the border, not the real client window */ xcb_configure_window(globalconf.connection, w, XCB_CONFIG_WINDOW_BORDER_WIDTH, @@ -1450,15 +1448,17 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at /* Store initial geometry and emits signals so we inform that geometry have * been set. */ -#define HANDLE_GEOM(attr) \ - c->geometry.attr = wgeom->attr; \ - luaA_object_emit_signal(L, -1, "property::" #attr, 0); -HANDLE_GEOM(x) -HANDLE_GEOM(y) -HANDLE_GEOM(width) -HANDLE_GEOM(height) -#undef HANDLE_GEOM + c->geometry.x = wgeom->x; + c->geometry.y = wgeom->y; + c->geometry.width = wgeom->width; + c->geometry.height = wgeom->height; + + luaA_object_emit_signal(L, -1, "property::x", 0); + luaA_object_emit_signal(L, -1, "property::y", 0); + luaA_object_emit_signal(L, -1, "property::width", 0); + luaA_object_emit_signal(L, -1, "property::height", 0); + luaA_object_emit_signal(L, -1, "property::window", 0); luaA_object_emit_signal(L, -1, "property::geometry", 0); /* Set border width */ From 3b1599bd990cc6f9d73f232faca580ce79b7cf53 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 24 Jan 2017 04:19:45 -0500 Subject: [PATCH 03/13] maximize: Stop doing it in 2 operations. Before 4.0, maximizing could only be done in 2 operations. 4.0 add an unified way, but kept doing 2 operations. The old Lua EWMH code to serialize the 2 operations was dropped when the codepath was simplified and replaced by a generic version in awful.placement. However this version never implemented combining multiple mementos into 1. This commit unify the maximize C code, drop the ugly macro template and actually fixes a couple more issues that were caused because request::geometry was sent twice. --- lib/awful/ewmh.lua | 1 + lib/awful/titlebar.lua | 8 ++- lib/awful/widget/tasklist.lua | 1 + objects/client.c | 93 ++++++++++++++++++++++++----------- 4 files changed, 70 insertions(+), 33 deletions(-) diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index 57bab35b3..ae34b6ba0 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -224,6 +224,7 @@ end local context_mapper = { maximized_vertical = "maximize_vertically", maximized_horizontal = "maximize_horizontally", + maximized = "maximize", fullscreen = "maximize" } diff --git a/lib/awful/titlebar.lua b/lib/awful/titlebar.lua index c055349e2..36863576e 100644 --- a/lib/awful/titlebar.lua +++ b/lib/awful/titlebar.lua @@ -460,13 +460,11 @@ end -- @param c The client for which the button is wanted. function titlebar.widget.maximizedbutton(c) local widget = titlebar.widget.button(c, "maximized", function(cl) - return cl.maximized_horizontal or cl.maximized_vertical + return cl.maximized end, function(cl, state) - cl.maximized_horizontal = not state - cl.maximized_vertical = not state + cl.maximized = not state end) - c:connect_signal("property::maximized_vertical", widget.update) - c:connect_signal("property::maximized_horizontal", widget.update) + c:connect_signal("property::maximized", widget.update) return widget end diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index eb0bffbac..fa773c351 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -453,6 +453,7 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg capi.client.connect_signal("property::floating", u) capi.client.connect_signal("property::maximized_horizontal", u) capi.client.connect_signal("property::maximized_vertical", u) + capi.client.connect_signal("property::maximized", u) capi.client.connect_signal("property::minimized", u) capi.client.connect_signal("property::name", u) capi.client.connect_signal("property::icon_name", u) diff --git a/objects/client.c b/objects/client.c index 334bbc729..f38b25739 100644 --- a/objects/client.c +++ b/objects/client.c @@ -805,9 +805,16 @@ * @function set_newindex_miss_handler */ +typedef enum { + CLIENT_MAXIMIZED_NONE = 0 << 0, + CLIENT_MAXIMIZED_V = 1 << 0, + CLIENT_MAXIMIZED_H = 1 << 1, +} client_maximized_t; + static area_t titlebar_get_area(client_t *c, client_titlebar_t bar); static drawable_t *titlebar_get_drawable(lua_State *L, client_t *c, int cl_idx, client_titlebar_t bar); static void client_resize_do(client_t *c, area_t geometry); +static void client_set_maximized_common(lua_State *L, int cidx, bool s, const char* type, const int val); /** Collect a client. * \param L The Lua VM state. @@ -1948,38 +1955,68 @@ client_get_maximized(client_t *c) * \param cidx The client index. * \param s The maximized status. */ -#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); \ - int max_before = client_get_maximized(c); \ - c->maximized_##type = s; \ - lua_pushstring(L, "maximized_"#type);\ - luaA_object_emit_signal(L, abs_cidx, "request::geometry", 1); \ - luaA_object_emit_signal(L, abs_cidx, "property::maximized_" #type, 0); \ - if(max_before != client_get_maximized(c)) \ - luaA_object_emit_signal(L, abs_cidx, "property::maximized", 0); \ - stack_windows(); \ - } \ - } -DO_FUNCTION_CLIENT_MAXIMIZED(vertical) -DO_FUNCTION_CLIENT_MAXIMIZED(horizontal) -#undef DO_FUNCTION_CLIENT_MAXIMIZED +void +client_set_maximized_common(lua_State *L, int cidx, bool s, const char* type, const int val) +{ + client_t *c = luaA_checkudata(L, cidx, &client_class); + + /* Store the current and next state on 2 bit */ + const client_maximized_t current = ( + (c->maximized_vertical ? CLIENT_MAXIMIZED_V : CLIENT_MAXIMIZED_NONE)| + (c->maximized_horizontal ? CLIENT_MAXIMIZED_H : CLIENT_MAXIMIZED_NONE) + ); + const client_maximized_t next = s ? val : CLIENT_MAXIMIZED_NONE; + + if(current != next) + { + int abs_cidx = luaA_absindex(L, cidx); + int max_before = client_get_maximized(c); + int h_before = c->maximized_horizontal; + int v_before = c->maximized_vertical; + + /*Update the client properties */ + c->maximized_horizontal = !!(next & CLIENT_MAXIMIZED_H); + c->maximized_vertical = !!(next & CLIENT_MAXIMIZED_V); + + /* Request the changes to be applied */ + lua_pushstring(L, type); + luaA_object_emit_signal(L, abs_cidx, "request::geometry", 1); + + /* Notify changes in the relevant properties */ + if (h_before != c->maximized_horizontal) + luaA_object_emit_signal(L, abs_cidx, "property::maximized_horizontal", 0); + if (v_before != c->maximized_vertical) + luaA_object_emit_signal(L, abs_cidx, "property::maximized_vertical", 0); + if(max_before != client_get_maximized(c)) + luaA_object_emit_signal(L, abs_cidx, "property::maximized", 0); + + stack_windows(); + } +} -/** Set a client maximized (horizontally and vertically). - * \param L The Lua VM state. - * \param cidx The client index. - * \param s Set or not the client maximized attribute. - */ void client_set_maximized(lua_State *L, int cidx, bool s) { - client_set_maximized_horizontal(L, cidx, s); - client_set_maximized_vertical(L, cidx, s); + return client_set_maximized_common( + L, cidx, s, "maximized", + CLIENT_MAXIMIZED_H | CLIENT_MAXIMIZED_V + ); +} + +void +client_set_maximized_horizontal(lua_State *L, int cidx, bool s) +{ + return client_set_maximized_common( + L, cidx, s, "maximized_horizontal", CLIENT_MAXIMIZED_H + ); +} + +void +client_set_maximized_vertical(lua_State *L, int cidx, bool s) +{ + return client_set_maximized_common( + L, cidx, s, "maximized_vertical", CLIENT_MAXIMIZED_V + ); } /** Set a client above, or not. From 3ca363115d029c0e19c303325db2ec391f07a574 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 24 Jan 2017 04:47:21 -0500 Subject: [PATCH 04/13] tests: Add tests for #1321 --- tests/test-maximize.lua | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/test-maximize.lua b/tests/test-maximize.lua index d16c980e0..489633cd9 100644 --- a/tests/test-maximize.lua +++ b/tests/test-maximize.lua @@ -23,6 +23,7 @@ local steps = { local c = client.get()[1] assert(not c.maximized_horizontal) assert(not c.maximized_vertical ) + assert(not c.maximized ) assert(not c.fullscreen ) c.maximized_horizontal = true @@ -99,6 +100,43 @@ local steps = { assert(new_geo[k] == v) end + c.floating = true + + awful.placement.centered(c) + original_geo = c:geometry() + + c.maximized = true + + + return true + end, + function() + local c = client.get()[1] + + local new_geo = c:geometry() + local sgeo = c.screen.workarea + + assert(c.maximized) + assert(c.floating) + assert(new_geo.x==sgeo.x) + assert(new_geo.y==sgeo.y) + + c.maximized = false + + return true + end, + function() + local c = client.get()[1] + + assert(not c.maximized) + assert(c.floating) + + local new_geo = c:geometry() + + for k,v in pairs(original_geo) do + assert(new_geo[k] == v) + end + return true end } From d5b681502a376afad5983eba4174b93a67132295 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 24 Jan 2017 05:41:22 -0500 Subject: [PATCH 05/13] maximize: Stop mixing horizontal, vertical and both. Before this commit, do this: c.maximize_hoizontal = true c.maximize = true c.maximize = false assert(c.maximize_hoizontal) Would not work because the states were not preserved individually. This commit fixes that. Awesome wont be confused about it's own state anymore. This may seem pointless, but when it come to undoing these maximizations, it was ambiguous. --- ewmh.c | 5 +++-- lib/awful/client.lua | 2 ++ lib/awful/ewmh.lua | 4 ++-- objects/client.c | 43 +++++++++++++++++-------------------------- objects/client.h | 4 ++++ 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/ewmh.c b/ewmh.c index ca862a1ef..608276478 100644 --- a/ewmh.c +++ b/ewmh.c @@ -49,9 +49,9 @@ ewmh_client_update_hints(lua_State *L) state[i++] = _NET_WM_STATE_MODAL; if(c->fullscreen) state[i++] = _NET_WM_STATE_FULLSCREEN; - if(c->maximized_vertical) + if(c->maximized_vertical || c->maximized) state[i++] = _NET_WM_STATE_MAXIMIZED_VERT; - if(c->maximized_horizontal) + if(c->maximized_horizontal || c->maximized) state[i++] = _NET_WM_STATE_MAXIMIZED_HORZ; if(c->sticky) state[i++] = _NET_WM_STATE_STICKY; @@ -220,6 +220,7 @@ ewmh_init_lua(void) luaA_class_connect_signal(L, &client_class, "property::fullscreen" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::maximized_horizontal" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::maximized_vertical" , ewmh_client_update_hints); + luaA_class_connect_signal(L, &client_class, "property::maximized" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::sticky" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::skip_taskbar" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::above" , ewmh_client_update_hints); diff --git a/lib/awful/client.lua b/lib/awful/client.lua index 73caf2cff..f8318bcce 100644 --- a/lib/awful/client.lua +++ b/lib/awful/client.lua @@ -138,6 +138,7 @@ function client.tiled(s, stacked) for _, c in pairs(clients) do if not client.object.get_floating(c) and not c.fullscreen + and not c.maximized and not c.maximized_vertical and not c.maximized_horizontal then table.insert(tclients, c) @@ -668,6 +669,7 @@ function client.object.get_floating(c) or c.fullscreen or c.maximized_vertical or c.maximized_horizontal + or c.maximized or client.object.is_fixed(c) then return true end diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index ae34b6ba0..76ae57929 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -45,10 +45,10 @@ local function geometry_change(window) -- Fix up the geometry in case this window needs to cover the whole screen. local bw = window.border_width or 0 local g = window.screen.workarea - if window.maximized_vertical then + if window.maximized_vertical or window.maximized then window:geometry { height = g.height - 2*bw, y = g.y } end - if window.maximized_horizontal then + if window.maximized_horizontal or window.maximized then window:geometry { width = g.width - 2*bw, x = g.x } end if window.fullscreen then diff --git a/objects/client.c b/objects/client.c index f38b25739..7683aa4c4 100644 --- a/objects/client.c +++ b/objects/client.c @@ -809,6 +809,7 @@ typedef enum { CLIENT_MAXIMIZED_NONE = 0 << 0, CLIENT_MAXIMIZED_V = 1 << 0, CLIENT_MAXIMIZED_H = 1 << 1, + CLIENT_MAXIMIZED_BOTH = 1 << 2, /* V|H == BOTH, but ~(V|H) != ~(BOTH)... */ } client_maximized_t; static area_t titlebar_get_area(client_t *c, client_titlebar_t bar); @@ -1940,16 +1941,6 @@ client_set_fullscreen(lua_State *L, int cidx, bool s) } } -/** Get a clients maximized state (horizontally and vertically). - * \param c The client. - * \return The maximized state. - */ -static int -client_get_maximized(client_t *c) -{ - return c->maximized_horizontal && c->maximized_vertical; -} - /** Set a client horizontally|vertically maximized. * \param L The Lua VM state. * \param cidx The client index. @@ -1962,21 +1953,28 @@ client_set_maximized_common(lua_State *L, int cidx, bool s, const char* type, co /* Store the current and next state on 2 bit */ const client_maximized_t current = ( - (c->maximized_vertical ? CLIENT_MAXIMIZED_V : CLIENT_MAXIMIZED_NONE)| - (c->maximized_horizontal ? CLIENT_MAXIMIZED_H : CLIENT_MAXIMIZED_NONE) + (c->maximized_vertical ? CLIENT_MAXIMIZED_V : CLIENT_MAXIMIZED_NONE)| + (c->maximized_horizontal ? CLIENT_MAXIMIZED_H : CLIENT_MAXIMIZED_NONE)| + (c->maximized ? CLIENT_MAXIMIZED_BOTH : CLIENT_MAXIMIZED_NONE) ); - const client_maximized_t next = s ? val : CLIENT_MAXIMIZED_NONE; + client_maximized_t next = s ? (val | current) : (current & (~val)); + + /* When both are already set during startup, assume `maximized` is true*/ + if (next == (CLIENT_MAXIMIZED_H|CLIENT_MAXIMIZED_V) && !globalconf.loop) + next = CLIENT_MAXIMIZED_BOTH; if(current != next) { int abs_cidx = luaA_absindex(L, cidx); - int max_before = client_get_maximized(c); + int max_before = c->maximized; int h_before = c->maximized_horizontal; int v_before = c->maximized_vertical; /*Update the client properties */ - c->maximized_horizontal = !!(next & CLIENT_MAXIMIZED_H); - c->maximized_vertical = !!(next & CLIENT_MAXIMIZED_V); + c->maximized_horizontal = !!(next & CLIENT_MAXIMIZED_H ); + c->maximized_vertical = !!(next & CLIENT_MAXIMIZED_V ); + c->maximized = !!(next & CLIENT_MAXIMIZED_BOTH); + /* Request the changes to be applied */ lua_pushstring(L, type); @@ -1987,7 +1985,7 @@ client_set_maximized_common(lua_State *L, int cidx, bool s, const char* type, co luaA_object_emit_signal(L, abs_cidx, "property::maximized_horizontal", 0); if (v_before != c->maximized_vertical) luaA_object_emit_signal(L, abs_cidx, "property::maximized_vertical", 0); - if(max_before != client_get_maximized(c)) + if(max_before != c->maximized) luaA_object_emit_signal(L, abs_cidx, "property::maximized", 0); stack_windows(); @@ -1998,8 +1996,7 @@ void client_set_maximized(lua_State *L, int cidx, bool s) { return client_set_maximized_common( - L, cidx, s, "maximized", - CLIENT_MAXIMIZED_H | CLIENT_MAXIMIZED_V + L, cidx, s, "maximized", CLIENT_MAXIMIZED_BOTH ); } @@ -3057,15 +3054,9 @@ LUA_OBJECT_EXPORT_PROPERTY(client, client_t, sticky, lua_pushboolean) LUA_OBJECT_EXPORT_PROPERTY(client, client_t, size_hints_honor, lua_pushboolean) LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_horizontal, lua_pushboolean) LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_vertical, lua_pushboolean) +LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized, lua_pushboolean) LUA_OBJECT_EXPORT_PROPERTY(client, client_t, startup_id, lua_pushstring) -static int -luaA_client_get_maximized(lua_State *L, client_t *c) -{ - lua_pushboolean(L, client_get_maximized(c)); - return 1; -} - static int luaA_client_get_content(lua_State *L, client_t *c) { diff --git a/objects/client.h b/objects/client.h index 760fb13cf..ad94e1333 100644 --- a/objects/client.h +++ b/objects/client.h @@ -82,6 +82,10 @@ struct client_t bool maximized_horizontal; /** True if the client is maximized vertically */ bool maximized_vertical; + /** True if the client is maximized both horizontally and vertically by the + * the user + */ + bool maximized; /** True if the client is above others */ bool above; /** True if the client is below others */ From 631e75a7573e69d16c6636882e05301d76ff20d6 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 25 Jan 2017 04:51:10 -0500 Subject: [PATCH 06/13] ewmh: Use the request:: API in the border_width / wa callback And stop listening to property::geometry, it's no longer needed. This also remove messing up the border without saving it somewhere. The concept is sound, but not the implementation. --- lib/awful/ewmh.lua | 41 +++++++++++++++++++++-------------------- tests/test-maximize.lua | 9 +++++---- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index 76ae57929..ba0a44252 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -37,26 +37,24 @@ local ewmh = { --- Update a client's settings when its geometry changes, skipping signals -- resulting from calls within. -local geometry_change_lock = false -local function geometry_change(window) - if geometry_change_lock then return end - geometry_change_lock = true +local repair_geometry_lock = false +local function repair_geometry(window) + if repair_geometry_lock then return end + repair_geometry_lock = true - -- Fix up the geometry in case this window needs to cover the whole screen. - local bw = window.border_width or 0 - local g = window.screen.workarea - if window.maximized_vertical or window.maximized then - window:geometry { height = g.height - 2*bw, y = g.y } - end - if window.maximized_horizontal or window.maximized then - window:geometry { width = g.width - 2*bw, x = g.x } - end - if window.fullscreen then - window.border_width = 0 - window:geometry(window.screen.geometry) + -- Re-apply the geometry locking properties to what they should be. + for _, prop in ipairs { + "fullscreen", "maximized", "maximized_vertical", "maximized_horizontal" + } do + if window[prop] then + window:emit_signal("request::geometry", prop, { + store_geometry = false + }) + break + end end - geometry_change_lock = false + repair_geometry_lock = false end --- Activate a window. @@ -265,7 +263,10 @@ function ewmh.geometry(c, context, hints) -- If the property is boolean and it correspond to the undo operation, -- restore the stored geometry. if state == false then + local original = repair_geometry_lock + repair_geometry_lock = true aplace.restore(c,{context=context}) + repair_geometry_lock = original return end @@ -283,11 +284,11 @@ client.connect_signal("request::activate", ewmh.activate) client.connect_signal("request::tag", ewmh.tag) client.connect_signal("request::urgent", ewmh.urgent) client.connect_signal("request::geometry", ewmh.geometry) -client.connect_signal("property::border_width", geometry_change) -client.connect_signal("property::geometry", geometry_change) +client.connect_signal("property::border_width", repair_geometry) +client.connect_signal("property::screen", repair_geometry) screen.connect_signal("property::workarea", function(s) for _, c in pairs(client.get(s)) do - geometry_change(c) + repair_geometry(c) end end) diff --git a/tests/test-maximize.lua b/tests/test-maximize.lua index 489633cd9..e67a27b59 100644 --- a/tests/test-maximize.lua +++ b/tests/test-maximize.lua @@ -82,10 +82,11 @@ local steps = { local bw = c.border_width assert(c.fullscreen) - assert(new_geo.x-bw==sgeo.x) - assert(new_geo.y-bw==sgeo.y) - assert(new_geo.x+new_geo.width+bw==sgeo.x+sgeo.width) - assert(new_geo.y+new_geo.height+bw==sgeo.y+sgeo.height) + + assert(new_geo.x==sgeo.x) + assert(new_geo.y==sgeo.y) + assert(new_geo.x+new_geo.width+2*bw==sgeo.x+sgeo.width) + assert(new_geo.y+new_geo.height+2*bw==sgeo.y+sgeo.height) c.fullscreen = false From 3a0f139b9e0e8a6f901a2447ab02ddb894b72b9f Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 25 Jan 2017 04:00:33 -0500 Subject: [PATCH 07/13] maximize: Officially honor screen padding Add an option too. Fix #1459 --- lib/awful/ewmh.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index ba0a44252..5fd9d73bf 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -13,12 +13,17 @@ local util = require("awful.util") local aclient = require("awful.client") local aplace = require("awful.placement") local asuit = require("awful.layout.suit") +local beautiful = require("beautiful") local ewmh = { generic_activate_filters = {}, contextual_activate_filters = {}, } +--- Honor the screen padding when maximizing. +-- @beautiful beautiful.maximized_honor_padding +-- @tparam[opt=true] boolean maximized_honor_padding + --- The list of all registered generic request::activate (focus stealing) -- filters. If a filter is added to only one context, it will be in -- `ewmh.contextual_activate_filters`["context_name"]. @@ -276,6 +281,10 @@ function ewmh.geometry(c, context, hints) props.honor_workarea = honor_default end + if props.honor_padding == nil and props.honor_workarea and context:match("maximize") then + props.honor_padding = beautiful.maximized_honor_padding ~= false + end + aplace[context](c, props) end end From 4ea6e133f868af0fa5575d44607e9d28db1ee62a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 26 Jan 2017 03:04:14 -0500 Subject: [PATCH 08/13] placement: Add some missing `ignore_border_width` checks. It was done in some places, but not all. --- lib/awful/placement.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index 7957ddf17..f7e7b982a 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -930,7 +930,7 @@ function placement.under_mouse(d, args) ngeo.x = math.floor(m_coords.x - ngeo.width / 2) ngeo.y = math.floor(m_coords.y - ngeo.height / 2) - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 ngeo.width = ngeo.width - 2*bw ngeo.height = ngeo.height - 2*bw @@ -1034,7 +1034,7 @@ function placement.resize_to_mouse(d, args) pts.x_only and ngeo.y + ngeo.height or math.max(p2.y, p1.y) ) - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 for _, a in ipairs {"width", "height"} do ngeo[a] = ngeo[a] - 2*bw @@ -1084,7 +1084,7 @@ function placement.align(d, args) local sgeo = get_parent_geometry(d, args) local dgeo = geometry_common(d, args) - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 local pos = align_map[args.position]( sgeo.width , @@ -1169,7 +1169,7 @@ function placement.stretch(d, args) local sgeo = get_parent_geometry(d, args) local dgeo = geometry_common(d, args) local ngeo = geometry_common(d, args, nil, true) - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 if args.direction == "left" then ngeo.x = sgeo.x @@ -1231,7 +1231,7 @@ function placement.maximize(d, args) local sgeo = get_parent_geometry(d, args) local ngeo = geometry_common(d, args, nil, true) - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 if (not args.axis) or args.axis :match "vertical" then ngeo.y = sgeo.y @@ -1308,7 +1308,7 @@ function placement.scale(d, args) end end - local bw = d.border_width or 0 + local bw = (not args.ignore_border_width) and d.border_width or 0 ngeo.width = ngeo.width - 2*bw ngeo.height = ngeo.height - 2*bw From 0bf8bb6a64638dec0e588b9aef720ad14fde796a Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 26 Jan 2017 03:06:05 -0500 Subject: [PATCH 09/13] fullscreen: Add a beautiful option to remove borders. This was previously done in a callback, but wasn't really clean and/or bug free. Borders could end up leaking on other screens as proven by an integration test. Fix #171 --- lib/awful/ewmh.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index 5fd9d73bf..5e2631711 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -24,6 +24,10 @@ local ewmh = { -- @beautiful beautiful.maximized_honor_padding -- @tparam[opt=true] boolean maximized_honor_padding +--- Hide the border on fullscreen clients. +-- @beautiful beautiful.fullscreen_hide_border +-- @tparam[opt=true] boolean fullscreen_hide_border + --- The list of all registered generic request::activate (focus stealing) -- filters. If a filter is added to only one context, it will be in -- `ewmh.contextual_activate_filters`["context_name"]. @@ -285,7 +289,19 @@ function ewmh.geometry(c, context, hints) props.honor_padding = beautiful.maximized_honor_padding ~= false end + if original_context == "fullscreen" and beautiful.fullscreen_hide_border ~= false then + props.ignore_border_width = true + end + aplace[context](c, props) + + -- Remove the border to get a "real" fullscreen. + if original_context == "fullscreen" and beautiful.fullscreen_hide_border ~= false then + local original = repair_geometry_lock + repair_geometry_lock = true + c.border_width = 0 + repair_geometry_lock = original + end end end From 5f693ead3087730c221b17d9d380861a884c699b Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 27 Jan 2017 12:57:32 -0500 Subject: [PATCH 10/13] rules: Move tags into the same group as tag Unrelated to this PR, but found while doing a review. --- lib/awful/rules.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index 6fa6efee3..c4ce649a8 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -376,7 +376,7 @@ function rules.extra_properties.placement(c, value) end end -function rules.extra_properties.tags(c, value, props) +function rules.high_priority_properties.tags(c, value, props) local current = c:tags() local tags, s = {}, nil From 6da20bb3014634af67370c731ace37110a2a5b55 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 27 Jan 2017 19:27:19 -0500 Subject: [PATCH 11/13] rules.placement: Add properties to honor padding and workarea --- lib/awful/rules.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index c4ce649a8..85b5f80c1 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -353,7 +353,7 @@ function rules.high_priority_properties.new_tag(c, value, props) return t end -function rules.extra_properties.placement(c, value) +function rules.extra_properties.placement(c, value, props) -- Avoid problems if awesome.startup and (c.size_hints.user_position or c.size_hints.program_position) then @@ -363,8 +363,8 @@ function rules.extra_properties.placement(c, value) local ty = type(value) local args = { - honor_workarea = true, - honor_padding = true + honor_workarea = props.honor_workarea ~= false, + honor_padding = props.honor_padding ~= false } if ty == "function" or (ty == "table" and From 477df4a35ba41a28b8e5c683e259a9b7fa3a94b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Fri, 3 Feb 2017 18:31:51 -0500 Subject: [PATCH 12/13] maximized/fullscreen: Use relative coords when restoring size. Also apply a copy of the memento instead of mutating the original. Fixes #1320 --- lib/awful/placement.lua | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index f7e7b982a..bf7baa358 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -291,6 +291,7 @@ local function store_geometry(d, reqtype) if not data[d][reqtype] then data[d][reqtype] = {} end data[d][reqtype] = d:geometry() data[d][reqtype].screen = d.screen + data[d][reqtype].sgeo = d.screen and d.screen.geometry or nil data[d][reqtype].border_width = d.border_width end @@ -1422,11 +1423,32 @@ function placement.restore(d, args) if not memento then return false end - memento.screen = nil --TODO use it + local x, y = memento.x, memento.y + + -- Some people consider that once moved to another screen, then + -- the memento needs to be upgraded. For now this is only true for + -- maximization until someone complains. + if memento.sgeo and memento.screen and args.context == "maximize" + and d.screen and get_screen(memento.screen) ~= get_screen(d.screen) then + -- Use the absolute geometry as the memento also does + local sgeo = get_screen(d.screen).geometry + + x = sgeo.x + (memento.x - memento.sgeo.x) + y = sgeo.y + (memento.y - memento.sgeo.y) + + end d.border_width = memento.border_width - d:geometry(memento) + -- Don't use the memento as it would be "destructive", since `x`, `y` + -- and `screen` have to be modified. + d:geometry { + x = x, + y = y, + width = memento.width, + height = memento.height, + } + return true end From 69f292a31f308a0d0908566a1bb00fa3d996432e Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 4 Feb 2017 23:11:12 -0500 Subject: [PATCH 13/13] doc: Add basic documentation for the custom rules properties. In the lack of a better documentation. --- lib/awful/rules.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index 85b5f80c1..e3e7f1bfc 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -1,6 +1,22 @@ --------------------------------------------------------------------------- --- Apply rules to clients at startup. -- +-- All existing `client` properties can be used in rules. It is also possible +-- to add random properties that will be later accessible as `c.property_name` +-- (where `c` is a valid client object) +-- +-- In addition to the existing properties, the following are supported: +-- +-- * placement +-- * honor_padding +-- * honor_workarea +-- * tag +-- * new_tag +-- * switchtotag +-- * focus +-- * titlebars_enabled +-- * callback +-- -- @author Julien Danjou <julien@danjou.info> -- @copyright 2009 Julien Danjou -- @module awful.rules