Document the new placement callback with some tweaks.
This commit is contained in:
parent
9b602cfc25
commit
c8fa41f367
19
README.md
19
README.md
|
@ -68,14 +68,29 @@ Use `local layout = machi.layout.create(args)` to instantiate the layout with an
|
|||
- `persistent`: whether to keep a history of the command for the layout. The default is `true`.
|
||||
- `default_cmd`: the command to use if there is no persistent history for this layout.
|
||||
- `editor`: the editor used for the layout. The default is `machi.default_editor` (or `machi.editor.default_editor`).
|
||||
- `new_placement_cb`: a callback `function(c, instance, areas)` that fits new client `c` into the areas.
|
||||
- `new_placement_cb`: a callback `function(c, instance, areas, geometry)` that fits new client `c` into the areas.
|
||||
Returns whether the new client is in draft mode. This is a new and experimental feature.
|
||||
XXX have a subsection for this.
|
||||
|
||||
Either `name` or `name_func` must be set - others are optional.
|
||||
|
||||
The function is compatible with the previous `machi.layout.create(name, editor, default_cmd)` calls.
|
||||
|
||||
For `new_placement_cb` the arguments are:
|
||||
- `c`: the new client to be placed.
|
||||
- `instance`: a layout and tag depedent table with the following fields available:
|
||||
- `cmd`: the current layout command.
|
||||
- `client_data`: a mapping from previously managed clients to their layout related settings and assigned areas.
|
||||
Drafting windows are located using `.lu` and `.rd` fields, otherwise located uisng `.area` field; Drafting override is in `.draft` field.
|
||||
Note that it may contains some clients that are no longer in the layout. You can filter using `screen.tiled_clients`.
|
||||
- `tag_data`: a mapping from area ids to their fake tag data. This is for nested layouts.
|
||||
- `areas`: the current array of areas produced by `instance.cmd`. Each area is a table with the following fields available:
|
||||
- `id`: self index of the array.
|
||||
- `x`, `y`, `width`, `height`: area geometry.
|
||||
- `layout`: the string used to index the nested layout, if any.
|
||||
- `geometry`: the output geometry of the client.
|
||||
|
||||
The callback places the new client by changing its geometry, and returns its draft perference for further area fitting.
|
||||
|
||||
## The layout editor and commands
|
||||
|
||||
### Starting editor in lua
|
||||
|
|
39
layout.lua
39
layout.lua
|
@ -219,11 +219,21 @@ function module.create(args_or_name, editor, default_cmd)
|
|||
end
|
||||
end
|
||||
|
||||
-- Make new clients appear in the end.
|
||||
local j = 0
|
||||
for i = 1, #cls do
|
||||
if cd[cls[i]] ~= nil then
|
||||
j = j + 1
|
||||
cls[j], cls[i] = cls[i], cls[j]
|
||||
end
|
||||
end
|
||||
|
||||
for i, c in ipairs(cls) do
|
||||
if c.floating or c.immobilized then
|
||||
log(DEBUG, "Ignore client " .. tostring(c))
|
||||
else
|
||||
cd[c] = cd[c] or {}
|
||||
p.geometries[c] = {}
|
||||
|
||||
local in_draft = cd[c].draft
|
||||
if cd[c].draft ~= nil then
|
||||
|
@ -233,21 +243,26 @@ function module.create(args_or_name, editor, default_cmd)
|
|||
elseif cd[c].area then
|
||||
in_draft = false
|
||||
elseif new_placement_cb then
|
||||
in_draft = new_placement_cb(c, instance, areas)
|
||||
in_draft = new_placement_cb(c, instance, areas, p.geometries[c])
|
||||
else
|
||||
in_draft = nil
|
||||
end
|
||||
|
||||
local skip = false
|
||||
local cx = p.geometries[c].x or c.x
|
||||
local cy = p.geometries[c].y or c.y
|
||||
local cw = p.geometries[c].w or c.width
|
||||
local ch = p.geometries[c].h or c.height
|
||||
|
||||
if in_draft ~= false then
|
||||
if cd[c].lu ~= nil and cd[c].rd ~= nil and
|
||||
cd[c].lu <= #areas and cd[c].rd <= #areas and
|
||||
not areas[cd[c].lu].inhabitable and not areas[cd[c].rd].inhabitable
|
||||
then
|
||||
if areas[cd[c].lu].x == c.x and
|
||||
areas[cd[c].lu].y == c.y and
|
||||
areas[cd[c].rd].x + areas[cd[c].rd].width - c.border_width * 2 == c.x + c.width and
|
||||
areas[cd[c].rd].y + areas[cd[c].rd].height - c.border_width * 2 == c.y + c.height
|
||||
if areas[cd[c].lu].x == cx and
|
||||
areas[cd[c].lu].y == cy and
|
||||
areas[cd[c].rd].x + areas[cd[c].rd].width - c.border_width * 2 == cx + cw and
|
||||
areas[cd[c].rd].y + areas[cd[c].rd].height - c.border_width * 2 == cy + ch
|
||||
then
|
||||
skip = true
|
||||
end
|
||||
|
@ -259,14 +274,13 @@ function module.create(args_or_name, editor, default_cmd)
|
|||
log(DEBUG, "Compute areas for " .. (c.name or ("<untitled:" .. tostring(c) .. ">")))
|
||||
lu = find_lu(c, areas)
|
||||
if lu ~= nil then
|
||||
c.x = areas[lu].x
|
||||
c.y = areas[lu].y
|
||||
cx = areas[lu].x
|
||||
cy = areas[lu].y
|
||||
rd = find_rd(c, areas, lu)
|
||||
end
|
||||
end
|
||||
|
||||
if lu ~= nil and rd ~= nil then
|
||||
p.geometries[c] = {}
|
||||
if lu == rd and cd[c].lu == nil then
|
||||
cd[c].area = lu
|
||||
place_client_in_area(c, lu)
|
||||
|
@ -282,16 +296,15 @@ function module.create(args_or_name, editor, default_cmd)
|
|||
cd[c].area < #areas and
|
||||
not areas[cd[c].area].inhabitable and
|
||||
areas[cd[c].area].layout == nil and
|
||||
areas[cd[c].area].x == c.x and
|
||||
areas[cd[c].area].y == c.y and
|
||||
areas[cd[c].area].width - c.border_width * 2 == c.width and
|
||||
areas[cd[c].area].height - c.border_width * 2 == c.height
|
||||
areas[cd[c].area].x == cx and
|
||||
areas[cd[c].area].y == cy and
|
||||
areas[cd[c].area].width - c.border_width * 2 == cw and
|
||||
areas[cd[c].area].height - c.border_width * 2 == ch
|
||||
then
|
||||
else
|
||||
log(DEBUG, "Compute areas for " .. (c.name or ("<untitled:" .. tostring(c) .. ">")))
|
||||
local area = find_area(c, areas)
|
||||
cd[c].area, cd[c].lu, cd[c].rd = area, nil, nil
|
||||
p.geometries[c] = {}
|
||||
place_client_in_area(c, area)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue