tests: "Complete" the screen template.

This isn't very nice code, far from it. But it renders fine. So,
as mentionned like what, 1.5 years ago, the original code dump was
half of the scope. This is the second half. It it has various sizes
for various core objects. All of them are hardcoded and some off by
a few pixels, but overall it works.
This commit is contained in:
Emmanuel Lepage Vallee 2020-08-09 23:33:29 -07:00
parent d9514820ef
commit 1cbd839084
1 changed files with 468 additions and 67 deletions

View File

@ -76,12 +76,13 @@ local function stripe_pat(col, angle, line_width, spacing)
end end
local colors = { local colors = {
geometry = "#000000", geometry = "#000000",
workarea = "#0000ff", workarea = "#0000ff",
tiling_area = "#ff0000", tiling_area = "#ff0000",
padding_area= "#ff0000", padding_area = "#ff0000",
wibar = "#000000", wibar = "#000000",
tiling_client = "#ff0000", tiling_client = "#ff0000",
gaps = "#9900ff",
} }
local function draw_area(_, rect, name, offset, highlight) local function draw_area(_, rect, name, offset, highlight)
@ -142,6 +143,7 @@ local function write_on_area_middle(rect, text, offset)
cr:show_layout(playout) cr:show_layout(playout)
end end
-- For clients/wibars with struts only.
local function draw_struct(_, struct, name, offset, label) local function draw_struct(_, struct, name, offset, label)
draw_solid_area(_, struct, name, offset) draw_solid_area(_, struct, name, offset)
if type(label) == 'string' then if type(label) == 'string' then
@ -149,6 +151,15 @@ local function draw_struct(_, struct, name, offset, label)
end end
end end
-- For floating or tiled clients.
local function draw_client(_, c, name, offset, label, alpha)
draw_solid_area(_, c, name, offset, alpha)
if type(label) == 'string' then
write_on_area_middle(c, label, offset)
end
end
local function compute_ruler(_, rect, name) local function compute_ruler(_, rect, name)
table.insert(hrulers, { table.insert(hrulers, {
label = name, x = rect.x, width = rect.width label = name, x = rect.x, width = rect.width
@ -176,7 +187,37 @@ end
local dx = 5 local dx = 5
local function show_ruler_label(offset, padding, ruler, playout) local playout, playout_height = nil, nil
local function get_playout()
if playout then return playout end
local pctx = PangoCairo.font_map_get_default():create_context()
playout = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc)
return playout
end
local function get_text_height()
if playout_height then return playout_height end
local l = get_playout()
local attr, parsed = Pango.parse_markup("<b>GeometryWorkareaPaddingMargins</b>", -1, 0)
l.attributes, l.text = attr, parsed
local _, logical = playout:get_pixel_extents()
playout_height = logical.height
return playout_height
end
local function show_ruler_label(offset, padding, ruler, playout2)
if not ruler.label then return end
local lbl local lbl
if ruler.x then if ruler.x then
@ -187,13 +228,85 @@ local function show_ruler_label(offset, padding, ruler, playout)
ruler.y.." height = "..ruler.height.."</i>" ruler.y.." height = "..ruler.height.."</i>"
end end
local attr, parsed = Pango.parse_markup(lbl, -1, 0)
playout2.attributes, playout2.text = attr, parsed
local _, logical = playout2:get_pixel_extents()
cr:move_to((offset.x - logical.width) /2, offset.y+padding)
cr:show_layout(playout2)
end
local function show_aligned_label(dx2, offset, padding, ruler)
local lbl
if ruler.x then
lbl = ruler.width
else
lbl = ruler.height
end
local attr, parsed = Pango.parse_markup(lbl, -1, 0) local attr, parsed = Pango.parse_markup(lbl, -1, 0)
playout.attributes, playout.text = attr, parsed playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents() local _, logical = playout:get_pixel_extents()
cr:move_to((offset.x - logical.width) /2, offset.y+padding)
if ruler.x then
local off = (ruler.width*factor - logical.width)/2
cr:move_to(ruler.x*factor+off, offset.y+padding)
else
local off = (ruler.height*factor - logical.width)/2
cr:move_to(-ruler.y*factor-dx2*factor-off, padding)
end
cr:show_layout(playout) cr:show_layout(playout)
end end
local function draw_vruler(s, dx2, sx, ruler, layer)
local pad = 5+(layer-1)*dx2
cr:set_source(color(ruler.color or (colors[ruler.label].."66")))
cr:move_to(sx+layer*dx2, ruler.y*factor)
cr:line_to(sx+layer*dx2, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor)
cr:line_to(sx+layer*dx2+2.5, ruler.y*factor)
cr:stroke()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor+ruler.height*factor)
cr:line_to(sx+layer*dx2+2.5, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:save()
cr:move_to(sx+layer*dx2-2.5,ruler.y*factor)
cr:rotate(-math.pi/2)
if ruler and ruler.label then
show_ruler_label({x=-s.geometry.height*factor, y=sx}, pad, ruler, get_playout())
elseif ruler and ruler.align then
show_aligned_label(dx2, {x=s.geometry.width*factor, y=0}, pad, ruler)
end
cr:restore()
end
local function draw_hruler(s, dx2, sy, ruler, layer)
local pad = 10+(layer-1)*(dx2 or 0)
cr:set_source(color(ruler.color or (colors[ruler.label].."66")))
cr:move_to(ruler.x*factor, sy+pad)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad)
cr:stroke()
cr:move_to(ruler.x*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor, sy+pad+2.5)
cr:stroke()
cr:move_to(ruler.x*factor+ruler.width*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad+2.5)
cr:stroke()
if ruler and ruler.label then
show_ruler_label({x=s.geometry.width*factor, y=sy}, pad, ruler, get_playout())
elseif ruler and ruler.align then
show_aligned_label(dx2, {x=s.geometry.width*factor, y=sy}, pad, ruler)
end
end
local function draw_rulers(s) local function draw_rulers(s)
-- The table has a maximum of 4 entries, the sort algorithm is irrelevant. -- The table has a maximum of 4 entries, the sort algorithm is irrelevant.
while not bubble_sort(hrulers, "x", "width" ) do end while not bubble_sort(hrulers, "x", "width" ) do end
@ -205,67 +318,290 @@ local function draw_rulers(s)
local sx = (s.geometry.x+s.geometry.width )*factor local sx = (s.geometry.x+s.geometry.width )*factor
local sy = (s.geometry.y+s.geometry.height)*factor local sy = (s.geometry.y+s.geometry.height)*factor
dx = get_text_height() + 10
local pctx = PangoCairo.font_map_get_default():create_context()
local playout = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc)
local attr, parsed = Pango.parse_markup("<b>GeometryWorkareaPaddingMargins</b>", -1, 0)
playout.attributes, playout.text = attr, parsed
local _, logical = playout:get_pixel_extents()
dx = logical.height + 10
for k, ruler in ipairs(vrulers) do for k, ruler in ipairs(vrulers) do
local pad = 5+(k-1)*dx draw_vruler(s, dx, sx, ruler, k)
cr:set_source(color(colors[ruler.label].."66"))
cr:move_to(sx+k*dx, ruler.y*factor)
cr:line_to(sx+k*dx, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:move_to(sx+k*dx-2.5,ruler.y*factor)
cr:line_to(sx+k*dx+2.5, ruler.y*factor)
cr:stroke()
cr:move_to(sx+k*dx-2.5,ruler.y*factor+ruler.height*factor)
cr:line_to(sx+k*dx+2.5, ruler.y*factor+ruler.height*factor)
cr:stroke()
cr:save()
cr:move_to(sx+k*dx-2.5,ruler.y*factor)
cr:rotate(-math.pi/2)
show_ruler_label({x=-s.geometry.height*factor, y=sx}, pad, ruler, playout)
cr:restore()
end end
for k, ruler in ipairs(hrulers) do for k, ruler in ipairs(hrulers) do
local pad = 10+(k-1)*dx draw_hruler(s, dx, sy, ruler, k)
cr:set_source(color(colors[ruler.label].."66"))
cr:move_to(ruler.x*factor, sy+pad)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad)
cr:stroke()
cr:move_to(ruler.x*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor, sy+pad+2.5)
cr:stroke()
cr:move_to(ruler.x*factor+ruler.width*factor, sy+pad-2.5)
cr:line_to(ruler.x*factor+ruler.width*factor, sy+pad+2.5)
cr:stroke()
show_ruler_label({x=s.geometry.width*factor, y=sy}, pad, ruler, playout)
end end
end end
local tr_x, tr_y = 0, 0
-- Not a very efficient way to do this, but at least it is simple.
local function deduplicate_gaps(gaps)
for _, gap1 in ipairs(gaps) do
for k, gap2 in ipairs(gaps) do
if gap1[2] == gap2[1] then
gap1[2] = gap2[2]
table.remove(gaps, k)
return true
elseif gap2[1] >= gap1[1] and gap2[2] <= gap1[2] and gap1 ~= gap2 then
table.remove(gaps, k)
return true
elseif gap1[1] == gap2[1] and gap2[2] == gap2[2] and gap1 ~= gap2 then
table.remove(gaps, k)
return true
end
end
end
return false
end
local function get_gaps(s)
local ret = {vertical={gaps={}, content={}}, horizontal={gaps={}, content={}}}
local gap = s.selected_tag.gap
if gap == 0 then return ret end
if s.selected_tag.gap_single_client == false and #s.tiled_clients == 1 then
return ret
end
-- First, get all gaps.
for _, c in ipairs(s.tiled_clients) do
local bw = c.border_width
table.insert(ret.horizontal.gaps, {c.x-gap , c.x })
table.insert(ret.vertical.gaps , {c.y-gap , c.y })
table.insert(ret.horizontal.gaps, {c.x+c.width +2*bw, c.x+c.width+gap +2*bw})
table.insert(ret.vertical.gaps , {c.y+c.height+2*bw, c.y+c.height+gap+2*bw})
end
-- Merge continuous gaps.
while deduplicate_gaps(ret.vertical.gaps ) do end
while deduplicate_gaps(ret.horizontal.gaps) do end
return ret
end
local function evaluate_translation(draw_gaps, draw_struts, draw_mwfact, draw_client_snap)
for s in screen do
if (draw_gaps and s.selected_tag and s.selected_tag.gap > 0) then
local gaps = get_gaps(s)
-- Only add the space if there is something to display.
if #gaps.horizontal.gaps > 0 then
tr_y = math.max(tr_y, 3 * get_text_height())
end
if #gaps.vertical.gaps > 0 then
tr_x = math.max(tr_x, 2 * get_text_height())
end
end
if draw_client_snap or draw_struts then
tr_y = math.max(tr_y, 3 * get_text_height())
tr_x = math.max(tr_x, 2 * get_text_height())
end
if draw_mwfact then
tr_y = math.max(tr_y, 3 * get_text_height())
end
end
end
local function translate()
cr:translate(tr_x, tr_y * 0.66)
end
local function draw_gaps(s)
cr:translate(-tr_x, -tr_y)
local gaps = get_gaps(s)
local offset = s.tiling_area
for _, hgap in ipairs(gaps.horizontal.gaps) do
draw_hruler(
s,
offset.x,
get_text_height(),
{
x = offset.x+hgap[1]+tr_x,
width = math.ceil(hgap[2]-hgap[1]),
label = nil,
color = colors.gaps.."66",
align = true
},
1
)
end
for _, vgap in ipairs(gaps.vertical.gaps) do
draw_vruler(
s,
get_text_height()*1.5,
0,
{
y = offset.y+vgap[1]+tr_y,
height = math.ceil(vgap[2]-vgap[1]),
label = nil,
color = colors.gaps.."66",
align = true
},
1
)
end
cr:translate(tr_x, tr_y)
end
local function has_struts(s)
for k, v in pairs(s.workarea) do
if s.geometry[k] ~= v then
return true
end
end
return false
end
local function draw_struts(s)
local left = s.workarea.x - s.geometry.x
local right = (s.geometry.x + s.geometry.width) - (s.workarea.x + s.workarea.width)
local top = s.workarea.y - s.geometry.y
local bottom = (s.geometry.y + s.geometry.height) - (s.workarea.y + s.workarea.height)
cr:translate(-tr_x, -tr_y)
if left > 0 then
draw_hruler(
s,
0,
get_text_height(),
{x = s.geometry.x+tr_x*2, width = left, color = colors.gaps.."66", align = true},
1
)
end
if top > 0 then
draw_vruler(
s,
get_text_height()*1.5,
0,
{y=s.geometry.y+tr_y*(1/factor), height = top, color = colors.gaps.."66", align = true},
1
)
end
if right > 0 then
draw_hruler(
s,
0,
get_text_height(),
{x = s.geometry.x, width = left, color = colors.gaps.."66", align = true},
1
)
end
if bottom > 0 then
draw_vruler(
s,
get_text_height()*1.5,
0,
{
y = s.geometry.y+tr_y*(1/factor)+s.geometry.height - bottom,
height = bottom,
color = colors.gaps.."66",
align = true
},
1
)
end
cr:translate(tr_x, tr_y)
end
local function draw_mwfact(s)
cr:translate(-tr_x, -tr_y)
local mwfact = s.selected_tag.master_width_factor
local offset = s.tiling_area.x
local width = s.tiling_area.width
local w1, w2 = math.ceil(width*mwfact), math.ceil(width*(1-mwfact))
draw_hruler(s, offset, get_text_height(), {x=offset,width=w1,color = colors.gaps.."66", align=true}, 1)
draw_hruler(s, offset, get_text_height(), {x=offset+w1,width=w2,color = colors.gaps.."66", align=true}, 1)
cr:translate(tr_x, tr_y)
end
local function draw_client_snap(s)
cr:translate(-tr_x, -tr_y)
local snap_areas = {
vertical ={},
horizontal={}
}
local d = require("awful.mouse.snap").default_distance
for _, c in ipairs(s.clients) do
if c.floating then
table.insert(snap_areas.horizontal, {c.x-d, c.x})
table.insert(snap_areas.horizontal, {c.x+c.width, c.x+c.width+d})
table.insert(snap_areas.vertical , {c.y-d, c.y})
table.insert(snap_areas.vertical , {c.y+c.height, c.y+c.height+d})
end
end
while deduplicate_gaps(snap_areas.horizontal) do end
while deduplicate_gaps(snap_areas.vertical ) do end
--FIXME
--[[for _, hgap in ipairs(snap_areas.horizontal) do
draw_hruler(
s,
0,
get_text_height(),
{x=tr_x+s.workarea.x+hgap[1],width=hgap[2]-hgap[1],label="gaps"},
1
)
end
for _, vgap in ipairs(snap_areas.vertical) do
draw_vruler(
s,
get_text_height()*1.5,
0,
{y=tr_y+vgap[1],height=vgap[2]-vgap[1],label="gaps"},
1
)
end]]--
cr:translate(tr_x, tr_y)
end
-- local function draw_screen_snap(s)
-- local d = require("awful.mouse.snap").aerosnap_distance
--
--
-- local proxy = {
-- x = c.x - sd,
-- y = c.y - sd,
-- width = c.width + 2*sd,
-- height = c.height + 2*sd,
-- }
--
-- draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
-- end
local function draw_info(s) local function draw_info(s)
cr:set_source_rgb(0, 0, 0) cr:set_source_rgb(0, 0, 0)
local pctx = PangoCairo.font_map_get_default():create_context() local pctx = PangoCairo.font_map_get_default():create_context()
local playout = Pango.Layout.new(pctx) local playout2 = Pango.Layout.new(pctx)
local pdesc = Pango.FontDescription() local pdesc = Pango.FontDescription()
pdesc:set_absolute_size(11 * Pango.SCALE) pdesc:set_absolute_size(11 * Pango.SCALE)
playout:set_font_description(pdesc) playout2:set_font_description(pdesc)
local rows = { local rows = {
"primary", "index", "geometry", "dpi", "dpi range", "outputs" "primary", "index", "geometry", "dpi", "dpi range", "outputs"
@ -298,13 +634,13 @@ local function draw_info(s)
-- Get the extents of the longest label. -- Get the extents of the longest label.
for k, label in ipairs(rows) do for k, label in ipairs(rows) do
local attr, parsed = Pango.parse_markup(label..":", -1, 0) local attr, parsed = Pango.parse_markup(label..":", -1, 0)
playout.attributes, playout.text = attr, parsed playout2.attributes, playout2.text = attr, parsed
local _, logical = playout:get_pixel_extents() local _, logical = playout2:get_pixel_extents()
col1_width = math.max(col1_width, logical.width+10) col1_width = math.max(col1_width, logical.width+10)
attr, parsed = Pango.parse_markup(values[k], -1, 0) attr, parsed = Pango.parse_markup(values[k], -1, 0)
playout.attributes, playout.text = attr, parsed playout2.attributes, playout2.text = attr, parsed
_, logical = playout:get_pixel_extents() _, logical = playout2:get_pixel_extents()
col2_width = math.max(col2_width, logical.width+10) col2_width = math.max(col2_width, logical.width+10)
height = math.max(height, logical.height) height = math.max(height, logical.height)
@ -316,15 +652,15 @@ local function draw_info(s)
-- Draw everything. -- Draw everything.
for k, label in ipairs(rows) do for k, label in ipairs(rows) do
local attr, parsed = Pango.parse_markup(label..":", -1, 0) local attr, parsed = Pango.parse_markup(label..":", -1, 0)
playout.attributes, playout.text = attr, parsed playout2.attributes, playout2.text = attr, parsed
cr:move_to(dx2, dy) cr:move_to(dx2, dy)
cr:show_layout(playout) cr:show_layout(playout2)
attr, parsed = Pango.parse_markup(values[k], -1, 0) attr, parsed = Pango.parse_markup(values[k], -1, 0)
playout.attributes, playout.text = attr, parsed playout2.attributes, playout2.text = attr, parsed
local _, logical = playout:get_pixel_extents() local _, logical = playout2:get_pixel_extents()
cr:move_to( dx2+col1_width+5, dy) cr:move_to( dx2+col1_width+5, dy)
cr:show_layout(playout) cr:show_layout(playout2)
dy = dy + 5 + logical.height dy = dy + 5 + logical.height
end end
@ -344,11 +680,21 @@ for _=1, screen.count() do
compute_ruler(s, s.geometry, "geometry") compute_ruler(s, s.geometry, "geometry")
end end
-- If there is some rulers on the left/top, add a global translation.
evaluate_translation(
args.draw_gaps,
args.draw_struts,
args.draw_mwfact,
args.draw_client_snap
)
-- Get the final size of the image. -- Get the final size of the image.
local sew, seh = screen._get_extents() local sew, seh = screen._get_extents()
sew, seh = sew/args.factor + (screen.count()-1)*10+2, seh/args.factor+2 sew, seh = sew/args.factor + (screen.count()-1)*10+2, seh/args.factor+2
sew,seh=sew+100,seh+100 sew, seh = sew + tr_x, seh + 0.66*tr_y
sew, seh = sew + 5*get_text_height(), seh + 5*get_text_height()
img = cairo.SvgSurface.create(image_path..".svg", sew, seh) img = cairo.SvgSurface.create(image_path..".svg", sew, seh)
cr = cairo.Context(img) cr = cairo.Context(img)
@ -356,10 +702,14 @@ cr = cairo.Context(img)
cr:set_line_width(1.5) cr:set_line_width(1.5)
cr:set_dash({10,4},1) cr:set_dash({10,4},1)
-- Instead of adding origin offset everywhere, translate the viewport.
translate()
-- Draw the various areas. -- Draw the various areas.
for k=1, screen.count() do for k=1, screen.count() do
local s = screen[1] local s = screen[1]
-- The outer geometry. -- The outer geometry.
draw_area(s, s.geometry, "geometry", (k-1)*10, args.highlight_geometry) draw_area(s, s.geometry, "geometry", (k-1)*10, args.highlight_geometry)
@ -381,17 +731,68 @@ for k=1, screen.count() do
draw_struct(s, args.draw_wibar, 'wibar', (k-1)*10, 'Wibar') draw_struct(s, args.draw_wibar, 'wibar', (k-1)*10, 'Wibar')
end end
local skip_gaps = s.selected_tag
and s.selected_tag.gap_single_client == false
and #s.tiled_clients == 1
local sd = require("awful.mouse.snap").default_distance
-- Draw clients. -- Draw clients.
if args.draw_clients then if args.draw_clients then
for label,c in pairs(args.draw_clients) do for label,c in pairs(args.draw_clients) do
draw_struct(s, c, 'tiling_client', (k-1)*10, label) local gap = c:tags()[1].gap
if args.draw_gaps and gap > 0 and (not c.floating) and not skip_gaps then
local proxy = {
x = c.x - gap,
y = c.y - gap,
width = c.width + 2*gap,
height = c.height + 2*gap,
}
draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
elseif args.draw_client_snap and c.floating then
local proxy = {
x = c.x - sd,
y = c.y - sd,
width = c.width + 2*sd,
height = c.height + 2*sd,
}
draw_client(s, proxy, 'gaps', (k-1)*10, nil, "11")
end
draw_client(s, c, 'tiling_client', (k-1)*10, label)
end end
end end
if args.draw_struts and has_struts(s) then
draw_struts(s)
end
-- Draw the informations. -- Draw the informations.
if args.display_screen_info ~= false then if args.display_screen_info ~= false then
draw_info(s) draw_info(s)
end end
-- Draw the useless gaps.
if args.draw_gaps and not skip_gaps then
draw_gaps(s)
end
-- Draw the useless gaps.
if args.draw_mwfact then
draw_mwfact(s)
end
-- Draw the snapping areas of floating clients.
if args.draw_client_snap then
draw_client_snap(s)
end
-- Draw the screen edge areas.
--if args.draw_screen_snap then
-- draw_screen_snap(s)
--end
end end
img:finish() img:finish()