From 0e3979b8e46f2d1531abdf404ca5dffc54631278 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 12 Sep 2018 08:15:38 +0300 Subject: [PATCH 1/5] tests: Fix resize width/height mixup in the test client Signed-off-by: Sergey Vlasov --- tests/_client.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/_client.lua b/tests/_client.lua index c88dd160..7bbfb310 100644 --- a/tests/_client.lua +++ b/tests/_client.lua @@ -145,9 +145,9 @@ return function(class, title, sn_rules, callback, resize_increment, args) options = table.concat { options, "resize_after_width=", - args.resize.height, ",", + args.resize.width, ",", "resize_after_height=", - args.resize.width, "," + args.resize.height, "," } end if args.gravity then From 7f11bc11081e2e26ece725774a1563769e79a7d2 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 12 Sep 2018 08:20:53 +0300 Subject: [PATCH 2/5] tests: Add initial size support to the test client Signed-off-by: Sergey Vlasov --- tests/_client.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/_client.lua b/tests/_client.lua index 7bbfb310..349a0070 100644 --- a/tests/_client.lua +++ b/tests/_client.lua @@ -12,8 +12,8 @@ Gtk.init() local function open_window(class, title, options) local window = Gtk.Window { - default_width = 100, - default_height = 100, + default_width = options.default_width or 100, + default_height = options.default_height or 100, title = title } if options.gravity then @@ -141,6 +141,15 @@ return function(class, title, sn_rules, callback, resize_increment, args) if args.maximize_after then options = options .. "maximize_after," end + if args.size then + options = table.concat { + options, + "default_width=", + args.size.width, ",", + "default_height=", + args.size.height, "," + } + end if args.resize then options = table.concat { options, From db11c7e9dabc8edb4f59fdac25978883afad3be9 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 12 Sep 2018 10:46:21 +0300 Subject: [PATCH 3/5] awful.placement: Fix client size corruption in no_overlap The awful.placement.no_overlap function was adding the window border width to the client width and height (this is performed in area_common(), which is called by geometry_common()), but did not reverse this operation by calling remove_border() before returning the final geometry; because of this, using no_overlap resulted in increasing the window width and height by 2*border_width. The bug was probably introduced in commit ebcc19844e25705270 (before that commit no_overlap changed the window position directly instead of relying on the new placement infrastructure), but was not noticed because of other problems (e.g., in the default configuration the result of no_overlap was overridden by the buggy no_offscreen). Signed-off-by: Sergey Vlasov --- lib/awful/placement.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index 41334bc4..d516195d 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -941,6 +941,7 @@ function placement.no_overlap(c, args) new.width = geometry.width new.height = geometry.height + remove_border(c, args, new) geometry_common(c, args, new) return fix_new_geometry(new, args, true) end From 61cdc405959ed738648a26459a5d0297c37b3432 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 12 Sep 2018 10:30:17 +0300 Subject: [PATCH 4/5] awful.placement: Fix no_offscreen when composed with other functions The awful.placement.no_offscreen function did not work properly when composed with other placement functions; in particular, the default configuration (awful.placement.no_overlap+awful.placement.no_offscreen) was broken. The compose function sets args.pretend=true and puts the result of the previous placement function into args.override_geometry before calling the next placement function, but no_offscreen did not use args.override_geometry, therefore the result of the previous placement function was discarded. All other placement functions use `geometry_common(c, args)` to get the current client geometry; `area_common(c)` should be used only when getting geometry of other clients. This change also fixes the problem with margin handling (adding margins should not affect the window size, only the window position should change); the test output which was adjusted in commit 0275d3537d05b66b9f is adjusted again to account for this change. Signed-off-by: Sergey Vlasov --- lib/awful/placement.lua | 2 +- tests/examples/awful/placement/no_offscreen.output.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua index d516195d..3cc2ceb0 100644 --- a/lib/awful/placement.lua +++ b/lib/awful/placement.lua @@ -851,7 +851,7 @@ function placement.no_offscreen(c, args) c = c or capi.client.focus args = add_context(args, "no_offscreen") - local geometry = area_common(c) + local geometry = geometry_common(c, args) local screen = get_screen(args.screen or c.screen or a_screen.getbycoord(geometry.x, geometry.y)) local screen_geometry = screen.workarea diff --git a/tests/examples/awful/placement/no_offscreen.output.txt b/tests/examples/awful/placement/no_offscreen.output.txt index 2bd013d5..3c3ea651 100644 --- a/tests/examples/awful/placement/no_offscreen.output.txt +++ b/tests/examples/awful/placement/no_offscreen.output.txt @@ -1,2 +1,2 @@ Before: x=-30, y=-30, width=100, height=100 -After: x=50, y=50, width=20, height=20 +After: x=50, y=50, width=100, height=100 From 16b5803fda7d81f472dec6b946f4e96960b5a4d5 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 12 Sep 2018 10:24:53 +0300 Subject: [PATCH 5/5] Add a test for awful.placement.no_overlap+awful.placement.no_offscreen Test that the placement function used in the default configuration behaves as intended. This test was failing before the no_overlap and no_offscreen fixes in two previous commits. Signed-off-by: Sergey Vlasov --- tests/test-awful-placement.lua | 170 +++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 tests/test-awful-placement.lua diff --git a/tests/test-awful-placement.lua b/tests/test-awful-placement.lua new file mode 100644 index 00000000..be1a49c2 --- /dev/null +++ b/tests/test-awful-placement.lua @@ -0,0 +1,170 @@ +local awful = require("awful") +local gears = require("gears") +local beautiful = require("beautiful") +local test_client = require("_client") +local runner = require("_runner") + +-- This test makes some assumptions about the no_overlap behavior which may not +-- be correct if the screen is in the portrait orientation. +if mouse.screen.workarea.height >= mouse.screen.workarea.width then + print("This test does not work with the portrait screen orientation.") + runner.run_steps { function() return true end } + return +end + +local tests = {} + +local tb_height = gears.math.round(beautiful.get_font_height() * 1.5) +local border_width = beautiful.border_width + +local class = "test-awful-placement" +local rule = { + rule = { + class = class + }, + properties = { + floating = true, + placement = awful.placement.no_overlap + awful.placement.no_offscreen + } +} +table.insert(awful.rules.rules, rule) + +local function check_geometry(c, x, y, width, height) + local g = c:geometry() + if g.x ~= x or g.y ~= y or g.width ~= width or g.height ~= height then + assert(false, string.format("(%d, %d, %d, %d) ~= (%d, %d, %d, %d)", + g.x, g.y, g.width, g.height, x, y, width, height)) + end +end + +local function default_test(c, geometry) + check_geometry(c, geometry.expected_x, geometry.expected_y, + geometry.expected_width or geometry.width, + geometry.expected_height or (geometry.height + tb_height)) + return true +end + +local client_count = 0 +local client_data = {} +local function add_client(args) + client_count = client_count + 1 + local client_index = client_count + table.insert(tests, function(count) + local name = string.format("client%010d", client_index) + if count <= 1 then + local geometry = args.geometry(mouse.screen.workarea) + test_client(class, name, nil, nil, nil, { + size = { + width = geometry.width, + height = geometry.height + } + }) + client_data[client_index] = { geometry = geometry } + return nil + elseif #client.get() >= client_index then + local data = client_data[client_index] + local c = data.c + if not c then + c = client.get()[1] + assert(c.name == name) + data.c = c + end + local test = args.test or default_test + return test(c, data.geometry) + end + end) +end + +-- The first 100x100 window should be placed at the top left corner. +add_client { + geometry = function(wa) + return { + width = 100, + height = 100, + expected_x = wa.x, + expected_y = wa.y + } + end +} + +-- The second 100x100 window should be placed to the right of the first window. +-- Note that this assumption fails if the screen is in the portrait orientation +-- (e.g., the test succeeds with a 600x703 screen and fails with 600x704). +add_client { + geometry = function(wa) + return { + width = 100, + height = 100, + expected_x = wa.x + 100 + 2*border_width, + expected_y = wa.y + } + end +} + +-- The wide window should be placed below the two 100x100 windows. +add_client { + geometry = function(wa) + return { + width = wa.width - 50, + height = 100, + expected_x = wa.x, + expected_y = wa.y + tb_height + 2*border_width + 100 + } + end +} + +-- The first large window which does not completely fit in any free area should +-- be placed at the bottom left corner (no_overlap should place it below the +-- wide window, and then no_offscreen should shift it up so that it would be +-- completely inside the workarea). +add_client { + geometry = function(wa) + return { + width = wa.width - 10, + height = wa.height - 50, + expected_x = wa.x, + expected_y = wa.y + 50 - 2*border_width - tb_height + } + end +} + +-- The second large window should be placed at the top right corner. +add_client { + geometry = function(wa) + return { + width = wa.width - 10, + height = wa.height - 50, + expected_x = wa.x + 10 - 2*border_width, + expected_y = wa.y + } + end +} + +-- The third large window should be placed at the bottom right corner. +add_client { + geometry = function(wa) + return { + width = wa.width - 10, + height = wa.height - 50, + expected_x = wa.x + 10 - 2*border_width, + expected_y = wa.y + 50 - 2*border_width - tb_height + } + end +} + +-- The fourth large window should be placed at the top left corner (the whole +-- workarea is occupied now). +add_client { + geometry = function(wa) + return { + width = wa.width - 50, + height = wa.height - 50, + expected_x = wa.x, + expected_y = wa.y + } + end +} + +runner.run_steps(tests) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80