Merge pull request #1748 from Elv13/fix_maximize_again
Fix maximize again
This commit is contained in:
commit
b98ca2ec98
32
event.c
32
event.c
|
@ -341,6 +341,8 @@ event_handle_configurerequest(xcb_configure_request_event_t *ev)
|
|||
uint16_t deco_bottom = bw + tb_bottom;
|
||||
int16_t diff_w = 0, diff_h = 0, diff_border = 0;
|
||||
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
|
||||
if(ev->value_mask & XCB_CONFIG_WINDOW_X)
|
||||
{
|
||||
int16_t diff = 0;
|
||||
|
@ -373,8 +375,6 @@ event_handle_configurerequest(xcb_configure_request_event_t *ev)
|
|||
}
|
||||
if(ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
|
||||
{
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
|
||||
diff_border = ev->border_width - bw;
|
||||
diff_h += diff_border;
|
||||
diff_w += diff_border;
|
||||
|
@ -396,7 +396,33 @@ event_handle_configurerequest(xcb_configure_request_event_t *ev)
|
|||
}
|
||||
|
||||
c->got_configure_request = true;
|
||||
client_resize(c, geometry, false);
|
||||
|
||||
/* Request the changes to be applied */
|
||||
luaA_object_push(L, c);
|
||||
lua_pushstring(L, "ewmh"); /* context */
|
||||
lua_newtable(L); /* props */
|
||||
|
||||
/* area, it needs to be directly in the `hints` table to comply with
|
||||
the "protocol"
|
||||
*/
|
||||
lua_pushstring(L, "x");
|
||||
lua_pushinteger(L, geometry.x);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
lua_pushstring(L, "y");
|
||||
lua_pushinteger(L, geometry.y);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
lua_pushstring(L, "width");
|
||||
lua_pushinteger(L, geometry.width);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
lua_pushstring(L, "height");
|
||||
lua_pushinteger(L, geometry.height);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
luaA_object_emit_signal(L, -3, "request::geometry", 2);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if (xembed_getbywin(&globalconf.embedded, ev->window))
|
||||
{
|
||||
|
|
63
ewmh.c
63
ewmh.c
|
@ -207,6 +207,28 @@ ewmh_init(void)
|
|||
father, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, &i);
|
||||
}
|
||||
|
||||
static void
|
||||
ewmh_update_maximize(bool h, bool status, bool toggle)
|
||||
{
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
|
||||
if (h)
|
||||
lua_pushstring(L, "client_maximize_horizontal");
|
||||
else
|
||||
lua_pushstring(L, "client_maximize_vertical");
|
||||
|
||||
/* Create table argument with raise=true. */
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "toggle");
|
||||
lua_pushboolean(L, toggle);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L, "status");
|
||||
lua_pushboolean(L, status);
|
||||
lua_settable(L, -3);
|
||||
|
||||
luaA_object_emit_signal(L, -3, "request::geometry", 2);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_init_lua(void)
|
||||
{
|
||||
|
@ -333,20 +355,20 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
|
|||
else if(state == _NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
{
|
||||
if(set == _NET_WM_STATE_REMOVE)
|
||||
client_set_maximized_horizontal(L, -1, false);
|
||||
ewmh_update_maximize(true, false, false);
|
||||
else if(set == _NET_WM_STATE_ADD)
|
||||
client_set_maximized_horizontal(L, -1, true);
|
||||
ewmh_update_maximize(true, true, false);
|
||||
else if(set == _NET_WM_STATE_TOGGLE)
|
||||
client_set_maximized_horizontal(L, -1, !c->maximized_horizontal);
|
||||
ewmh_update_maximize(true, false, true);
|
||||
}
|
||||
else if(state == _NET_WM_STATE_MAXIMIZED_VERT)
|
||||
{
|
||||
if(set == _NET_WM_STATE_REMOVE)
|
||||
client_set_maximized_vertical(L, -1, false);
|
||||
ewmh_update_maximize(false, false, false);
|
||||
else if(set == _NET_WM_STATE_ADD)
|
||||
client_set_maximized_vertical(L, -1, true);
|
||||
ewmh_update_maximize(false, true, false);
|
||||
else if(set == _NET_WM_STATE_TOGGLE)
|
||||
client_set_maximized_vertical(L, -1, !c->maximized_vertical);
|
||||
ewmh_update_maximize(false, false, true);
|
||||
}
|
||||
else if(state == _NET_WM_STATE_ABOVE)
|
||||
{
|
||||
|
@ -554,6 +576,8 @@ ewmh_client_check_hints(client_t *c)
|
|||
void *data = NULL;
|
||||
xcb_get_property_cookie_t c0, c1, c2;
|
||||
xcb_get_property_reply_t *reply;
|
||||
bool is_h_max = false;
|
||||
bool is_v_max = false;
|
||||
|
||||
/* Send the GetProperty requests which will be processed later */
|
||||
c0 = xcb_get_property_unchecked(globalconf.connection, false, c->window,
|
||||
|
@ -578,9 +602,36 @@ ewmh_client_check_hints(client_t *c)
|
|||
{
|
||||
state = (xcb_atom_t *) data;
|
||||
for(int i = 0; i < xcb_get_property_value_length(reply) / ssizeof(xcb_atom_t); i++)
|
||||
if (state[i] == _NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
is_h_max = true;
|
||||
else if (state[i] == _NET_WM_STATE_MAXIMIZED_VERT)
|
||||
is_v_max = true;
|
||||
else
|
||||
ewmh_process_state_atom(c, state[i], _NET_WM_STATE_ADD);
|
||||
}
|
||||
|
||||
/* Check maximization manually */
|
||||
if (is_h_max && is_v_max) {
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
luaA_object_push(L, c);
|
||||
client_set_maximized(L, -1, true);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if(is_h_max)
|
||||
{
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
luaA_object_push(L, c);
|
||||
client_set_maximized_horizontal(L, -1, true);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if(is_v_max)
|
||||
{
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
luaA_object_push(L, c);
|
||||
client_set_maximized_vertical(L, -1, true);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
p_delete(&reply);
|
||||
|
||||
reply = xcb_get_property_reply(globalconf.connection, c2, NULL);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
local client = client
|
||||
local screen = screen
|
||||
local ipairs = ipairs
|
||||
local timer = require("gears.timer")
|
||||
local gtable = require("gears.table")
|
||||
local aclient = require("awful.client")
|
||||
local aplace = require("awful.placement")
|
||||
|
@ -302,10 +303,88 @@ function ewmh.geometry(c, context, hints)
|
|||
end
|
||||
end
|
||||
|
||||
--- Merge the 2 requests sent by clients wanting to be maximized.
|
||||
--
|
||||
-- The X clients set 2 flags (atoms) when they want to be maximized. This caused
|
||||
-- 2 request::geometry to be sent. This code gives some time for them to arrive
|
||||
-- and send a new `request::geometry` (through the property change) with the
|
||||
-- combined state.
|
||||
--
|
||||
-- @signalhandler awful.ewmh.merge_maximization
|
||||
-- @tparam client c The client
|
||||
-- @tparam string context The context
|
||||
-- @tparam[opt={}] table hints The hints to pass to the handler
|
||||
function ewmh.merge_maximization(c, context, hints)
|
||||
if context ~= "client_maximize_horizontal" and context ~= "client_maximize_vertical" then
|
||||
return
|
||||
end
|
||||
|
||||
if not c._delay_maximization then
|
||||
c._delay_maximization = function()
|
||||
-- This ignores unlikely corner cases like mismatching toggles.
|
||||
-- That's likely to be an accident anyway.
|
||||
if c._delayed_max_h and c._delayed_max_v then
|
||||
c.maximized = c._delayed_max_h or c._delayed_max_v
|
||||
elseif c._delayed_max_h then
|
||||
c.maximized_horizontal = c._delayed_max_h
|
||||
elseif c._delayed_max_v then
|
||||
c.maximized_vertical = c._delayed_max_v
|
||||
end
|
||||
end
|
||||
|
||||
timer {
|
||||
timeout = 1/60,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
if not c.valid then return end
|
||||
|
||||
c._delay_maximization(c)
|
||||
c._delay_maximization = nil
|
||||
c._delayed_max_h = nil
|
||||
c._delayed_max_v = nil
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function get_value(suffix, long_suffix)
|
||||
if hints.toggle and c["_delayed_max_"..suffix] ~= nil then
|
||||
return not c["_delayed_max_"..suffix]
|
||||
elseif hints.toggle then
|
||||
return not c["maximized_"..long_suffix]
|
||||
else
|
||||
return hints.status
|
||||
end
|
||||
end
|
||||
|
||||
if context == "client_maximize_horizontal" then
|
||||
c._delayed_max_h = get_value("h", "horizontal")
|
||||
elseif context == "client_maximize_vertical" then
|
||||
c._delayed_max_v = get_value("v", "vertical")
|
||||
end
|
||||
end
|
||||
|
||||
--- Allow the client to move itself.
|
||||
--
|
||||
-- This is the default geometry request handler when the context is `ewmh`.
|
||||
--
|
||||
-- @signalhandler awful.ewmh.client_geometry_requests
|
||||
-- @tparam client c The client
|
||||
-- @tparam string context The context
|
||||
-- @tparam[opt={}] table hints The hints to pass to the handler
|
||||
function ewmh.client_geometry_requests(c, context, hints)
|
||||
if context == "ewmh" and hints then
|
||||
c:geometry(hints)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
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("request::geometry", ewmh.merge_maximization)
|
||||
client.connect_signal("request::geometry", ewmh.client_geometry_requests)
|
||||
client.connect_signal("property::border_width", repair_geometry)
|
||||
client.connect_signal("property::screen", repair_geometry)
|
||||
screen.connect_signal("property::workarea", function(s)
|
||||
|
|
|
@ -32,8 +32,19 @@ local function open_window(class, title, options)
|
|||
}
|
||||
window:set_geometry_hints(nil, geom, Gdk.WindowHints.RESIZE_INC)
|
||||
end
|
||||
if options.maximize_before then
|
||||
window:maximize()
|
||||
end
|
||||
window:set_wmclass(class, class)
|
||||
window:show_all()
|
||||
if options.maximize_after then
|
||||
window:maximize()
|
||||
end
|
||||
if options.resize_after_width and options.resize_after_height then
|
||||
window:resize(
|
||||
tonumber(options.resize_after_width), tonumber(options.resize_after_height)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_options(options)
|
||||
|
@ -124,10 +135,26 @@ return function(class, title, sn_rules, callback, resize_increment, args)
|
|||
if resize_increment then
|
||||
options = options .. "resize_increment,"
|
||||
end
|
||||
if args.maximize_before then
|
||||
options = options .. "maximize_before,"
|
||||
end
|
||||
if args.maximize_after then
|
||||
options = options .. "maximize_after,"
|
||||
end
|
||||
if args.resize then
|
||||
options = table.concat {
|
||||
options,
|
||||
"resize_after_width=",
|
||||
args.resize.height, ",",
|
||||
"resize_after_height=",
|
||||
args.resize.width, ","
|
||||
}
|
||||
end
|
||||
if args.gravity then
|
||||
assert(type(args.gravity)=="number","Use `lgi.Gdk.Gravity.NORTH_WEST`")
|
||||
options = options .. "gravity=" .. args.gravity .. ","
|
||||
end
|
||||
|
||||
local data = class .. "\n" .. title .. "\n" .. options .. "\n"
|
||||
local success, msg = pipe:write_all(data)
|
||||
assert(success, tostring(msg))
|
||||
|
|
|
@ -12,6 +12,17 @@ end
|
|||
|
||||
local original_geo = nil
|
||||
|
||||
local counter = 0
|
||||
|
||||
local function geometry_handler(c, context, hints)
|
||||
hints = hints or {}
|
||||
assert(type(c) == "client")
|
||||
assert(type(context) == "string")
|
||||
assert(type(hints.toggle) == "boolean")
|
||||
assert(type(hints.status) == "boolean")
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
local steps = {
|
||||
function(count)
|
||||
if count == 1 then
|
||||
|
@ -142,6 +153,92 @@ local steps = {
|
|||
assert(geo_to_str(original_geo) == geo_to_str(new_geo),
|
||||
geo_to_str(original_geo) .. " == " .. geo_to_str(new_geo))
|
||||
|
||||
c:kill()
|
||||
|
||||
return true
|
||||
end,
|
||||
-- Now, start some clients maximized
|
||||
function()
|
||||
if #client.get() > 0 then return end
|
||||
|
||||
test_client(nil,nil,nil,nil,nil,{maximize_before=true})
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
|
||||
if not c then return end
|
||||
|
||||
assert(not c.maximized_horizontal)
|
||||
assert(not c.maximized_vertical)
|
||||
assert(c.maximized)
|
||||
|
||||
c:kill()
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
if #client.get() > 0 then return end
|
||||
|
||||
test_client(nil,nil,nil,nil,nil,{maximize_after=true})
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
|
||||
if not c then return end
|
||||
|
||||
assert(not c.maximized_horizontal)
|
||||
assert(not c.maximized_vertical)
|
||||
|
||||
-- It might happen in the second try
|
||||
if not c.maximized then return end
|
||||
|
||||
c:kill()
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
if #client.get() > 0 then return end
|
||||
|
||||
-- Test if resizing requests work
|
||||
test_client(nil,nil,nil,nil,nil,{resize={width=400, height=400}})
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
if #client.get() ~= 1 then return end
|
||||
|
||||
local c = client.get()[1]
|
||||
local _, size = c:titlebar_top()
|
||||
|
||||
if c.width ~= 400 or c.height ~= 400+size then return end
|
||||
|
||||
c:kill()
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
if #client.get() > 0 then return end
|
||||
|
||||
-- Remove the default handler and replace it with a testing one.
|
||||
-- **WARNING**: add tests **BEFORE** this function if you want them
|
||||
-- to be relevant.
|
||||
client.disconnect_signal("request::geometry", awful.ewmh.geometry)
|
||||
client.disconnect_signal("request::geometry", awful.ewmh.merge_maximization)
|
||||
client.connect_signal("request::geometry", geometry_handler)
|
||||
|
||||
test_client(nil,nil,nil,nil,nil,{maximize_after=true})
|
||||
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
|
||||
if not c or counter ~= 2 then return end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue