Per-window setting of draft mode.

This commit is contained in:
Xinhao Yuan 2021-02-26 20:21:21 -05:00
parent b8a08279cf
commit ee08eecb49
3 changed files with 136 additions and 123 deletions

View File

@ -269,6 +269,8 @@ The geometry of the window is from the upper-left corner of the UL to the bottom
This is suppose to work with areas 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`.
__New in machi-ng:__ draft mode can be overrided by per-window settings. Use `f` or `.` key in switcher UI, or change the `c.machi_draft` boolean for window `c`.
### Nested layouts
__This feature is a toy. It may come with performance and usability issues - you have been warned.__
@ -279,7 +281,7 @@ Known caveats include:
2. `client.*wfact` and other layout related operations don't work as machi fakes tag data to the nested layout engine.
But it hopefully works if one changes the fields in the faked tag data.
__This feature is not available in draft mode.__
__This feature is not available for windows 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 area to the mapped one.
@ -302,8 +304,9 @@ Calling `machi.switcher.start()` will create a switcher supporting the following
- `Shift` + arrow keys: move the focused window to other areas by the direction. In draft mode, move the window while preserving its size.
- `Control`[ + `Shift`] + arrow keys: move the bottom-right (or top-left window if `Shift` is pressed) area of the focused window by direction. Only works in draft mode.
- `Tab`: switch beteen windows covering the current areas.
- `u` or `PageUp` (`Prior`): In non-draft mode, you can select the parent of the current area.
- `/`: In non-draft mode, this opens the editor to edit the selected area using the same command interpretation.
- `u` or `PageUp` (`Prior`): select the parent of the current area.
- `f` or `.`: toggle the per-window setting of draft mode.
- `/`: open the editor to edit the selected area using the same command interpretation.
Note the final command may be transcoded to be embeddable, but the areas shall be the same.
So far, the key binding is not configurable. One has to modify the source code to change it.

View File

@ -212,12 +212,15 @@ function module.create(args_or_name, editor, default_cmd)
end
end
if draft_mode then
for i, c in ipairs(cls) do
if c.floating or c.immobilized then
log(DEBUG, "Ignore client " .. tostring(c))
else
local skip = false
for i, c in ipairs(cls) do
if c.floating or c.immobilized then
log(DEBUG, "Ignore client " .. tostring(c))
else
local in_draft = c.machi_draft
if in_draft == nil then in_draft = draft_mode end
local skip = false
if in_draft then
if c.machi.lu ~= nil and c.machi.rd ~= nil and
c.machi.lu <= #areas and c.machi.rd <= #areas and
not areas[c.machi.lu].inhabitable and not areas[c.machi.rd].inhabitable
@ -249,12 +252,6 @@ function module.create(args_or_name, editor, default_cmd)
p.geometries[c] = {}
module.set_geometry(p.geometries[c], areas[lu], areas[rd], useless_gap, 0)
end
end
end
else
for i, c in ipairs(cls) do
if c.floating or c.immobilized then
log(DEBUG, "Ignore client " .. tostring(c))
else
if c.machi.area ~= nil and
c.machi.area < #areas and
@ -281,62 +278,64 @@ function module.create(args_or_name, editor, default_cmd)
end
end
end
end
for area, clients in pairs(nested_clients) do
if instance.tag_data[area] == nil then
-- TODO: Make the default more flexible.
instance.tag_data[area] = {
column_count = 1,
master_count = 1,
master_fill_policy = "expand",
gap = 0,
master_width_factor = 0.5,
_private = {
awful_tag_properties = {
},
for area, clients in pairs(nested_clients) do
if instance.tag_data[area] == nil then
-- TODO: Make the default more flexible.
instance.tag_data[area] = {
column_count = 1,
master_count = 1,
master_fill_policy = "expand",
gap = 0,
master_width_factor = 0.5,
_private = {
awful_tag_properties = {
},
}
end
local nested_params = {
tag = instance.tag_data[area],
screen = p.screen,
clients = clients,
padding = 0,
geometry = {
x = areas[area].x,
y = areas[area].y,
width = areas[area].width,
height = areas[area].height,
},
-- Not sure how useless_gap adjustment works here. It seems to work anyway.
workarea = {
x = areas[area].x - useless_gap,
y = areas[area].y - useless_gap,
width = areas[area].width + useless_gap * 2,
height = areas[area].height + useless_gap * 2,
},
useless_gap = useless_gap,
geometries = {},
}
machi_editor.nested_layouts[areas[area].layout].arrange(nested_params)
for _, c in ipairs(clients) do
p.geometries[c] = {
x = nested_params.geometries[c].x,
y = nested_params.geometries[c].y,
width = nested_params.geometries[c].width,
height = nested_params.geometries[c].height,
}
end
end
local nested_params = {
tag = instance.tag_data[area],
screen = p.screen,
clients = clients,
padding = 0,
geometry = {
x = areas[area].x,
y = areas[area].y,
width = areas[area].width,
height = areas[area].height,
},
-- Not sure how useless_gap adjustment works here. It seems to work anyway.
workarea = {
x = areas[area].x - useless_gap,
y = areas[area].y - useless_gap,
width = areas[area].width + useless_gap * 2,
height = areas[area].height + useless_gap * 2,
},
useless_gap = useless_gap,
geometries = {},
}
machi_editor.nested_layouts[areas[area].layout].arrange(nested_params)
for _, c in ipairs(clients) do
p.geometries[c] = {
x = nested_params.geometries[c].x,
y = nested_params.geometries[c].y,
width = nested_params.geometries[c].width,
height = nested_params.geometries[c].height,
}
end
end
end
local function resize_handler (c, context, h)
local areas, draft_mode = get_areas(c.screen, c.screen.selected_tag)
if areas == nil then return end
if #areas == 0 then return end
local in_draft = c.machi_draft
if in_draft == nil then in_draft = draft_mode end
if draft_mode then
if in_draft then
local lu = find_lu(h, areas)
local rd = nil
if lu ~= nil then
@ -375,25 +374,25 @@ function module.create(args_or_name, editor, default_cmd)
else
if context ~= "mouse.move" then return end
if #areas == 0 then return end
local center_x = h.x + h.width / 2
local center_y = h.y + h.height / 2
local choice = 1
local choice = nil
local choice_value = nil
for i, r in ipairs(areas) 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)
if choice_value == nil or choice_value > dis then
choice = i
choice_value = dis
for i, a in ipairs(areas) do
if not a.inhabitable then
local ac_x = a.x + a.width / 2
local ac_y = a.y + a.height / 2
local dis = (ac_x - center_x) * (ac_x - center_x) + (ac_y - center_y) * (ac_y - center_y)
if choice_value == nil or choice_value > dis then
choice = i
choice_value = dis
end
end
end
if c.machi.area ~= choice then
if choice and c.machi.area ~= choice then
c.machi.area = choice
module.set_geometry(c, areas[choice], areas[choice], 0, c.border_width)
end

View File

@ -430,74 +430,78 @@ function module.start(c, exit_keys)
tablist = nil
set_selected_area(nil)
if c and ctrl and draft_mode then
local lu = c.machi.lu
local rd = c.machi.rd
if c then
local in_draft = c and c.machi_draft
if in_draft == nil then in_draft = draft_mode end
if ctrl and in_draft then
local lu = c.machi.lu
local rd = c.machi.rd
if shift then
lu = choice
if areas[rd].x + areas[rd].width <= areas[lu].x or
areas[rd].y + areas[rd].height <= areas[lu].y
then
rd = nil
end
else
rd = choice
if areas[rd].x + areas[rd].width <= areas[lu].x or
areas[rd].y + areas[rd].height <= areas[lu].y
then
lu = nil
end
end
if shift then
lu = choice
if areas[rd].x + areas[rd].width <= areas[lu].x or
areas[rd].y + areas[rd].height <= areas[lu].y
then
rd = nil
end
else
rd = choice
if areas[rd].x + areas[rd].width <= areas[lu].x or
areas[rd].y + areas[rd].height <= areas[lu].y
then
lu = nil
end
end
if lu ~= nil and rd ~= nil then
machi.layout.set_geometry(c, areas[lu], areas[rd], 0, c.border_width)
elseif lu ~= nil then
machi.layout.set_geometry(c, areas[lu], nil, 0, c.border_width)
elseif rd ~= nil then
c.x = min(c.x, areas[rd].x)
c.y = min(c.y, areas[rd].y)
machi.layout.set_geometry(c, nil, areas[rd], 0, c.border_width)
end
c.machi.lu = lu
c.machi.rd = rd
if lu ~= nil and rd ~= nil then
machi.layout.set_geometry(c, areas[lu], areas[rd], 0, c.border_width)
elseif lu ~= nil then
machi.layout.set_geometry(c, areas[lu], nil, 0, c.border_width)
elseif rd ~= nil then
c.x = min(c.x, areas[rd].x)
c.y = min(c.y, areas[rd].y)
machi.layout.set_geometry(c, nil, areas[rd], 0, c.border_width)
end
c.machi.lu = lu
c.machi.rd = rd
c:emit_signal("request::activate", "mouse.move", {raise=false})
c:raise()
api.layout.arrange(screen)
elseif c and shift then
-- move the window
if draft_mode then
c.x = areas[choice].x
c.y = areas[choice].y
else
machi.layout.set_geometry(c, areas[choice], areas[choice], 0, c.border_width)
c.machi.area = choice
end
c:emit_signal("request::activate", "mouse.move", {raise=false})
c:raise()
api.layout.arrange(screen)
c:emit_signal("request::activate", "mouse.move", {raise=false})
c:raise()
api.layout.arrange(screen)
elseif shift then
-- move the window
if in_draft then
c.x = areas[choice].x
c.y = areas[choice].y
else
machi.layout.set_geometry(c, areas[choice], areas[choice], 0, c.border_width)
c.machi.area = choice
end
c:emit_signal("request::activate", "mouse.move", {raise=false})
c:raise()
api.layout.arrange(screen)
tablist = nil
tablist = nil
end
else
maintain_tablist()
-- move the focus
if #tablist > 0 and tablist[1] ~= c then
c = tablist[1]
api.client.focus = c
end
maintain_tablist()
-- move the focus
if #tablist > 0 and tablist[1] ~= c then
c = tablist[1]
api.client.focus = c
end
end
infobox.bgimage = draw_info
end
elseif (key == "u" or key == "Prior") and not draft_mode then
elseif (key == "u" or key == "Prior") then
local current_area = selected_area()
if areas[current_area].parent_id then
tablist = nil
set_selected_area(areas[current_area].parent_id)
infobox.bgimage = draw_info
end
elseif key == "/" and not draft_mode then
elseif key == "/" then
local current_area = selected_area()
local original_cmd = machi.engine.areas_to_command(areas, true, current_area)
areas[current_area].hole = true
@ -526,6 +530,13 @@ function module.start(c, exit_keys)
end
)
exit()
elseif (key == "f" or key == ".") and c then
if c.machi_draft == nil then
c.machi_draft = not draft_mode
else
c.machi_draft = not c.machi_draft
end
api.layout.arrange(screen)
elseif key == "Escape" or key == "Return" then
exit()
else