move region calculation to arrangement
This commit is contained in:
parent
bc8bda02e6
commit
dfb3e8f365
|
@ -12,8 +12,8 @@ TL;DR --- I want the control of my layout.
|
|||
|
||||
## Use the layout
|
||||
|
||||
Use `layout = layout_machi.layout.create(name)` to instantiate the layout.
|
||||
It is advised to instantiate layouts of unique names for each tag (and for each screen), since the editor will restore the last regions of the layout based on the names.
|
||||
Use `layout = layout_machi.layout.create(name, editor)` to instantiate the layout with an editor object (see below on creating the editor).
|
||||
The editor will restore the last regions of the layouts based on their names.
|
||||
|
||||
## Editor
|
||||
|
||||
|
@ -101,8 +101,6 @@ So far, the key binding is not configurable. One has to modify the source code t
|
|||
`layout_machi.editor.fit_region(c, cycle = false)` will fit a floating client into the closest region.
|
||||
If `cycle` is true, it then moves the window by cycling all regions.
|
||||
|
||||
`layout_machi.editor.refresh_layout(layout, screen)` will recalculate the regions of the layout based on the workarea of the `screen` and the last editing command performed on `layout`.
|
||||
|
||||
## Caveats
|
||||
|
||||
`beautiful.useless_gap` is handled differently in layout-machi and it doesn't cooperate well with the standard way.
|
||||
|
|
52
editor.lua
52
editor.lua
|
@ -70,7 +70,7 @@ end
|
|||
-- @return whether any actions have been taken on the client
|
||||
local function fit_region(c, cycle)
|
||||
layout = api.layout.get(c.screen)
|
||||
regions = layout.get_regions and layout.get_regions()
|
||||
regions = layout.get_regions and layout.get_regions(c.screen.workarea)
|
||||
if type(regions) ~= "table" or #regions < 1 then
|
||||
return false
|
||||
end
|
||||
|
@ -102,6 +102,28 @@ local function shrink_area_with_gap(a, gap)
|
|||
height = a.height - (a.bu and 0 or gap / 2) - (a.bd and 0 or gap / 2) }
|
||||
end
|
||||
|
||||
-- local function parse(cmd)
|
||||
-- root = {}
|
||||
-- args = ""
|
||||
|
||||
-- open_areas = { root }
|
||||
|
||||
-- for c = 1, #cmd do
|
||||
-- char = cmd:sub(c, c)
|
||||
|
||||
-- if char == "w" then
|
||||
-- local a = open_areas[#open_areas]
|
||||
-- table.remove(open_areas, #open_areas)
|
||||
|
||||
-- root.type = "w"
|
||||
-- root.
|
||||
|
||||
-- else if tonumber(char) ~= nil then
|
||||
-- args = args .. char
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
local function restore_data(data)
|
||||
if data.history_file then
|
||||
local file, err = io.open(data.history_file, "r")
|
||||
|
@ -268,7 +290,7 @@ local function create(data)
|
|||
depth = a.depth + 1,
|
||||
group_id = split_count,
|
||||
bl = i == 1 and a.bl or false,
|
||||
br = i == #offset and a.br or false,
|
||||
br = i == #offset - 1 and a.br or false,
|
||||
bu = a.bu,
|
||||
bd = a.bd,
|
||||
}
|
||||
|
@ -313,7 +335,7 @@ local function create(data)
|
|||
bl = a.bl,
|
||||
br = a.br,
|
||||
bu = i == 1 and a.bu or false,
|
||||
bd = i == #offset and a.bd or false,
|
||||
bd = i == #offset - 1 and a.bd or false,
|
||||
}
|
||||
children[#children + 1] = child
|
||||
end
|
||||
|
@ -678,8 +700,8 @@ local function create(data)
|
|||
)
|
||||
end
|
||||
|
||||
local function set_by_cmd(layout, screen, cmd)
|
||||
init(screen.workarea)
|
||||
local function run_cmd(init_area, cmd)
|
||||
init(init_area)
|
||||
push_history()
|
||||
|
||||
for i = 1, #cmd do
|
||||
|
@ -702,26 +724,18 @@ local function create(data)
|
|||
end
|
||||
end
|
||||
)
|
||||
layout.cmd = cmd
|
||||
data.last_cmd[layout.name] = cmd
|
||||
layout.set_regions(areas_with_gap)
|
||||
api.layout.arrange(screen)
|
||||
|
||||
return areas_with_gap
|
||||
end
|
||||
|
||||
local function refresh_layout(layout, screen)
|
||||
if layout.cmd == nil then return end
|
||||
set_by_cmd(layout, screen, layout.cmd)
|
||||
end
|
||||
|
||||
local function try_restore_last(layout, screen)
|
||||
if data.last_cmd[layout.name] == nil then return end
|
||||
set_by_cmd(layout, screen, data.last_cmd[layout.name])
|
||||
local function get_last_cmd(name)
|
||||
return data.last_cmd[name]
|
||||
end
|
||||
|
||||
return {
|
||||
start_interactive = start_interactive,
|
||||
refresh_layout = refresh_layout,
|
||||
try_restore_last = try_restore_last,
|
||||
run_cmd = run_cmd,
|
||||
get_last_cmd = get_last_cmd
|
||||
}
|
||||
end
|
||||
|
||||
|
|
108
layout.lua
108
layout.lua
|
@ -36,53 +36,71 @@ local function find_region(c, regions)
|
|||
return choice
|
||||
end
|
||||
|
||||
function do_arrange(p, priv)
|
||||
local wa = p.workarea
|
||||
local cls = p.clients
|
||||
local regions = priv.regions
|
||||
function create(name, editor)
|
||||
local priv = {
|
||||
name = name,
|
||||
editor = editor,
|
||||
cmd = editor.get_last_cmd(name),
|
||||
regions_cache = {}
|
||||
}
|
||||
|
||||
if #regions == 0 then return end
|
||||
local function get_regions(workarea)
|
||||
if priv.cmd == nil then return {} end
|
||||
local key = tostring(workarea.width) .. "x" .. tostring(workarea.height) .. "+" .. tostring(workarea.x) .. "+" .. tostring(workarea.y)
|
||||
if priv.regions_cache[key] == nil then
|
||||
priv.regions_cache[key] = priv.editor.run_cmd(workarea, priv.cmd)
|
||||
end
|
||||
return priv.regions_cache[key]
|
||||
end
|
||||
|
||||
function arrange(p)
|
||||
local wa = p.workarea
|
||||
local cls = p.clients
|
||||
local regions = get_regions(wa)
|
||||
|
||||
|
||||
if #regions == 0 then return end
|
||||
|
||||
for i, c in ipairs(cls) do
|
||||
if c.floating then
|
||||
print("Ignore client " .. tostring(c))
|
||||
else
|
||||
if c.machi_region == nil then
|
||||
c.machi_region = find_region(c, regions)
|
||||
elseif c.machi_region > #regions then
|
||||
c.machi_region = #regions
|
||||
elseif c.machi_region <= 1 then
|
||||
c.machi_region = 1
|
||||
end
|
||||
local region = c.machi_region
|
||||
|
||||
p.geometries[c] = {
|
||||
x = regions[region].x,
|
||||
y = regions[region].y,
|
||||
width = regions[region].width,
|
||||
height = regions[region].height,
|
||||
}
|
||||
|
||||
print("Put client " .. tostring(c) .. " to region " .. region)
|
||||
|
||||
for i, c in ipairs(cls) do
|
||||
if c.floating then
|
||||
print("Ignore client " .. tostring(c))
|
||||
else
|
||||
if c.machi_region == nil then
|
||||
c.machi_region = find_region(c, regions)
|
||||
elseif c.machi_region > #regions then
|
||||
c.machi_region = #regions
|
||||
elseif c.machi_region <= 1 then
|
||||
c.machi_region = 1
|
||||
end
|
||||
local region = c.machi_region
|
||||
|
||||
p.geometries[c] = {
|
||||
x = regions[region].x,
|
||||
y = regions[region].y,
|
||||
width = regions[region].width,
|
||||
height = regions[region].height,
|
||||
}
|
||||
|
||||
print("Put client " .. tostring(c) .. " to region " .. region)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function create(name)
|
||||
local priv = { regions = {} }
|
||||
|
||||
local function set_regions(regions)
|
||||
priv.regions = regions
|
||||
end
|
||||
|
||||
local function get_regions()
|
||||
return priv.regions
|
||||
function set_cmd(cmd)
|
||||
if priv.cmd ~= cmd then
|
||||
priv.cmd = cmd
|
||||
priv.regions_cache = {}
|
||||
end
|
||||
end
|
||||
|
||||
-- move the closest region regardingly to the center distance
|
||||
local function resize_handler(c, context, h)
|
||||
if context ~= "mouse.move" then return end
|
||||
|
||||
local workarea = c.screen.workarea
|
||||
local regions = get_regions(workarea)
|
||||
|
||||
if #priv.regions == 0 then return end
|
||||
|
||||
local center_x = h.x + h.width / 2
|
||||
|
@ -90,7 +108,8 @@ function create(name)
|
|||
|
||||
local choice = 1
|
||||
local choice_value = nil
|
||||
for i, r in ipairs(priv.regions) do
|
||||
|
||||
for i, r in ipairs(regions) do
|
||||
local r_x = r.x + r.width / 2
|
||||
local r_y = r.y + r.height / 2
|
||||
local dis = (r_x - center_x) * (r_x - center_x) + (r_y - center_y) * (r_y - center_y)
|
||||
|
@ -102,24 +121,23 @@ function create(name)
|
|||
|
||||
if c.machi_region ~= choice then
|
||||
c.machi_region = choice
|
||||
c.x = priv.regions[choice].x
|
||||
c.y = priv.regions[choice].y
|
||||
c.width = priv.regions[choice].width
|
||||
c.height = priv.regions[choice].height
|
||||
c.x = regions[choice].x
|
||||
c.y = regions[choice].y
|
||||
c.width = regions[choice].width
|
||||
c.height = regions[choice].height
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
name = name,
|
||||
arrange = function (p) do_arrange(p, priv) end,
|
||||
get_region_count = function () return #priv.regions end,
|
||||
set_regions = set_regions,
|
||||
arrange = arrange,
|
||||
set_cmd = set_cmd,
|
||||
get_regions = get_regions,
|
||||
resize_handler = resize_handler,
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
return {
|
||||
create = create,
|
||||
find_region = find_region,
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ local function start(c)
|
|||
local layout = api.layout.get(screen)
|
||||
if c.floating or layout.get_regions == nil then return end
|
||||
|
||||
local regions = layout.get_regions()
|
||||
local regions = layout.get_regions(c.screen.workarea)
|
||||
|
||||
local infobox = api.wibox({
|
||||
screen = screen,
|
||||
|
|
Loading…
Reference in New Issue