diff --git a/README.md b/README.md index be15807..b4f124c 100644 --- a/README.md +++ b/README.md @@ -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. 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. +4. There is no more per-layout setting of "draft mode". Every window has its own setting. ### 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()` -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. ## 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`. - `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. + 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. @@ -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). 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. -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 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. +Draft mode is suppose to work well with grid areas (produced by `d` or `w` operations), but it is not limited to those. +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. +You can also use `f` or `.` key in switcher UI to manually cycle through modes despit how the window previously spans areas. ### Nested layouts diff --git a/layout.lua b/layout.lua index 6f659d3..e0f272c 100644 --- a/layout.lua +++ b/layout.lua @@ -12,7 +12,7 @@ local DEBUG = -1 local module = { log_level = WARNING, - global_default_cmd = "dw66.", + global_default_cmd = "w66.", allow_shrinking_by_mouse_moving = false, } @@ -176,14 +176,16 @@ function module.create(args_or_name, editor, default_cmd) local workarea = screen.workarea local instance = get_instance_(tag) 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) if instance.areas_cache[key] == nil then instance.areas_cache[key] = args.editor.run_cmd(cmd, screen, tag) + if instance.areas_cache[key] == nil then + return + 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], draft_mode ~= nil + return instance.client_data, instance.tag_data, instance.areas_cache[key], instance, args.new_placement_cb end 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 cls = p.clients 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 local nested_clients = {} @@ -220,12 +222,14 @@ function module.create(args_or_name, editor, default_cmd) in_draft = true elseif cd[c].area then in_draft = false + elseif new_placement_cb then + in_draft = new_placement_cb(c, instance, areas) else - in_draft = draft_mode + in_draft = nil end local skip = false - if in_draft then + 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 @@ -252,7 +256,15 @@ function module.create(args_or_name, editor, default_cmd) end 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] = {} module.set_geometry(p.geometries[c], areas[lu], areas[rd], useless_gap, 0) end @@ -335,7 +347,7 @@ function module.create(args_or_name, editor, default_cmd) local tag = c.screen.selected_tag local instance = get_instance_(tag) 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 @@ -348,7 +360,8 @@ function module.create(args_or_name, editor, default_cmd) elseif cd[c].area then in_draft = false else - in_draft = draft_mode + log(ERROR, "Assuming in_draft for unhandled client "..tostring(c)) + in_draft = true end if in_draft then local lu = find_lu(h, areas) diff --git a/switcher.lua b/switcher.lua index 107a6c0..f37170c 100644 --- a/switcher.lua +++ b/switcher.lua @@ -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 - 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 return end @@ -481,7 +481,8 @@ function module.start(c, exit_keys) elseif cd[c].area then in_draft = false else - in_draft = draft_mode + log(ERROR, "Assuming in_draft for unhandled client "..tostring(c)) + in_draft = true end if in_draft then c.x = areas[choice].x @@ -547,13 +548,12 @@ function module.start(c, exit_keys) exit() elseif (key == "f" or key == ".") and c then if cd[c].draft == nil then - cd[c].draft = not draft_mode - elseif cd[c].draft ~= draft_mode then - cd[c].draft = draft_mode + cd[c].draft = true + elseif cd[c].draft == true then + cd[c].draft = false else cd[c].draft = nil end - print("set draft to", cd[c].draft, draft_mode) awful.layout.arrange(screen) elseif key == "Escape" or key == "Return" then exit()