Nested layout.

This commit is contained in:
Xinhao Yuan 2021-02-14 23:04:42 -05:00
parent 9fa3d500c3
commit a651f5528e
4 changed files with 81 additions and 13 deletions

View File

@ -1,4 +1,4 @@
# ![](icon.png) layout-machi # ![machi icon](icon.png) layout-machi
A manual layout for Awesome with a rapid interactive editor. A manual layout for Awesome with a rapid interactive editor.
@ -8,16 +8,16 @@ Draft mode: https://imgur.com/a/BOvMeQL
## Why? ## Why?
TL;DR --- I want the control of my layout. TL;DR --- To bring back control the window layout.
1. Dynamic tiling is an overkill, since tiling is only useful for persistent windows, and people extensively use hibernate/sleep these days. 1. Dynamic tiling can be an overkill, since tiling is only useful for persistent windows, and people extensively use hibernate/sleep these days.
2. I don't want to have all windows moving around whenever a new window shows up. 2. Having window moving around can be annoying whenever a new window shows up.
3. I want to have a flexible layout such that I can quickly adjust to whatever I need. 3. I want a flexible layout such that I can quickly adjust to whatever I need.
## Compatibilities ## Compatibilities
I developed it with Awesome 4.3. I developed it with Awesome git version. Hopefully it works with 4.3 stable.
Please let me know if it does not work in other versions. Please let me know if it does not work in 4.3 or older versions.
## Really quick usage ## Really quick usage
@ -228,7 +228,7 @@ Final merge, size 3x1, `w443113132231`:
### Draft mode ### Draft mode
__This mode is experimental. Its usage may change fast.__ __This mode is somewhat usable, yet it may change in the future.__
Unlike the original machi layout, where a window fits in a single region, draft mode allows window to span across multiple regions. Unlike the original machi layout, where a window fits in a single region, draft mode allows window to span across multiple regions.
Each tiled window is associated with a upper-left region (ULR) and a bottom-right region (BRR). Each tiled window is associated with a upper-left region (ULR) and a bottom-right region (BRR).
@ -237,6 +237,20 @@ The geometry of the window is from the upper-left corner of the ULR to the botto
This is suppose to work with regions produced with `d` or `w` operation. This is suppose to work with regions produced with `d` or `w` operation.
To enable draft mode in a layout, configure the layout with a command with a leading `d`, for example, `d12210121`, or `dw66`. To enable draft mode in a layout, configure the layout with a command with a leading `d`, for example, `d12210121`, or `dw66`.
### Nested layouts
__This feature is a toy. It may come with performance and usability issues - you have been warned.__
__This feature is not available in draft mode.__
To set up nested layouts, you first need to check/modify `machi.editor.nested_layouts` array, which maps an argument string (`[0-9,]+`) to a layout object.
In machi command, use the argument string with command `x` will set up the nested layout of the region to the mapped one.
For example, since by default `machi.editor.nested_layouts["0"]` is `awful.layout.suit.tile` and `machi.editor.nested_layouts["1"]` is `awful.layout.suit.spiral`,
the command `11h0x1x` will split the screen horizontally apply the layouts accordingly - see the figure below.
![nested layout screenshot](nested_layout_screenshot.png)
### Persistent history ### Persistent history
By default, the last 100 command sequences are stored in `.cache/awesome/history_machi`. By default, the last 100 command sequences are stored in `.cache/awesome/history_machi`.

View File

@ -18,6 +18,12 @@ local DEBUG = -1
local module = { local module = {
log_level = WARNING, log_level = WARNING,
nested_layouts = {
["0"] = api.layout.suit.tile,
["1"] = api.layout.suit.spiral,
["2"] = api.layout.suit.fair,
["3"] = api.layout.suit.fair.horizontal,
},
} }
local function log(level, msg) local function log(level, msg)
@ -131,7 +137,8 @@ end
local function shrink_area_with_gap(a, inner_gap, outer_gap) local function shrink_area_with_gap(a, inner_gap, outer_gap)
return { x = a.x + (a.bl and outer_gap or inner_gap / 2), y = a.y + (a.bu and outer_gap or inner_gap / 2), return { x = a.x + (a.bl and outer_gap or inner_gap / 2), y = a.y + (a.bu and outer_gap or inner_gap / 2),
width = a.width - (a.bl and outer_gap or inner_gap / 2) - (a.br and outer_gap or inner_gap / 2), width = a.width - (a.bl and outer_gap or inner_gap / 2) - (a.br and outer_gap or inner_gap / 2),
height = a.height - (a.bu and outer_gap or inner_gap / 2) - (a.bd and outer_gap or inner_gap / 2) } height = a.height - (a.bu and outer_gap or inner_gap / 2) - (a.bd and outer_gap or inner_gap / 2),
layout = a.layout }
end end
function module.restore_data(data) function module.restore_data(data)
@ -553,6 +560,11 @@ function module.create(data)
max_depth = n max_depth = n
end end
elseif method == "x" then
push_area()
closed_areas[#closed_areas].layout = module.nested_layouts[arg_str]
elseif method == "-" then elseif method == "-" then
push_area() push_area()
@ -596,6 +608,7 @@ function module.create(data)
["d"] = 3, ["D"] = 3, ["d"] = 3, ["D"] = 3,
["s"] = 3, ["S"] = 3, ["s"] = 3, ["S"] = 3,
["t"] = 3, ["T"] = 3, ["t"] = 3, ["T"] = 3,
["x"] = 3,
["-"] = 2, ["-"] = 2,
["/"] = 2, ["/"] = 2,
["."] = 1, ["."] = 1,

View File

@ -183,6 +183,7 @@ function module.create(args_or_name, editor, default_cmd)
local regions, draft_mode = get_regions(wa, get_screen(p.screen).selected_tag) local regions, draft_mode = get_regions(wa, get_screen(p.screen).selected_tag)
if #regions == 0 then return end if #regions == 0 then return end
local nested_clients = {}
if draft_mode then if draft_mode then
for i, c in ipairs(cls) do for i, c in ipairs(cls) do
@ -227,6 +228,7 @@ function module.create(args_or_name, editor, default_cmd)
log(DEBUG, "Ignore client " .. tostring(c)) log(DEBUG, "Ignore client " .. tostring(c))
else else
if c.machi_region ~= nil and if c.machi_region ~= nil and
regions[c.machi_region].layout == nil and
regions[c.machi_region].x == c.x and regions[c.machi_region].x == c.x and
regions[c.machi_region].y == c.y and regions[c.machi_region].y == c.y and
regions[c.machi_region].width - c.border_width * 2 == c.width and regions[c.machi_region].width - c.border_width * 2 == c.width and
@ -237,11 +239,53 @@ function module.create(args_or_name, editor, default_cmd)
local region = find_region(c, regions) local region = find_region(c, regions)
c.machi_region = region c.machi_region = region
p.geometries[c] = {} p.geometries[c] = {}
if regions[region].layout ~= nil then
local clients = nested_clients[region]
if clients == nil then clients = {}; nested_clients[region] = clients end
clients[#clients + 1] = c
else
module.set_geometry(p.geometries[c], regions[region], regions[region], useless_gap, 0) module.set_geometry(p.geometries[c], regions[region], regions[region], useless_gap, 0)
end end
end end
end end
end end
for region, clients in pairs(nested_clients) do
local nested_params = {
tags = {
-- Any tag properties to fake?
useless_gap = 0,
},
screen = p.screen,
clients = clients,
padding = 0,
geometry = {
x = regions[region].x,
y = regions[region].y,
width = regions[region].width,
height = regions[region].height,
},
-- Not sure how useless_gap adjustment works here. It seems to work anyway.
workarea = {
x = regions[region].x - useless_gap / 2,
y = regions[region].y - useless_gap / 2,
width = regions[region].width + useless_gap,
height = regions[region].height + useless_gap,
},
useless_gap = 0,
geometries = {},
}
regions[region].layout.arrange(nested_params)
for _, c in ipairs(clients) do
p.geometries[c] = {
x = nested_params.geometries[c].x - useless_gap / 2,
y = nested_params.geometries[c].y - useless_gap / 2,
width = nested_params.geometries[c].width + useless_gap,
height = nested_params.geometries[c].height + useless_gap,
}
end
end
end
end end
local function resize_handler (c, context, h) local function resize_handler (c, context, h)
@ -289,9 +333,6 @@ function module.create(args_or_name, editor, default_cmd)
else else
if context ~= "mouse.move" then return end if context ~= "mouse.move" then return end
local workarea = c.screen.workarea
local regions = get_regions(workarea, c.screen.selected_tag)
if #regions == 0 then return end if #regions == 0 then return end
local center_x = h.x + h.width / 2 local center_x = h.x + h.width / 2

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB