Track focus and cursor position when selecting screen
This commit is contained in:
parent
5956636d7e
commit
0366cd142f
|
@ -99,4 +99,7 @@ collision.settings.swap_across_screen = true
|
|||
# Other
|
||||
|
||||
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
|
||||
cursor position.
|
41
focus.lua
41
focus.lua
|
@ -17,44 +17,11 @@ local module = {}
|
|||
local wiboxes,delta = nil,100
|
||||
|
||||
---------------- Visual -----------------------
|
||||
local function gen(item_height)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, item_height,item_height)
|
||||
local cr = cairo.Context(img)
|
||||
local rad = 10
|
||||
cr:set_source_rgba(0,0,0,0)
|
||||
cr:paint()
|
||||
cr:set_source_rgba(1,1,1,1)
|
||||
cr:arc(rad,rad,rad,0,2*math.pi)
|
||||
cr:arc(item_height-rad,rad,rad,0,2*math.pi)
|
||||
cr:arc(rad,item_height-rad,rad,0,2*math.pi)
|
||||
cr:arc(item_height-rad,item_height-rad,rad,0,2*math.pi)
|
||||
cr:fill()
|
||||
cr:rectangle(0,rad, item_height, item_height-2*rad)
|
||||
cr:rectangle(rad,0, item_height-2*rad, item_height)
|
||||
cr:fill()
|
||||
return img._native
|
||||
end
|
||||
|
||||
local function constructor(width)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, width)
|
||||
local cr = cairo.Context(img)
|
||||
cr:move_to(0,0)
|
||||
cr:set_source(color(beautiful.fg_normal))
|
||||
cr:paint()
|
||||
cr:set_source(color(beautiful.bg_normal))
|
||||
cr:set_antialias(1)
|
||||
cr:rectangle(0, (width/2), 10, (width/2))
|
||||
cr:rectangle(width-10, (width/2), 10, (width/2))
|
||||
for i=0,(width/2) do
|
||||
cr:rectangle(i, 0, 1, (width/2)-i)
|
||||
cr:rectangle(width-i, 0, 1, (width/2)-i)
|
||||
end
|
||||
cr:fill()
|
||||
return cairo.Pattern.create_for_surface(img)
|
||||
end
|
||||
|
||||
local function init()
|
||||
local bounding,arrow = gen(75),constructor(55)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, 75, 75)
|
||||
local cr = cairo.Context(img)
|
||||
|
||||
local bounding,arrow = col_utils.draw_round_rect(cr,0,0,75,75,10),col_utils.arrow(55,color(beautiful.fg_normal),color(beautiful.bg_normal))
|
||||
wiboxes = {}
|
||||
for k,v in ipairs({"up","right","down","left","center"}) do
|
||||
wiboxes[v] = wibox({})
|
||||
|
|
17
init.lua
17
init.lua
|
@ -1,4 +1,4 @@
|
|||
local capi = {root=root,client=client,mouse=mouse,
|
||||
local capi = {root=root,client=client,mouse=mouse, timer=timer
|
||||
screen = screen, keygrabber = keygrabber}
|
||||
local util = require( "awful.util" )
|
||||
local awful = require( "awful" )
|
||||
|
@ -9,6 +9,7 @@ local module = {
|
|||
_resize = require( "collision.resize"),
|
||||
_max = require( "collision.max" ),
|
||||
_screen = require( "collision.screen"),
|
||||
_mouse = require( "collision.mouse" ),
|
||||
settings= col_utils.settings ,
|
||||
util = col_utils ,
|
||||
}
|
||||
|
@ -127,11 +128,23 @@ function module.screen(direction, move)
|
|||
end
|
||||
|
||||
function module.select_screen(idx)
|
||||
if idx and idx > 0 and idx < capi.screen.count() then
|
||||
if idx and idx > 0 and idx <= capi.screen.count() then
|
||||
module._screen.select_screen(idx)
|
||||
end
|
||||
end
|
||||
|
||||
function module.highlight_cursor(timeout)
|
||||
module._mouse.highlight()
|
||||
if timer then
|
||||
local timer = capi.timer({ timeout = timeout }) -- 30 mins
|
||||
timer:connect_signal("timeout", function()
|
||||
module._mouse.hide()
|
||||
timer:stop()
|
||||
end)
|
||||
timer:start()
|
||||
end
|
||||
end
|
||||
|
||||
local function new(k)
|
||||
-- Replace the keys array. The new one has to have a valid mapping
|
||||
keys = k or keys
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
local capi = {screen=screen,client=client,mouse=mouse, keygrabber = keygrabber}
|
||||
local math,table = math,table
|
||||
local wibox = require( "wibox" )
|
||||
local awful = require( "awful" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local color = require( "gears.color" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local surface = require( "gears.surface" )
|
||||
local col_utils = require( "collision.util" )
|
||||
|
||||
local module = {}
|
||||
|
||||
local w = nil
|
||||
|
||||
function module.highlight()
|
||||
if not w then
|
||||
w = wibox{}
|
||||
w.height = 100
|
||||
w.width = 100
|
||||
w.ontop = true
|
||||
|
||||
local img = cairo.ImageSurface(cairo.Format.A8, 100,100)
|
||||
local cr = cairo.Context(img)
|
||||
-- cr:set_operator(cairo.Operator.CLEAR)
|
||||
cr:set_source_rgba(0,0,0,0)
|
||||
cr:paint()
|
||||
cr:set_operator(cairo.Operator.SOURCE)
|
||||
cr:set_source_rgba(1,1,1,1)
|
||||
|
||||
cr:save()
|
||||
cr:translate(0,-30)
|
||||
cr:move_to(50,50)
|
||||
cr:rotate(math.pi)
|
||||
col_utils.arrow_path(cr,40)
|
||||
cr:fill()
|
||||
cr:restore()
|
||||
|
||||
cr:save()
|
||||
cr:translate(-30,0)
|
||||
cr:move_to(50,50)
|
||||
cr:rotate(math.pi/2)
|
||||
col_utils.arrow_path(cr,40)
|
||||
cr:fill()
|
||||
cr:restore()
|
||||
|
||||
cr:save()
|
||||
cr:translate(30,0)
|
||||
cr:move_to(50,50)
|
||||
cr:rotate(-math.pi/2)
|
||||
col_utils.arrow_path(cr,40)
|
||||
cr:fill()
|
||||
cr:restore()
|
||||
|
||||
cr:save()
|
||||
cr:translate(0,30)
|
||||
cr:move_to(50,50)
|
||||
col_utils.arrow_path(cr,40)
|
||||
cr:fill()
|
||||
cr:restore()
|
||||
|
||||
cr:arc(50,50,50,0,2*math.pi)
|
||||
cr:set_line_width(5)
|
||||
cr:stroke()
|
||||
|
||||
cr:set_source_rgba(1,0,0,1)
|
||||
w.shape_bounding = img._native
|
||||
|
||||
|
||||
img = cairo.ImageSurface(cairo.Format.ARGB32, 100,100)
|
||||
cr = cairo.Context(img)
|
||||
cr:set_source(color(beautiful.bg_urgent))
|
||||
cr:paint()
|
||||
cr:set_source(color(beautiful.fg_normal))
|
||||
cr:arc(50,50,50,0,2*math.pi)
|
||||
cr:set_line_width(5)
|
||||
cr:stroke()
|
||||
w:set_bg(cairo.Pattern.create_for_surface(img))
|
||||
end
|
||||
w.x = capi.mouse.coords().x -50
|
||||
w.y = capi.mouse.coords().y -50
|
||||
w.visible = true
|
||||
end
|
||||
|
||||
function module.hide()
|
||||
w.visible = false
|
||||
end
|
||||
|
||||
return module
|
83
screen.lua
83
screen.lua
|
@ -1,13 +1,14 @@
|
|||
local capi = {screen=screen,client=client,mouse=mouse, keygrabber = keygrabber}
|
||||
local math,table = math,table
|
||||
local wibox = require( "wibox" )
|
||||
local awful = require( "awful" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local color = require( "gears.color" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local surface = require( "gears.surface" )
|
||||
local pango = require( "lgi" ).Pango
|
||||
local pangocairo = require( "lgi" ).PangoCairo
|
||||
local wibox = require( "wibox" )
|
||||
local awful = require( "awful" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
local color = require( "gears.color" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local surface = require( "gears.surface" )
|
||||
local pango = require( "lgi" ).Pango
|
||||
local pangocairo = require( "lgi" ).PangoCairo
|
||||
local mouse = require( "collision.mouse" )
|
||||
|
||||
local module = {}
|
||||
|
||||
|
@ -17,6 +18,10 @@ local shape = nil
|
|||
local pss = 1
|
||||
local opss = nil
|
||||
|
||||
-- Keep an index of the last selection client for each screen
|
||||
local last_clients = setmetatable({},{__mode="v"})
|
||||
local last_clients_coords = {}
|
||||
|
||||
-- Screen order is not always geometrical, sort them
|
||||
local function get_first_screen()
|
||||
local ret = {}
|
||||
|
@ -52,6 +57,9 @@ local function create_text(text)
|
|||
local cr = cairo.Context(img)
|
||||
local selected = text == screens[pss]
|
||||
cr:set_source(color(selected and beautiful.bg_urgent or beautiful.bg_alternate or beautiful.bg_normal))
|
||||
if selected then
|
||||
opss = screens_inv[text]
|
||||
end
|
||||
cr:paint()
|
||||
cr:set_source(color(beautiful.fg_normal))
|
||||
cr:set_line_width(6)
|
||||
|
@ -102,8 +110,21 @@ local function init_wiboxes(direction)
|
|||
end
|
||||
|
||||
local function select_screen(scr_index,move,old_screen)
|
||||
local geom = capi.screen[scr_index].geometry
|
||||
capi.mouse.coords({x=geom.x+geom.width/2,y=geom.y+geom.height/2+55})
|
||||
if scr_index ~= old_screen then
|
||||
local c = last_clients[scr_index]
|
||||
if c and c:isvisible() then
|
||||
local geom = c:geometry()
|
||||
if last_clients_coords[scr_index] and last_clients_coords[scr_index].client == c then
|
||||
capi.mouse.coords(last_clients_coords[scr_index])
|
||||
else
|
||||
capi.mouse.coords({x=geom.x+geom.width/2,y=geom.y+geom.height/2+55})
|
||||
end
|
||||
mouse.highlight()
|
||||
else
|
||||
local geom = capi.screen[scr_index].geometry
|
||||
capi.mouse.coords({x=geom.x+geom.width/2,y=geom.y+geom.height/2+55})
|
||||
end
|
||||
end
|
||||
|
||||
if move then
|
||||
local t = awful.tag.selected(old_screen)
|
||||
|
@ -119,6 +140,30 @@ local function select_screen(scr_index,move,old_screen)
|
|||
return scr_index
|
||||
end
|
||||
|
||||
local function in_rect(c,point)
|
||||
if not c then return true end
|
||||
local geo = c:geometry()
|
||||
return (
|
||||
geo.x < point.x and geo.y < point.y and
|
||||
geo.x + geo.width > point.x and geo.y + geo.height > point.y
|
||||
)
|
||||
end
|
||||
|
||||
local function save_cursor_position()
|
||||
local coords = capi.mouse.coords()
|
||||
local c = capi.client.focus
|
||||
-- Be sure that that mouse in inside of the selected client before doing that
|
||||
if c and in_rect(c,coords) then
|
||||
last_clients_coords[c.screen] = {
|
||||
client = c,
|
||||
x = coords.x,
|
||||
y = coords.y,
|
||||
}
|
||||
else
|
||||
last_clients_coords[capi.mouse.screen] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function next_screen(ss,dir,move)
|
||||
local scr_index = screens_inv[ss]
|
||||
|
||||
|
@ -135,8 +180,9 @@ function module.display(_,dir,move)
|
|||
if #wiboxes == 0 then
|
||||
init_wiboxes(dir)
|
||||
end
|
||||
save_cursor_position()
|
||||
module.reload(nil,direction)
|
||||
local ss,opss = current_screen(move),pss
|
||||
local ss = current_screen(move)
|
||||
next_screen(ss,dir,move)
|
||||
module.reload(nil,direction)
|
||||
end
|
||||
|
@ -159,6 +205,7 @@ function module.hide()
|
|||
for s=1, capi.screen.count() do
|
||||
wiboxes[s].visible = false
|
||||
end
|
||||
mouse.hide()
|
||||
end
|
||||
|
||||
local function show()
|
||||
|
@ -168,7 +215,6 @@ local function show()
|
|||
end
|
||||
|
||||
function module.reload(mod,dir,__,___,move)
|
||||
opss = pss
|
||||
local ss = current_screen(move)
|
||||
if dir then
|
||||
ss = next_screen(ss,dir:lower(),move or (mod and #mod == 4))
|
||||
|
@ -182,20 +228,20 @@ function module.reload(mod,dir,__,___,move)
|
|||
end
|
||||
|
||||
function module.select_screen(idx)
|
||||
save_cursor_position()
|
||||
select_screen(screens_inv[idx],false)
|
||||
print("ENTER",idx)
|
||||
if #wiboxes == 0 then
|
||||
init_wiboxes(dir)
|
||||
end
|
||||
|
||||
highlight_screen(idx)
|
||||
highlight_screen(screens_inv[idx])
|
||||
|
||||
show()
|
||||
|
||||
capi.keygrabber.run(function(mod, key, event)
|
||||
print("EVENT",event)
|
||||
if event == "release" then
|
||||
module.hide()
|
||||
mouse.hide()
|
||||
capi.keygrabber.stop()
|
||||
return false
|
||||
end
|
||||
|
@ -203,5 +249,12 @@ function module.select_screen(idx)
|
|||
end)
|
||||
end
|
||||
|
||||
-- capi.mouse.connect_signal("property::screen",1,function(i)
|
||||
-- print("FOO",i)
|
||||
-- end)
|
||||
capi.client.connect_signal("focus",function(c)
|
||||
last_clients[c.screen] = c
|
||||
end)
|
||||
|
||||
return module
|
||||
-- kate: space-indent on; indent-width 2; replace-tabs on;
|
25
util.lua
25
util.lua
|
@ -2,6 +2,7 @@ local math = math
|
|||
local color = require( "gears.color" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local glib = require("lgi").GLib
|
||||
local cairo = require( "lgi" ).cairo
|
||||
|
||||
local module = {settings={}}
|
||||
|
||||
|
@ -16,6 +17,30 @@ function module.get_rgb()
|
|||
return rr,rg,rb
|
||||
end
|
||||
|
||||
function module.arrow_path(cr,width)
|
||||
cr:rel_move_to( 0 , -width/2 )
|
||||
cr:rel_line_to( width/2 , width/2 )
|
||||
cr:rel_line_to( -10 , 0 )
|
||||
cr:rel_line_to( 0 , width/2 )
|
||||
cr:rel_line_to( (-width)+20 , 0 )
|
||||
cr:rel_line_to( 0 , -width/2 )
|
||||
cr:rel_line_to( -10 , 0 )
|
||||
cr:rel_line_to( width/2 , -width/2)
|
||||
cr:close_path()
|
||||
end
|
||||
|
||||
function module.arrow(width,bg,fg)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, width)
|
||||
local cr = cairo.Context(img)
|
||||
cr:set_source(fg)
|
||||
cr:paint()
|
||||
cr:set_source(bg)
|
||||
cr:move_to(width/2,width/2)
|
||||
module.arrow_path(cr,width)
|
||||
cr:fill()
|
||||
return cairo.Pattern.create_for_surface(img)
|
||||
end
|
||||
|
||||
function module.draw_round_rect(cr,x,y,w,h,radius)
|
||||
cr:save()
|
||||
cr:translate(x,y)
|
||||
|
|
Loading…
Reference in New Issue