TMP
* Use the new Awesome `shape` API * Fix the `split` module * Support dynamic resize
This commit is contained in:
parent
042272bee9
commit
7bcbb822c9
|
@ -117,6 +117,7 @@ assigned to shortcuts.
|
|||
The `collision.highlight_cursor(timeout)` method will highlight the current mouse
|
||||
cursor position.
|
||||
|
||||
Use `collision.mouse.highlight()` and `collision.mouse.hide()`
|
||||
# Notes
|
||||
|
||||
Using the focus arrows to select empty screens only work in Awesome 3.5.7+
|
38
focus.lua
38
focus.lua
|
@ -3,6 +3,8 @@ local capi = { client = client , mouse = mouse ,
|
|||
|
||||
local setmetatable = setmetatable
|
||||
local ipairs = ipairs
|
||||
local surface = require( "gears.surface" )
|
||||
local shape = require( "gears.shape" )
|
||||
local util = require( "awful.util" )
|
||||
local client = require( "awful.client" )
|
||||
local tag = require( "awful.tag" )
|
||||
|
@ -19,16 +21,6 @@ local edge = nil
|
|||
|
||||
---------------- Visual -----------------------
|
||||
local function init()
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, 75, 75)
|
||||
local cr = cairo.Context(img)
|
||||
col_utils.draw_round_rect(cr,0,0,75,75,10)
|
||||
cr:fill()
|
||||
|
||||
local bounding,arrow = img._native,col_utils.arrow(55,10,0,
|
||||
beautiful.collision_bg_focus or beautiful.bg_normal or "#000000",
|
||||
beautiful.collision_fg_focus or beautiful.fg_normal or "#0000ff"
|
||||
)
|
||||
|
||||
wiboxes = {}
|
||||
for k,v in ipairs({"up","right","down","left","center"}) do
|
||||
wiboxes[v] = wibox({})
|
||||
|
@ -37,26 +29,24 @@ local function init()
|
|||
wiboxes[v].ontop = true
|
||||
if v ~= "center" then
|
||||
local ib,m = wibox.widget.imagebox(),wibox.layout.margin()
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, 55, 55)
|
||||
local cr = cairo.Context(img)
|
||||
cr:translate(55/2,55/2)
|
||||
cr:rotate((k-1)*(2*math.pi)/4)
|
||||
cr:translate(-(55/2),-(55/2))
|
||||
cr:set_source(arrow)
|
||||
cr:paint()
|
||||
ib:set_image(img)
|
||||
|
||||
ib:set_image(surface.load_from_shape(55, 55,
|
||||
shape.transform(col_utils.arrow_path2)
|
||||
: rotate_at(55/2, 55/2, (k-1)*(2*math.pi)/4),
|
||||
beautiful.collision_fg_focus or beautiful.fg_normal or "#0000ff",
|
||||
nil , 55, 55-20
|
||||
))
|
||||
|
||||
m:set_margins(10)
|
||||
m:set_widget(ib)
|
||||
wiboxes[v]:set_widget(m)
|
||||
wiboxes[v].shape_bounding = bounding
|
||||
surface.apply_shape_bounding(wiboxes[v], shape.rounded_rect, 10)
|
||||
end
|
||||
end
|
||||
wiboxes["center"]:set_bg(beautiful.collision_bg_center or beautiful.bg_urgent or "#ff0000")
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, 75,75)
|
||||
local cr = cairo.Context(img)
|
||||
col_utils.draw_round_rect(cr,0,0,75,75,75/2)
|
||||
cr:fill()
|
||||
wiboxes["center"].shape_bounding = img._native
|
||||
|
||||
surface.apply_shape_bounding(wiboxes["center"], shape.rounded_rect, 37.5)
|
||||
|
||||
end
|
||||
|
||||
local function emulate_client(screen)
|
||||
|
|
6
init.lua
6
init.lua
|
@ -9,7 +9,7 @@ local module = {
|
|||
_resize = require( "collision.resize"),
|
||||
_max = require( "collision.max" ),
|
||||
_screen = require( "collision.screen"),
|
||||
_mouse = require( "collision.mouse" ),
|
||||
mouse = require( "collision.mouse" ),
|
||||
settings= col_utils.settings ,
|
||||
util = col_utils ,
|
||||
split = require( "collision.split" ),
|
||||
|
@ -135,11 +135,11 @@ function module.select_screen(idx)
|
|||
end
|
||||
|
||||
function module.highlight_cursor(timeout)
|
||||
module._mouse.highlight()
|
||||
module.mouse.highlight()
|
||||
if timer then
|
||||
local timer = capi.timer({ timeout = timeout }) -- 30 mins
|
||||
timer:connect_signal("timeout", function()
|
||||
module._mouse.hide()
|
||||
module.mouse.hide()
|
||||
timer:stop()
|
||||
end)
|
||||
timer:start()
|
||||
|
|
|
@ -8,6 +8,7 @@ local awful = require("awful")
|
|||
local beautiful = require("beautiful")
|
||||
local color = require( "gears.color")
|
||||
local util = require( "collision.util" )
|
||||
local shape = require( "gears.shape" )
|
||||
local capi = { screen = screen, client=client }
|
||||
|
||||
local module = {}
|
||||
|
@ -89,7 +90,13 @@ function module.draw(tag,cr,width,height)
|
|||
cr:set_line_width(3)
|
||||
for c,ll in ipairs({l,l2}) do
|
||||
for c,geom in pairs(ll) do
|
||||
util.draw_round_rect(cr,geom.x*ratio*w_stretch+margin,geom.y*ratio+margin,geom.width*ratio*w_stretch-margin*2,geom.height*ratio-margin*2,radius)
|
||||
shape.transform(shape.rounded_rect)
|
||||
: translate(geom.x*ratio*w_stretch+margin, geom.y*ratio+margin) (
|
||||
cr,
|
||||
geom.width*ratio*w_stretch-margin*2,
|
||||
geom.height*ratio-margin*2,
|
||||
radius
|
||||
)
|
||||
cr:close_path()
|
||||
cr:set_source_rgba(r,g,b,0.7)
|
||||
cr:stroke_preserve()
|
||||
|
|
61
max.lua
61
max.lua
|
@ -7,6 +7,8 @@ local beautiful = require( "beautiful" )
|
|||
local surface = require( "gears.surface" )
|
||||
local layout = require( "collision.layout" )
|
||||
local util = require( "collision.util" )
|
||||
local shape = require( "gears.shape" )
|
||||
local shape = require( "gears.shape" )
|
||||
local pango = require("lgi").Pango
|
||||
local pangocairo = require("lgi").PangoCairo
|
||||
local module = {}
|
||||
|
@ -22,26 +24,24 @@ local function init()
|
|||
end
|
||||
|
||||
local margin = 15
|
||||
|
||||
local function create_arrow(cr,x,y,width, height,direction)
|
||||
cr:save()
|
||||
cr:translate(x,y)
|
||||
if direction then
|
||||
cr:translate(width,height)
|
||||
cr:rotate(math.pi)
|
||||
end
|
||||
cr:move_to(x,y)
|
||||
local r,g,b = util.get_rgb()
|
||||
cr:set_source_rgba(r,g,b,0.15)
|
||||
cr:set_antialias(1)
|
||||
cr:rectangle(2*margin,2*(height/7),width/3,3*(height/7))
|
||||
|
||||
local s = shape.transform(shape.arrow)
|
||||
: rotate_at(width/4, height/4, math.pi/2)
|
||||
|
||||
if direction == 1 then
|
||||
s : rotate_at(width/4, height/4, math.pi)
|
||||
end
|
||||
|
||||
s : translate(x, y)
|
||||
|
||||
s(cr, width/2, height/2, nil)
|
||||
|
||||
cr:fill()
|
||||
cr:move_to(2*margin+width/3,(height/7))
|
||||
cr:line_to(width-2*margin,height/2)
|
||||
cr:line_to(2*margin+width/3,6*(height/7))
|
||||
cr:line_to(2*margin+width/3,(height/7))
|
||||
cr:close_path()
|
||||
cr:fill()
|
||||
cr:restore()
|
||||
end
|
||||
|
||||
local pango_l = nil
|
||||
|
@ -89,12 +89,19 @@ local function draw_shape(s,collection,current_idx,icon_f,y,text_height)
|
|||
for k,v in ipairs(collection) do
|
||||
-- Shape bounding
|
||||
cr:set_source(white)
|
||||
util.draw_round_rect(cr,dx,0,width,height,rad)
|
||||
|
||||
local s = shape.transform(shape.rounded_rect) : translate(dx, 0)
|
||||
s(cr, width, height, 10)
|
||||
cr:fill()
|
||||
|
||||
-- Borders and background
|
||||
cr3:set_source(k==current_idx and focus or nornal)
|
||||
util.draw_round_rect(cr3,dx+border,0+border,width-2*border,height-2*border,rad)
|
||||
|
||||
-- cr3:move_to(0,0)
|
||||
-- s = shape.transform(shape.rounded_rect) : translate(dx+border, border)
|
||||
-- s(cr3, width-2*border, height-2*border, rad)
|
||||
|
||||
cr3:set_line_width(2*border + 4) -- The 4 is required to cover the non-antialiased region
|
||||
cr3:stroke_preserve()
|
||||
cr3:set_source(bg)
|
||||
|
@ -159,9 +166,10 @@ local function client_icon(c,width,height)
|
|||
local w,h = geom.width*scale,geom.height*scale
|
||||
|
||||
-- Create a mask
|
||||
util.draw_round_rect(cr,(width-w)/2,(height-h)/2,w,h,10)
|
||||
local s = shape.transform(shape.rounded_rect) : translate((width-w)/2, (height-h)/2)
|
||||
s(cr, w, h, 10)
|
||||
|
||||
cr:fill()
|
||||
cr:clip()
|
||||
|
||||
cr:translate((width-w)/2,(height-h)/2)
|
||||
|
||||
|
@ -171,10 +179,9 @@ local function client_icon(c,width,height)
|
|||
|
||||
-- Paint the screenshot in the rounded rectangle
|
||||
cr:set_source_surface(surface(c.content))
|
||||
cr:set_operator(cairo.Operator.IN)
|
||||
|
||||
cr:paint()
|
||||
cr:restore()
|
||||
cr:restore()
|
||||
|
||||
-- Add icon on top, "solve" the black window issue
|
||||
local icon = surface(c.icon)
|
||||
|
@ -183,13 +190,13 @@ local function client_icon(c,width,height)
|
|||
return img
|
||||
end
|
||||
|
||||
local w,h = icon:get_width(),icon:get_height()
|
||||
local aspect,aspect_h = width / w,(height) / h
|
||||
if aspect > aspect_h then aspect = aspect_h end
|
||||
cr:translate((width-w*aspect)/2,(height-h*aspect)/2)
|
||||
cr:scale(aspect, aspect)
|
||||
cr:set_source_surface(icon)
|
||||
cr:paint_with_alpha(0.5)
|
||||
-- local w,h = icon:get_width(),icon:get_height()
|
||||
-- local aspect,aspect_h = width / w,(height) / h
|
||||
-- if aspect > aspect_h then aspect = aspect_h end
|
||||
-- cr:translate((width-w*aspect)/2,(height-h*aspect)/2)
|
||||
-- cr:scale(aspect, aspect)
|
||||
-- cr:set_source_surface(icon)
|
||||
-- cr:paint_with_alpha(0.5)
|
||||
|
||||
return img
|
||||
end
|
||||
|
|
29
resize.lua
29
resize.lua
|
@ -4,11 +4,19 @@ local wibox,color = require( "wibox" ) , require( "gears.color" )
|
|||
local cairo,beautiful = require( "lgi").cairo , require( "beautiful" )
|
||||
local awful = require("awful")
|
||||
local col_utils = require( "collision.util" )
|
||||
local d_resize = require( "awful.layout.dynamic.resize" )
|
||||
local module,indicators,cur_c,auto_hide = {},nil,nil
|
||||
|
||||
local values = {"top" , "top_right" , "right" , "bottom_right" ,
|
||||
"bottom" , "bottom_left", "left" , "top_left" }
|
||||
|
||||
local invert = {
|
||||
left = "right" ,
|
||||
right = "left" ,
|
||||
top = "bottom",
|
||||
bottom = "top"
|
||||
}
|
||||
|
||||
local function gen_shape_bounding(radius)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, radius,radius)
|
||||
local cr = cairo.Context(img)
|
||||
|
@ -98,6 +106,12 @@ end
|
|||
|
||||
function module.display(c,toggle)
|
||||
local c = c or capi.client.focus
|
||||
if not c then return end
|
||||
if type(c) ~= "client" then
|
||||
print("FAILED", debug.traceback())
|
||||
os.exit()
|
||||
end
|
||||
|
||||
if not indicators then
|
||||
create_indicators()
|
||||
end
|
||||
|
@ -127,6 +141,8 @@ function module.resize(mod,key,event,direction,is_swap,is_max)
|
|||
new_geo[r_direction[direction]] = new_geo[r_direction[direction]] + r_sign[direction]*100
|
||||
end
|
||||
c:geometry(new_geo)
|
||||
elseif lay.is_dynamic then
|
||||
d_resize.ajust_geometry(c, 100 * (is_swap and -1 or 1), is_swap and invert[direction] or direction)
|
||||
elseif layouts_all[lay] then
|
||||
local ret = layouts_all[lay][direction]
|
||||
if ret.mwfact then
|
||||
|
@ -147,7 +163,20 @@ local corners = {
|
|||
|
||||
-- Resize from the top left corner
|
||||
function module.mouse_resize(c,corner)
|
||||
if not c then return end
|
||||
|
||||
module.display(c)
|
||||
|
||||
-- Check if the dynamic resize codepath is available
|
||||
local lay = awful.layout.get(c.screen)
|
||||
if lay.is_dynamic then
|
||||
d_resize.generic_mouse_resize_handler(c, nil, nil, nil,{
|
||||
leave_callback = module.hide
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
-- Use the internal resizing code
|
||||
local geom,curX,curY = c:geometry(),capi.mouse.coords().x,capi.mouse.coords().y
|
||||
capi.mousegrabber.run(function(mouse)
|
||||
if mouse.buttons[1] == false then
|
||||
|
|
79
split.lua
79
split.lua
|
@ -11,6 +11,7 @@ local utils = require( "collision.util" )
|
|||
local wibox = require( "wibox" )
|
||||
local beautiful = require( "beautiful" )
|
||||
local tag = require( "awful.tag" )
|
||||
local util = require( "awful.util" )
|
||||
local textbox = require( "wibox.widget.textbox" )
|
||||
local color = require( "gears.color" )
|
||||
local cairo = require( "lgi" ).cairo
|
||||
|
@ -29,7 +30,12 @@ module.key_map = {
|
|||
"a", "s", "d", "f", "g",
|
||||
"h", "j", "k", "l", "z",
|
||||
"x", "c", "v", "b", "n",
|
||||
"m", "-", "=", ",", "."
|
||||
"m", "-", "=", ",", ".",
|
||||
";", "'", "[", "]", "/",
|
||||
"!","@","#","$","%","^",
|
||||
"&","*","(",")","+","{",
|
||||
"}",":",'"',"<",">","?",
|
||||
"`", "\\",
|
||||
}
|
||||
|
||||
local dir_to_angle = {
|
||||
|
@ -38,11 +44,12 @@ local dir_to_angle = {
|
|||
top = math.pi ,
|
||||
bottom = 0 ,
|
||||
middle = 0 ,
|
||||
stack = 0 ,
|
||||
}
|
||||
|
||||
local dir_to_width_offset_ratio = {
|
||||
internal = {
|
||||
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5,
|
||||
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5, stack = -0.5,
|
||||
},
|
||||
sides = {
|
||||
right = -1 , left = 0 , top = -0.5, bottom = -0.5, middle = -0.5,
|
||||
|
@ -51,7 +58,7 @@ local dir_to_width_offset_ratio = {
|
|||
|
||||
local dir_to_height_offset_ratio = {
|
||||
internal = {
|
||||
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5,
|
||||
left = -0.5, right = -0.5, top = -0.5, bottom = -0.5, middle = -0.5, stack = -0.5,
|
||||
},
|
||||
sides = {
|
||||
left = -0.5, right = -0.5, top = 0 , bottom = -1 , middle = -0.5,
|
||||
|
@ -59,7 +66,7 @@ local dir_to_height_offset_ratio = {
|
|||
}
|
||||
|
||||
local dir_to_size = {
|
||||
left = 60, right = 60, top = 60, bottom = 60, middle = 50,
|
||||
left = 60, right = 60, top = 60, bottom = 60, middle = 50, stack = 50,
|
||||
}
|
||||
|
||||
local type_to_size_ratio = {
|
||||
|
@ -75,14 +82,26 @@ local function internal_rect_pattern(size, direction)
|
|||
cr:set_source(color(beautiful.collision_bg_splitter or beautiful.bg_normal or "#0000ff"))
|
||||
cr:paint()
|
||||
|
||||
local fg = color(beautiful.collision_fg_splitter or beautiful.fg_normal or "#ffffff")
|
||||
local s,r,g,b,a = fg:get_rgba()
|
||||
cr:set_source_rgba(r,g,b,0.4)
|
||||
|
||||
-- This one is different
|
||||
if direction == "stack" then
|
||||
cr:rectangle(3, 3, size - 12, size - 12)
|
||||
cr:stroke()
|
||||
cr:rectangle(9, 9, size - 12, size - 12)
|
||||
cr:stroke_preserve()
|
||||
cr:set_source_rgba(r,g,b,0.2)
|
||||
cr:fill()
|
||||
return cairo.Pattern.create_for_surface(img)
|
||||
end
|
||||
|
||||
cr:translate(size/2,size/2)
|
||||
cr:rotate(dir_to_angle[direction])
|
||||
cr:translate(-size/2,-size/2)
|
||||
|
||||
local fg = color(beautiful.collision_fg_splitter or beautiful.fg_normal or "#ffffff")
|
||||
local s,r,g,b,a = fg:get_rgba()
|
||||
|
||||
cr:set_source_rgba(r,g,b,0.4)
|
||||
cr:rectangle(3, 3, size-6, size/2-6)
|
||||
cr:stroke()
|
||||
cr:rectangle(3, size/2+3, size-6, size/2-6)
|
||||
|
@ -120,14 +139,7 @@ local function add_splitter(context, args)
|
|||
local bg = beautiful.collision_bg_splitter or beautiful.bg_alternate or beautiful.bg_normal or "#0000ff"
|
||||
local width = size * #points
|
||||
|
||||
local w = wibox {
|
||||
x = math.ceil(args.x + dir_to_width_offset_ratio [s_type][direction]*width),
|
||||
y = math.ceil(args.y + dir_to_height_offset_ratio[s_type][direction]*size),
|
||||
width = width,
|
||||
height = size,
|
||||
ontop = true,
|
||||
bg = bg ,
|
||||
}
|
||||
local top_level_l = wibox.layout.flex.vertical()
|
||||
|
||||
local l = wibox.layout.flex.horizontal()
|
||||
|
||||
|
@ -142,7 +154,7 @@ local function add_splitter(context, args)
|
|||
|
||||
local tb = textbox()
|
||||
|
||||
tb:set_markup("<b>".. shortcut .."</b>")
|
||||
tb:set_markup("<b>".. util.quote_pattern(shortcut) .."</b>")
|
||||
tb:set_valign "middle"
|
||||
tb:set_align "center"
|
||||
|
||||
|
@ -153,7 +165,31 @@ local function add_splitter(context, args)
|
|||
context.hooks[shortcut] = point
|
||||
end
|
||||
|
||||
w:set_widget(l)
|
||||
local height = size
|
||||
|
||||
if args.label then
|
||||
local tb = wibox.widget.textbox()
|
||||
tb:set_align("center")
|
||||
tb:set_text(args.label)
|
||||
tb:set_wrap("mode")
|
||||
height = height + tb:get_height_for_width(width)
|
||||
|
||||
top_level_l:add(tb)
|
||||
end
|
||||
|
||||
top_level_l:add(l)
|
||||
|
||||
-- Create a wibox
|
||||
local w = wibox {
|
||||
x = math.ceil(args.x + dir_to_width_offset_ratio [s_type][direction]*width),
|
||||
y = math.ceil(args.y + dir_to_height_offset_ratio[s_type][direction]*size),
|
||||
width = width,
|
||||
height = height,
|
||||
ontop = true,
|
||||
bg = bg ,
|
||||
}
|
||||
|
||||
w:set_widget(top_level_l)
|
||||
|
||||
utils.apply_shape_bounding(w, function(cr) type_to_shape[s_type](cr, w.width, w.height, direction) end)
|
||||
|
||||
|
@ -185,6 +221,7 @@ local function drill(context, root, source)
|
|||
|
||||
if points then
|
||||
for k, point in ipairs(points) do
|
||||
print(#points)
|
||||
add_splitter(context, point)
|
||||
end
|
||||
end
|
||||
|
@ -211,7 +248,9 @@ local function find_split_points(context)
|
|||
if layout.hierarchy then
|
||||
local wa = layout.param.workarea
|
||||
context.add_x, context.add_y = wa.x, wa.y
|
||||
if drill(context, layout.hierarchy, nil) then
|
||||
local source = drill(context, layout.hierarchy, nil)
|
||||
if source then
|
||||
print("\n\nGET", layout.hierarchy, layout.hierarchy:get_widget())
|
||||
context.source_root = layout.hierarchy:get_widget()
|
||||
end
|
||||
end
|
||||
|
@ -232,12 +271,12 @@ end
|
|||
local function start_keygrabber(context)
|
||||
capi.keygrabber.run(function(mod, key, event)
|
||||
local hook = context.hooks[key]
|
||||
|
||||
print("\n\nKEY", key, hook)
|
||||
if hook and hook.callback and event == "press" then
|
||||
context.hooks[key]:callback(context)
|
||||
end
|
||||
|
||||
if event == "press" then
|
||||
if event == "press" and not (key == "Shift_Lt" or key == "Shift_R") then
|
||||
hide(context)
|
||||
capi.keygrabber.stop()
|
||||
end
|
||||
|
|
16
util.lua
16
util.lua
|
@ -38,6 +38,22 @@ function module.arrow_path(cr, width, sidesize)
|
|||
cr:close_path()
|
||||
end
|
||||
|
||||
function module.arrow_path2(cr, width, height, head_width, shaft_width, shaft_length)
|
||||
local shaft_length = shaft_length or height / 2
|
||||
local shaft_width = shaft_width or width / 2
|
||||
local head_width = head_width or width
|
||||
local head_length = height - shaft_length
|
||||
|
||||
cr:move_to( width/2 , 0 )
|
||||
cr:rel_line_to( head_width/2 , head_length )
|
||||
cr:rel_line_to( -(head_width-shaft_width)/2 , 0 )
|
||||
cr:rel_line_to( 0 , shaft_length )
|
||||
cr:rel_line_to( -shaft_width , 0 )
|
||||
cr:rel_line_to( 0 , -shaft_length )
|
||||
cr:rel_line_to( -(head_width-shaft_width)/2 , 0 )
|
||||
cr:close_path()
|
||||
end
|
||||
|
||||
function module.arrow(width, sidesize, margin, bg_color, fg_color)
|
||||
local img = cairo.ImageSurface(cairo.Format.ARGB32, width+2*margin, width+2*margin)
|
||||
local cr = cairo.Context(img)
|
||||
|
|
Loading…
Reference in New Issue