focus: Allow empty screens to be selected

This commit is contained in:
Emmanuel Lepage Vallee 2015-03-14 23:17:18 -04:00
parent 7155d6c48c
commit 38d8824668
3 changed files with 85 additions and 59 deletions

View File

@ -102,4 +102,8 @@ The `collision.select_screen(idx)` function allow to select a screen and can be
assigned to shortcuts. assigned to shortcuts.
The `collision.highlight_cursor(timeout)` method will highlight the current mouse The `collision.highlight_cursor(timeout)` method will highlight the current mouse
cursor position. cursor position.
# Notes
Using the focus arrows to select empty screens only work in Awesome 3.5.7+

130
focus.lua
View File

@ -54,15 +54,20 @@ local function init()
wiboxes["center"].shape_bounding = img._native wiboxes["center"].shape_bounding = img._native
end end
local function emulate_client(screen)
return {is_screen = true, screen=screen, geometry=function() return capi.screen[screen].workarea end}
end
local function display_wiboxes(cltbl,geomtbl,float,swap,c) local function display_wiboxes(cltbl,geomtbl,float,swap,c)
if not wiboxes then if not wiboxes then
init() init()
end end
local fc = capi.client.focus or emulate_client(capi.mouse.screen)
for k,v in ipairs({"left","right","up","down","center"}) do for k,v in ipairs({"left","right","up","down","center"}) do
local next_clients = (float and swap) and c or cltbl[util.get_rectangle_in_direction(v , geomtbl, capi.client.focus:geometry())] local next_clients = (float and swap) and c or cltbl[util.get_rectangle_in_direction(v , geomtbl, fc:geometry())]
if next_clients or k==5 then if next_clients or k==5 then
local same, center = capi.client.focus == next_clients,k==5 local same, center = fc == next_clients,k==5
local geo = center and capi.client.focus:geometry() or next_clients:geometry() local geo = center and fc:geometry() or next_clients:geometry()
wiboxes[v].visible = true wiboxes[v].visible = true
wiboxes[v].x = (swap and float and (not center)) and (geo.x + (k>2 and (geo.width/2) or 0) + (k==2 and geo.width or 0) - 75/2) or (geo.x + geo.width/2 - 75/2) wiboxes[v].x = (swap and float and (not center)) and (geo.x + (k>2 and (geo.width/2) or 0) + (k==2 and geo.width or 0) - 75/2) or (geo.x + geo.width/2 - 75/2)
wiboxes[v].y = (swap and float and (not center)) and (geo.y + (k<=2 and geo.height/2 or 0) + (k==4 and geo.height or 0) - 75/2) or (geo.y + geo.height/2 - 75/2) wiboxes[v].y = (swap and float and (not center)) and (geo.y + (k<=2 and geo.height/2 or 0) + (k==4 and geo.height or 0) - 75/2) or (geo.y + geo.height/2 - 75/2)
@ -91,61 +96,86 @@ local function floating_clients()
end end
local function bydirection(dir, c, swap,max) local function bydirection(dir, c, swap,max)
if c then if not c then
local float = client.floating.get(c) or alayout.get(c.screen) == alayout.suit.floating c = emulate_client(capi.mouse.screen)
-- Move the client if floating, swaping wont work anyway end
if swap and float then
c:geometry((max and float_move_max or float_move)(dir,c)) local float = nil
display_wiboxes(nil,nil,float,swap,c)
else if c.is_screen then
-- Get all clients rectangle float = false
local cltbl,geomtbl = max and floating_clients() or client.tiled(),{} else
for i,cl in ipairs(cltbl) do float = (client.floating.get(c) or alayout.get(c.screen) == alayout.suit.floating)
geomtbl[i] = cl:geometry() end
-- Move the client if floating, swaping wont work anyway
if swap and float then
c:geometry((max and float_move_max or float_move)(dir,c))
display_wiboxes(nil,nil,float,swap,c)
else
-- Get all clients rectangle
local cltbl,geomtbl,scrs = max and floating_clients() or client.tiled(),{},{}
for i,cl in ipairs(cltbl) do
geomtbl[i] = cl:geometry()
scrs[cl.screen or 1] = true
end
-- Add rectangles for empty screens too
for i = 1, capi.screen.count() do
if not scrs[i] then
geomtbl[#geomtbl+1] = capi.screen[i].workarea
cltbl[#geomtbl] = emulate_client(i)
end end
local target = util.get_rectangle_in_direction(dir, geomtbl, c:geometry()) end
if swap ~= true then
-- If we found a client to focus, then do it. local target = util.get_rectangle_in_direction(dir, geomtbl, c:geometry())
if target then if swap ~= true then
capi.client.focus = cltbl[((not cltbl[target] and #cltbl == 1) and 1 or target)] -- If we found a client to focus, then do it.
if target then
local cl = cltbl[target]
if cl and cl.is_screen then
capi.client.focus = nil --TODO Fix upstream fix
capi.mouse.screen = capi.screen[cl.screen]
else
capi.client.focus = cltbl[((not cl and #cltbl == 1) and 1 or target)]
capi.client.focus:raise() capi.client.focus:raise()
end end
else end
if target then else
-- We found a client to swap if target then
local other = cltbl[((not cltbl[target] and #cltbl == 1) and 1 or target)] -- We found a client to swap
if other.screen == c.screen or col_utils.settings.swap_across_screen then local other = cltbl[((not cltbl[target] and #cltbl == 1) and 1 or target)]
--BUG swap doesn't work if the screen is not the same if other.screen == c.screen or col_utils.settings.swap_across_screen then
c:swap(other) --BUG swap doesn't work if the screen is not the same
else c:swap(other)
local t = tag.selected(other.screen) --TODO get index
c.screen = other.screen
c:tags({t})
end
else else
-- No client to swap, try to find a screen. local t = tag.selected(other.screen) --TODO get index
local screen_geom = {} c.screen = other.screen
for i = 1, capi.screen.count() do c:tags({t})
screen_geom[i] = capi.screen[i].workarea
end
target = util.get_rectangle_in_direction(dir, screen_geom, c:geometry())
if target and target ~= c.screen then
local t = tag.selected(target)
c.screen = target
c:tags({t})
c:raise()
end
end end
if target then else
-- Geometries have changed by swapping, so refresh. -- No client to swap, try to find a screen.
cltbl,geomtbl = max and floating_clients() or client.tiled(),{} local screen_geom = {}
for i,cl in ipairs(cltbl) do for i = 1, capi.screen.count() do
geomtbl[i] = cl:geometry() screen_geom[i] = capi.screen[i].workarea
end end
target = util.get_rectangle_in_direction(dir, screen_geom, c:geometry())
if target and target ~= c.screen then
local t = tag.selected(target)
c.screen = target
c:tags({t})
c:raise()
end
end
if target then
-- Geometries have changed by swapping, so refresh.
cltbl,geomtbl = max and floating_clients() or client.tiled(),{}
for i,cl in ipairs(cltbl) do
geomtbl[i] = cl:geometry()
end end
end end
display_wiboxes(cltbl,geomtbl,float,swap,c)
end end
display_wiboxes(cltbl,geomtbl,float,swap,c)
end end
end end

View File

@ -171,7 +171,6 @@ function module.mouse_resize(c,corner)
if c.apply_size_hints then if c.apply_size_hints then
local w,h = c:apply_size_hints(new.width,new.height) local w,h = c:apply_size_hints(new.width,new.height)
new.x,new.y,new.width,new.height = new.x - (w-new.width),new.y - (h-new.height),w,h new.x,new.y,new.width,new.height = new.x - (w-new.width),new.y - (h-new.height),w,h
print("AAA",w,h,new.width,new.height,new.x)
end end
c:geometry(new) c:geometry(new)
@ -180,13 +179,6 @@ function module.mouse_resize(c,corner)
end,"fleur") end,"fleur")
end end
-- awful.mouse.client._resize = awful.mouse.client.resize
-- awful.mouse.client.resize = function(c,...)
-- module.display(c)
-- auto_hide = true
-- awful.mouse.client._resize(c,...)
-- module.hide()
-- end
return module return module
-- kate: space-indent on; indent-width 2; replace-tabs on; -- kate: space-indent on; indent-width 2; replace-tabs on;