Deprecate per-layout draft mode. Add placement callback.

This commit is contained in:
Xinhao Yuan 2021-02-27 11:11:54 -05:00
parent 27f684ee5a
commit 2b8ee4abd6
3 changed files with 38 additions and 21 deletions

View File

@ -17,6 +17,7 @@ Machi-ng is a refactoring effort of machi with new features and enhancements.
1. Added a max split (before merging) of 1,000 for all commands and a global cap of 10,000 areas. 1. Added a max split (before merging) of 1,000 for all commands and a global cap of 10,000 areas.
2. `t` command now applies to the current area and its further splits, instead of globally. 2. `t` command now applies to the current area and its further splits, instead of globally.
3. `s` command now shifts inside the last group of pending areas that have the same parent, instead of all pending areas. 3. `s` command now shifts inside the last group of pending areas that have the same parent, instead of all pending areas.
4. There is no more per-layout setting of "draft mode". Every window has its own setting.
### New features & enhancements ### New features & enhancements
@ -54,7 +55,7 @@ The package comes with the icon for `layoutbox`, which can be set with the follo
`require("beautiful").layout_machi = machi.get_icon()` `require("beautiful").layout_machi = machi.get_icon()`
By default, any machi layout will use the layout command from `machi.layout.default_cmd`, which is initialized as `dw66.` (see interpretation below). By default, any machi layout will use the layout command from `machi.layout.default_cmd`, which is initialized as `w66.` (see interpretation below).
You can change it after loading the module. You can change it after loading the module.
## Use the layout ## Use the layout
@ -67,6 +68,9 @@ 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`. - `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. - `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`). - `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.
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. Either `name` or `name_func` must be set - others are optional.
@ -266,10 +270,10 @@ Unlike the regular placement, where a window fits in a single area, windows in d
Each drafting window is associated with a upper-left area (UL) and a bottom-right area (BR). Each drafting window is associated with a upper-left area (UL) and a bottom-right area (BR).
The geometry of the window is from the upper-left corner of the UL to the bottom-right corner of the BR. The geometry of the window is from the upper-left corner of the UL to the bottom-right corner of the BR.
Draft mode is suppose to work well with areas produced with `d` or `w` operation, but it is not limited to those. Draft mode is suppose to work well with grid areas (produced by `d` or `w` operations), but it is not limited to those.
To enable draft mode in a layout by default, configure the layout with a command with a leading `d`, for example, `d12210121`, or `dw66`. Draft mode is enabled for a newly placed window when its UL and BR is in different areas.
Resize a window to a single area to disable drafting, or across areas to enable drafting.
Draft mode can be easily overrided by per-window settings. Resize a window to a single area to disable drafting, or across areas to enable drafting. You can also use `f` or `.` key in switcher UI to manually cycle through modes. You can also use `f` or `.` key in switcher UI to manually cycle through modes despit how the window previously spans areas.
### Nested layouts ### Nested layouts

View File

@ -12,7 +12,7 @@ local DEBUG = -1
local module = { local module = {
log_level = WARNING, log_level = WARNING,
global_default_cmd = "dw66.", global_default_cmd = "w66.",
allow_shrinking_by_mouse_moving = false, allow_shrinking_by_mouse_moving = false,
} }
@ -176,14 +176,16 @@ function module.create(args_or_name, editor, default_cmd)
local workarea = screen.workarea local workarea = screen.workarea
local instance = get_instance_(tag) local instance = get_instance_(tag)
local cmd = instance.cmd or module.global_default_cmd local cmd = instance.cmd or module.global_default_cmd
if cmd == nil then return nil, nil, nil, false end if cmd == nil then return end
local key = tostring(workarea.width) .. "x" .. tostring(workarea.height) .. "+" .. tostring(workarea.x) .. "+" .. tostring(workarea.y) local key = tostring(workarea.width) .. "x" .. tostring(workarea.height) .. "+" .. tostring(workarea.x) .. "+" .. tostring(workarea.y)
if instance.areas_cache[key] == nil then if instance.areas_cache[key] == nil then
instance.areas_cache[key] = args.editor.run_cmd(cmd, screen, tag) instance.areas_cache[key] = args.editor.run_cmd(cmd, screen, tag)
if instance.areas_cache[key] == nil then
return
end
end end
local draft_mode = instance.areas_cache[key] and instance.areas_cache[key][1].draft_mode return instance.client_data, instance.tag_data, instance.areas_cache[key], instance, args.new_placement_cb
return instance.client_data, instance.tag_data, instance.areas_cache[key], draft_mode ~= nil
end end
local function set_cmd(cmd, tag) local function set_cmd(cmd, tag)
@ -202,7 +204,7 @@ function module.create(args_or_name, editor, default_cmd)
local wa = screen.workarea -- get the real workarea without the gap (instead of p.workarea) local wa = screen.workarea -- get the real workarea without the gap (instead of p.workarea)
local cls = p.clients local cls = p.clients
local tag = screen.selected_tag local tag = screen.selected_tag
local cd, td, areas, draft_mode = get_instance_data(screen, tag) local cd, td, areas, instance, new_placement_cb = get_instance_data(screen, tag)
if areas == nil then return end if areas == nil then return end
local nested_clients = {} local nested_clients = {}
@ -220,12 +222,14 @@ function module.create(args_or_name, editor, default_cmd)
in_draft = true in_draft = true
elseif cd[c].area then elseif cd[c].area then
in_draft = false in_draft = false
elseif new_placement_cb then
in_draft = new_placement_cb(c, instance, areas)
else else
in_draft = draft_mode in_draft = nil
end end
local skip = false local skip = false
if in_draft then if in_draft ~= false then
if cd[c].lu ~= nil and cd[c].rd ~= nil and if cd[c].lu ~= nil and cd[c].rd ~= nil and
cd[c].lu <= #areas and cd[c].rd <= #areas and cd[c].lu <= #areas and cd[c].rd <= #areas and
not areas[cd[c].lu].inhabitable and not areas[cd[c].rd].inhabitable not areas[cd[c].lu].inhabitable and not areas[cd[c].rd].inhabitable
@ -252,7 +256,15 @@ function module.create(args_or_name, editor, default_cmd)
end end
if lu ~= nil and rd ~= nil then if lu ~= nil and rd ~= nil then
cd[c].area, cd[c].lu, cd[c].rd = nil, lu, rd if lu == rd and cd[c].draft ~= true then
cd[c].lu = nil
cd[c].rd = nil
cd[c].area = lu
else
cd[c].lu = lu
cd[c].rd = rd
cd[c].area = nil
end
p.geometries[c] = {} p.geometries[c] = {}
module.set_geometry(p.geometries[c], areas[lu], areas[rd], useless_gap, 0) module.set_geometry(p.geometries[c], areas[lu], areas[rd], useless_gap, 0)
end end
@ -335,7 +347,7 @@ function module.create(args_or_name, editor, default_cmd)
local tag = c.screen.selected_tag local tag = c.screen.selected_tag
local instance = get_instance_(tag) local instance = get_instance_(tag)
local cd = instance.client_data local cd = instance.client_data
local cd, td, areas, draft_mode = get_instance_data(c.screen, tag) local cd, td, areas, _placement_cb = get_instance_data(c.screen, tag)
if areas == nil then return end if areas == nil then return end
@ -348,7 +360,8 @@ function module.create(args_or_name, editor, default_cmd)
elseif cd[c].area then elseif cd[c].area then
in_draft = false in_draft = false
else else
in_draft = draft_mode log(ERROR, "Assuming in_draft for unhandled client "..tostring(c))
in_draft = true
end end
if in_draft then if in_draft then
local lu = find_lu(h, areas) local lu = find_lu(h, areas)

View File

@ -78,7 +78,7 @@ function module.start(c, exit_keys)
if (c ~= nil and c.floating) or layout.machi_get_instance_data == nil then return end if (c ~= nil and c.floating) or layout.machi_get_instance_data == nil then return end
local cd, td, areas, draft_mode = layout.machi_get_instance_data(screen, screen.selected_tag) local cd, td, areas, _new_placement_cb = layout.machi_get_instance_data(screen, screen.selected_tag)
if areas == nil or #areas == 0 then if areas == nil or #areas == 0 then
return return
end end
@ -481,7 +481,8 @@ function module.start(c, exit_keys)
elseif cd[c].area then elseif cd[c].area then
in_draft = false in_draft = false
else else
in_draft = draft_mode log(ERROR, "Assuming in_draft for unhandled client "..tostring(c))
in_draft = true
end end
if in_draft then if in_draft then
c.x = areas[choice].x c.x = areas[choice].x
@ -547,13 +548,12 @@ function module.start(c, exit_keys)
exit() exit()
elseif (key == "f" or key == ".") and c then elseif (key == "f" or key == ".") and c then
if cd[c].draft == nil then if cd[c].draft == nil then
cd[c].draft = not draft_mode cd[c].draft = true
elseif cd[c].draft ~= draft_mode then elseif cd[c].draft == true then
cd[c].draft = draft_mode cd[c].draft = false
else else
cd[c].draft = nil cd[c].draft = nil
end end
print("set draft to", cd[c].draft, draft_mode)
awful.layout.arrange(screen) awful.layout.arrange(screen)
elseif key == "Escape" or key == "Return" then elseif key == "Escape" or key == "Return" then
exit() exit()