Relocate a client window as if it is undecorated when reparenting it back. It eliminates the position offset due to re-decorating when a client trys to restore its previous position. (#3253)
Add tests for geometry changes when managing/unmanaging clients. Also verified that it fixed issue #2308.
This commit is contained in:
parent
cd4008c249
commit
ab6f7e03ca
|
@ -111,8 +111,9 @@ awesome_atexit(bool restart)
|
|||
/* Move clients where we want them to be and keep the stacking order intact */
|
||||
foreach(c, globalconf.stack)
|
||||
{
|
||||
area_t geometry = client_get_undecorated_geometry(*c);
|
||||
xcb_reparent_window(globalconf.connection, (*c)->window, globalconf.screen->root,
|
||||
(*c)->geometry.x, (*c)->geometry.y);
|
||||
geometry.x, geometry.y);
|
||||
}
|
||||
|
||||
/* Save the client order. This is useful also for "hard" restarts. */
|
||||
|
|
|
@ -2267,6 +2267,27 @@ client_add_titlebar_geometry(client_t *c, area_t *geometry)
|
|||
geometry->height += c->titlebar[CLIENT_TITLEBAR_BOTTOM].size;
|
||||
}
|
||||
|
||||
area_t
|
||||
client_get_undecorated_geometry(client_t *c)
|
||||
{
|
||||
area_t geometry = c->geometry;
|
||||
if (!c->fullscreen) {
|
||||
int diff_left = c->titlebar[CLIENT_TITLEBAR_LEFT].size;
|
||||
int diff_right = c->titlebar[CLIENT_TITLEBAR_RIGHT].size;
|
||||
int diff_top = c->titlebar[CLIENT_TITLEBAR_TOP].size;
|
||||
int diff_bottom = c->titlebar[CLIENT_TITLEBAR_BOTTOM].size;
|
||||
geometry.width -= diff_left + diff_right;
|
||||
geometry.height -= diff_top + diff_bottom;
|
||||
if (c->size_hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) {
|
||||
xwindow_translate_for_gravity(c->size_hints.win_gravity,
|
||||
-diff_left - c->border_width, -diff_top - c->border_width,
|
||||
-diff_right - c->border_width, -diff_bottom - c->border_width,
|
||||
&geometry.x, &geometry.y);
|
||||
}
|
||||
}
|
||||
return geometry;
|
||||
}
|
||||
|
||||
/** Send a synthetic configure event to a window.
|
||||
*/
|
||||
void
|
||||
|
@ -2941,9 +2962,10 @@ client_unmanage(client_t *c, client_unmanage_t reason)
|
|||
|
||||
if(reason != CLIENT_UNMANAGE_DESTROYED)
|
||||
{
|
||||
area_t geometry = client_get_undecorated_geometry(c);
|
||||
xcb_unmap_window(globalconf.connection, c->window);
|
||||
xcb_reparent_window(globalconf.connection, c->window, globalconf.screen->root,
|
||||
c->geometry.x, c->geometry.y);
|
||||
geometry.x, geometry.y);
|
||||
}
|
||||
|
||||
if (c->nofocus_window != XCB_NONE)
|
||||
|
|
|
@ -256,6 +256,7 @@ void client_emit_scanned(void);
|
|||
void client_emit_scanning(void);
|
||||
drawable_t *client_get_drawable(client_t *, int, int);
|
||||
drawable_t *client_get_drawable_offset(client_t *, int *, int *);
|
||||
area_t client_get_undecorated_geometry(client_t *);
|
||||
|
||||
/** Put client on top of the stack.
|
||||
* \param c The client to raise.
|
||||
|
|
|
@ -6,9 +6,13 @@ local wibox = require( "wibox" )
|
|||
local beautiful = require( "beautiful" )
|
||||
local cruled = require("ruled.client")
|
||||
local gdebug = require("gears.debug")
|
||||
local test_client = require("_client")
|
||||
local lgi = require("lgi")
|
||||
local gears = require("gears")
|
||||
|
||||
local w = nil
|
||||
local w1_draw, w2_draw
|
||||
local windowid
|
||||
|
||||
-- Replacing the rules is not supported anymore.
|
||||
local dep = gdebug.deprecate
|
||||
|
@ -257,6 +261,113 @@ local steps = {
|
|||
end
|
||||
}
|
||||
|
||||
runner.run_steps(steps)
|
||||
-- Tests for unmanaged client geometries with different gravity settings.
|
||||
local test_data = {
|
||||
-- gravity => expectation of unmanaged x, y, w, h.
|
||||
["NORTH_WEST"] = {0, 0, 100, 80},
|
||||
["NORTH"] = {10, 0, 100, 80},
|
||||
["NORTH_EAST"] = {20, 0, 100, 80},
|
||||
["WEST"] = {0, 20, 100, 80},
|
||||
["CENTER"] = {10, 20, 100, 80},
|
||||
["EAST"] = {20, 20, 100, 80},
|
||||
["SOUTH_WEST"] = {0, 40, 100, 80},
|
||||
["SOUTH"] = {10, 40, 100, 80},
|
||||
["SOUTH_EAST"] = {20, 40, 100, 80},
|
||||
["STATIC"] = {10, 30, 100, 80}
|
||||
}
|
||||
for gravity, expectation in pairs(test_data) do
|
||||
gears.table.merge(steps, {
|
||||
function()
|
||||
set_rules { }
|
||||
-- Wait for the previous cleanup to be done
|
||||
if #client.get() == 0 then
|
||||
return true
|
||||
end
|
||||
end,
|
||||
function(count)
|
||||
if count == 1 then
|
||||
print("testing gravity " .. gravity)
|
||||
test_client(nil,nil,nil,nil,nil,{gravity=lgi.Gdk.Gravity[gravity]})
|
||||
else
|
||||
local c = client.get()[1]
|
||||
if c then
|
||||
assert(c.size_hints.win_gravity == gravity:lower())
|
||||
c.border_width = 10
|
||||
c:titlebar_top(20)
|
||||
c:geometry({
|
||||
x = 0,
|
||||
y = 0,
|
||||
width = 100,
|
||||
height = 100
|
||||
})
|
||||
windowid = c.window
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
-- For some reason unmanage needs to happen in a separate step to pass the tests..
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
c:unmanage()
|
||||
awesome.sync()
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local display = lgi.Gdk.Display.open(os.getenv("DISPLAY"))
|
||||
local window = lgi.GdkX11.X11Window.foreign_new_for_display(display, windowid)
|
||||
local x, y, width, height = window:get_geometry()
|
||||
print(gravity, x, y, width, height)
|
||||
assert(x == expectation[1])
|
||||
assert(y == expectation[2])
|
||||
assert(width == expectation[3])
|
||||
assert(height == expectation[4])
|
||||
window:destroy()
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local display = lgi.Gdk.Display.open(os.getenv("DISPLAY"))
|
||||
local window = lgi.GdkX11.X11Window.foreign_new_for_display(display, windowid)
|
||||
if window then return end
|
||||
return true
|
||||
end,
|
||||
-- Additionally, checks our expectations are correct by adding decoration back.
|
||||
function(count)
|
||||
if count == 1 then
|
||||
test_client(nil,nil,nil,nil,nil,{gravity=lgi.Gdk.Gravity[gravity]})
|
||||
else
|
||||
local c = client.get()[1]
|
||||
if c then
|
||||
assert(c.size_hints.win_gravity == gravity:lower())
|
||||
c.border_width = 0
|
||||
c:titlebar_top(0)
|
||||
c:geometry({
|
||||
x = expectation[1],
|
||||
y = expectation[2],
|
||||
width = expectation[3],
|
||||
height = expectation[4]
|
||||
})
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
c:titlebar_top(20)
|
||||
c.border_width = 10
|
||||
return true
|
||||
end,
|
||||
function()
|
||||
local c = client.get()[1]
|
||||
assert(c.border_width == 10 )
|
||||
assert(c:geometry().x == 0 )
|
||||
assert(c:geometry().y == 0 )
|
||||
assert(c:geometry().height == 100 )
|
||||
assert(c:geometry().width == 100 )
|
||||
c:kill()
|
||||
return true
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
runner.run_steps(steps)
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
Loading…
Reference in New Issue