Added function to change screen focus by direction
The function awful.screen.focus_bydirection changes the screen focus according to physical position. The code is based on awful.client.focus.bydirection. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
5701c473d4
commit
d799ac76aa
|
@ -47,6 +47,23 @@ function screen.focus(_screen)
|
||||||
capi.mouse.screen = _screen
|
capi.mouse.screen = _screen
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Give the focus to a screen, and move pointer, by physical position relative to current screen.
|
||||||
|
-- @param dir The direction, can be either "up", "down", "left" or "right".
|
||||||
|
-- @param screen Screen number.
|
||||||
|
function screen.focus_bydirection(dir, _screen)
|
||||||
|
local sel = _screen or capi.mouse.screen
|
||||||
|
if sel then
|
||||||
|
local geomtbl = {}
|
||||||
|
for s = 1, capi.screen.count() do
|
||||||
|
geomtbl[s] = capi.screen[s].geometry
|
||||||
|
end
|
||||||
|
local target = util.get_rectangle_in_direction(dir, geomtbl, capi.screen[sel].geometry)
|
||||||
|
if target then
|
||||||
|
return screen.focus(target)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Give the focus to a screen, and move pointer, but relative to the current
|
--- Give the focus to a screen, and move pointer, but relative to the current
|
||||||
-- focused screen.
|
-- focused screen.
|
||||||
-- @param i Value to add to the current focused screen index. 1 will focus next
|
-- @param i Value to add to the current focused screen index. 1 will focus next
|
||||||
|
|
|
@ -198,9 +198,9 @@ function util.geticonpath(iconname, exts, dirs, size)
|
||||||
icon = d .. iconname .. '.' .. e
|
icon = d .. iconname .. '.' .. e
|
||||||
if util.file_readable(icon) then
|
if util.file_readable(icon) then
|
||||||
return icon
|
return icon
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if file exists and is readable.
|
--- Check if file exists and is readable.
|
||||||
|
@ -260,6 +260,76 @@ function util.subsets(set)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return true whether rectangle B is in the right direction
|
||||||
|
-- compared to rectangle A.
|
||||||
|
-- @param dir The direction.
|
||||||
|
-- @param gA The geometric specification for rectangle A.
|
||||||
|
-- @param gB The geometric specification for rectangle B.
|
||||||
|
-- @return True if B is in the direction of A.
|
||||||
|
local function is_in_direction(dir, gA, gB)
|
||||||
|
if dir == "up" then
|
||||||
|
return gA.y > gB.y
|
||||||
|
elseif dir == "down" then
|
||||||
|
return gA.y < gB.y
|
||||||
|
elseif dir == "left" then
|
||||||
|
return gA.x > gB.x
|
||||||
|
elseif dir == "right" then
|
||||||
|
return gA.x < gB.x
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Calculate distance between two points.
|
||||||
|
-- i.e: if we want to move to the right, we will take the right border
|
||||||
|
-- of the currently focused screen and the left side of the checked screen.
|
||||||
|
-- @param dir The direction.
|
||||||
|
-- @param gA The first rectangle.
|
||||||
|
-- @param gB The second rectangle.
|
||||||
|
-- @return The distance between the screens.
|
||||||
|
local function calculate_distance(dir, _gA, _gB)
|
||||||
|
local gA = _gA
|
||||||
|
local gB = _gB
|
||||||
|
|
||||||
|
if dir == "up" then
|
||||||
|
gB.y = gB.y + gB.height
|
||||||
|
elseif dir == "down" then
|
||||||
|
gA.y = gA.y + gA.height
|
||||||
|
elseif dir == "left" then
|
||||||
|
gB.x = gB.x + gB.width
|
||||||
|
elseif dir == "right" then
|
||||||
|
gA.x = gA.x + gA.width
|
||||||
|
end
|
||||||
|
|
||||||
|
return math.sqrt(math.pow(gB.x - gA.x, 2) + math.pow(gB.y - gA.y, 2))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get the nearest rectangle in the given direction. Every rectangle is specified as a table
|
||||||
|
-- with 'x', 'y', 'width', 'height' keys, the same as client or screen geometries.
|
||||||
|
-- @param dir The direction, can be either "up", "down", "left" or "right".
|
||||||
|
-- @param recttbl A table of rectangle specifications.
|
||||||
|
-- @param cur The current rectangle.
|
||||||
|
-- @return The index for the rectangle in recttbl closer to cur in the given direction. nil if none found.
|
||||||
|
function util.get_rectangle_in_direction(dir, recttbl, cur)
|
||||||
|
local dist, dist_min
|
||||||
|
local target = nil
|
||||||
|
|
||||||
|
-- We check each object
|
||||||
|
for i, rect in ipairs(recttbl) do
|
||||||
|
-- Check geometry to see if object is located in the right direction.
|
||||||
|
if is_in_direction(dir, cur, rect) then
|
||||||
|
-- Calculate distance between current and checked object.
|
||||||
|
dist = calculate_distance(dir, cur, rect)
|
||||||
|
|
||||||
|
-- If distance is shorter then keep the object.
|
||||||
|
if not target or dist < dist_min then
|
||||||
|
target = i
|
||||||
|
dist_min = dist
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return target
|
||||||
|
end
|
||||||
|
|
||||||
--- Join all tables given as parameters.
|
--- Join all tables given as parameters.
|
||||||
-- This will iterate all tables and insert all their keys into a new table.
|
-- This will iterate all tables and insert all their keys into a new table.
|
||||||
-- @param args A list of tables to join
|
-- @param args A list of tables to join
|
||||||
|
|
Loading…
Reference in New Issue