awful.screen: extract screen:get_next_in_direction() (#1597)

This extracts the code for finding the next screen
from focus_bydirection to a separate method on
the screen object.

The main reason was to use the finding code without
actually changing the screen focus but this should
incidentally make the code slightly easier to test
as well since both concerns can be tested in
isolation.

Signed-off-by: Christoph Mertz <chris@nimel.de>
This commit is contained in:
Christoph Mertz 2017-03-05 04:16:15 +01:00 committed by Emmanuel Lepage Vallée
parent 2b88c92d52
commit 9cb60b8130
3 changed files with 61 additions and 10 deletions

View File

@ -122,6 +122,28 @@ function screen.focus(_screen)
end end
end end
--- Get the next screen in a specific direction.
--
-- This gets the next screen relative to this one in
-- the specified direction.
--
-- @function screen:get_next_in_direction
-- @param self Screen.
-- @param dir The direction, can be either "up", "down", "left" or "right".
function screen.object.get_next_in_direction(self, dir)
local sel = get_screen(self)
if not sel then
return
end
local geomtbl = {}
for s in capi.screen do
geomtbl[s] = s.geometry
end
return grect.get_in_direction(dir, geomtbl, sel.geometry)
end
--- Move the focus to a screen in a specific direction. --- Move the focus to a screen in a specific direction.
-- --
-- This moves the mouse pointer to the last known position on the new screen, -- This moves the mouse pointer to the last known position on the new screen,
@ -131,15 +153,10 @@ end
-- @param _screen Screen. -- @param _screen Screen.
function screen.focus_bydirection(dir, _screen) function screen.focus_bydirection(dir, _screen)
local sel = get_screen(_screen or screen.focused()) local sel = get_screen(_screen or screen.focused())
if sel then local target = sel:get_next_in_direction(dir)
local geomtbl = {}
for s in capi.screen do
geomtbl[s] = s.geometry
end
local target = grect.get_in_direction(dir, geomtbl, sel.geometry)
if target then if target then
return screen.focus(target) return target:focus()
end
end end
end end

View File

@ -117,7 +117,7 @@ local function calculate_distance(dir, _gA, _gB)
gAx = _gA.x + _gA.width gAx = _gA.x + _gA.width
end end
return math.sqrt(math.pow(gBx - gAx, 2) + math.pow(gBy - gAy, 2)) return math.sqrt((gBx - gAx) ^ 2 + (gBy - gAy) ^ 2)
end end
--- Get the nearest rectangle in the given direction. Every rectangle is specified as a table --- Get the nearest rectangle in the given direction. Every rectangle is specified as a table

View File

@ -76,6 +76,40 @@ describe("awful.screen", function()
end) end)
end) end)
describe("get_next_in_direction", function()
before_each(function()
fake_screens = {
{ geometry = { x = 0, y = 0, width = 1, height = 1 }, index = 1 },
{ geometry = { x = 1, y = 0, width = 1, height = 1 }, index = 2 },
{ geometry = { x = 0, y = 1, width = 1, height = 1 }, index = 3 },
{ geometry = { x = 1, y = 1, width = 1, height = 1 }, index = 4 },
}
end)
it("gets screens to the left", function()
assert.is.equal(fake_screens[1], ascreen.object.get_next_in_direction(fake_screens[2], "left"))
end)
it("gets screens to the right", function()
assert.is.equal(fake_screens[2], ascreen.object.get_next_in_direction(fake_screens[1], "right"))
end)
it("gets screens to the top", function()
assert.is.equal(fake_screens[2], ascreen.object.get_next_in_direction(fake_screens[4], "up"))
end)
it("gets screens to the bottom", function()
assert.is.equal(fake_screens[4], ascreen.object.get_next_in_direction(fake_screens[2], "down"))
end)
it("gets no screens if none exist in the direction", function()
assert.is_nil(ascreen.object.get_next_in_direction(fake_screens[2], "up"))
assert.is_nil(ascreen.object.get_next_in_direction(fake_screens[4], "down"))
assert.is_nil(ascreen.object.get_next_in_direction(fake_screens[2], "right"))
assert.is_nil(ascreen.object.get_next_in_direction(fake_screens[1], "left"))
end)
end)
describe("no screens", function() describe("no screens", function()
before_each(function() before_each(function()
fake_screens = {} fake_screens = {}