Added/Implemented machi-editor
This commit is contained in:
672
lib/layout-machi/editor.lua
Normal file
672
lib/layout-machi/editor.lua
Normal file
@@ -0,0 +1,672 @@
|
||||
local this_package = ... and (...):match("(.-)[^%.]+$") or ""
|
||||
local machi_engine = require(this_package.."engine")
|
||||
local beautiful = require("beautiful")
|
||||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
local gears = require("gears")
|
||||
local gfs = require("gears.filesystem")
|
||||
local lgi = require("lgi")
|
||||
local dpi = require("beautiful.xresources").apply_dpi
|
||||
|
||||
local ERROR = 2
|
||||
local WARNING = 1
|
||||
local INFO = 0
|
||||
local DEBUG = -1
|
||||
|
||||
local module = {
|
||||
log_level = WARNING,
|
||||
nested_layouts = {
|
||||
["0"] = awful.layout.suit.tile,
|
||||
["1"] = awful.layout.suit.spiral,
|
||||
["2"] = awful.layout.suit.fair,
|
||||
["3"] = awful.layout.suit.fair.horizontal,
|
||||
},
|
||||
}
|
||||
|
||||
local function log(level, msg)
|
||||
if level > module.log_level then
|
||||
print(msg)
|
||||
end
|
||||
end
|
||||
|
||||
local function with_alpha(col, alpha)
|
||||
local r, g, b
|
||||
_, r, g, b, _ = col:get_rgba()
|
||||
return lgi.cairo.SolidPattern.create_rgba(r, g, b, alpha)
|
||||
end
|
||||
|
||||
local function max(a, b)
|
||||
if a < b then return b else return a end
|
||||
end
|
||||
|
||||
local function is_tiling(c)
|
||||
return
|
||||
not (c.tomb_floating or c.floating or c.maximized_horizontal or c.maximized_vertical or c.maximized or c.fullscreen)
|
||||
end
|
||||
|
||||
local function set_tiling(c)
|
||||
c.floating = false
|
||||
c.maximized = false
|
||||
c.maximized_vertical = false
|
||||
c.maximized_horizontal = false
|
||||
c.fullscreen = false
|
||||
end
|
||||
|
||||
local function _area_tostring(wa)
|
||||
return "{x:" .. tostring(wa.x) .. ",y:" .. tostring(wa.y) .. ",w:" .. tostring(wa.width) .. ",h:" .. tostring(wa.height) .. "}"
|
||||
end
|
||||
|
||||
local function shrink_area_with_gap(a, gap)
|
||||
return {
|
||||
x = a.x + gap,
|
||||
y = a.y + gap,
|
||||
width = a.width - gap * 2,
|
||||
height = a.height - gap * 2,
|
||||
}
|
||||
end
|
||||
|
||||
function module.restore_data(data)
|
||||
if data.history_file then
|
||||
local file, err = io.open(data.history_file, "r")
|
||||
if err then
|
||||
log(INFO, "cannot read history from " .. data.history_file)
|
||||
else
|
||||
data.cmds = {}
|
||||
data.last_cmd = {}
|
||||
local last_layout_name
|
||||
for line in file:lines() do
|
||||
if line:sub(1, 1) == "+" then
|
||||
last_layout_name = line:sub(2, #line)
|
||||
else
|
||||
if last_layout_name ~= nil then
|
||||
log(DEBUG, "restore last cmd " .. line .. " for " .. last_layout_name)
|
||||
data.last_cmd[last_layout_name] = line
|
||||
last_layout_name = nil
|
||||
else
|
||||
log(DEBUG, "restore cmd " .. line)
|
||||
data.cmds[#data.cmds + 1] = line
|
||||
end
|
||||
end
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
function module.create(data)
|
||||
if data == nil then
|
||||
data = module.restore_data({
|
||||
history_file = gfs.get_cache_dir() .. "/history_machi",
|
||||
history_save_max = 100,
|
||||
})
|
||||
end
|
||||
|
||||
data.cmds = data.cmds or {}
|
||||
data.last_cmd = data.last_cmd or {}
|
||||
data.minimum_size = data.minimum_size or 100
|
||||
|
||||
|
||||
local function add_cmd(instance_name, cmd)
|
||||
-- remove duplicated entries
|
||||
local j = 1
|
||||
for i = 1, #data.cmds do
|
||||
if data.cmds[i] ~= cmd then
|
||||
data.cmds[j] = data.cmds[i]
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
for i = #data.cmds, j, -1 do
|
||||
table.remove(data.cmds, i)
|
||||
end
|
||||
|
||||
data.cmds[#data.cmds + 1] = cmd
|
||||
data.last_cmd[instance_name] = cmd
|
||||
if data.history_file then
|
||||
local file, err = io.open(data.history_file, "w")
|
||||
if err then
|
||||
log(ERROR, "cannot save history to " .. data.history_file)
|
||||
else
|
||||
for i = max(1, #data.cmds - data.history_save_max + 1), #data.cmds do
|
||||
if data.cmds[i] ~= "." then
|
||||
log(DEBUG, "save cmd " .. data.cmds[i])
|
||||
file:write(data.cmds[i] .. "\n")
|
||||
end
|
||||
end
|
||||
for name, cmd in pairs(data.last_cmd) do
|
||||
log(DEBUG, "save last cmd " .. cmd .. " for " .. name)
|
||||
file:write("+" .. name .. "\n" .. cmd .. "\n")
|
||||
end
|
||||
end
|
||||
file:close()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
local function start_interactive(screen, embed_args)
|
||||
local info_size = dpi(60)
|
||||
-- colors are in rgba
|
||||
local border_color = with_alpha(
|
||||
gears.color(beautiful.machi_editor_border_color or beautiful.border_focus),
|
||||
beautiful.machi_editor_border_opacity or 0.75)
|
||||
local active_color = with_alpha(
|
||||
gears.color(beautiful.machi_editor_active_color or beautiful.bg_focus),
|
||||
beautiful.machi_editor_active_opacity or 0.5)
|
||||
local open_color = with_alpha(
|
||||
gears.color(beautiful.machi_editor_open_color or beautiful.bg_normal),
|
||||
beautiful.machi_editor_open_opacity or 0.5)
|
||||
local done_color = with_alpha(
|
||||
gears.color(beautiful.machi_editor_done_color or beautiful.bg_focus),
|
||||
beautiful.machi_editor_done_opacity or 0.5)
|
||||
local closed_color = open_color
|
||||
|
||||
if to_save == nil then
|
||||
to_save = true
|
||||
end
|
||||
|
||||
screen = screen or awful.screen.focused()
|
||||
local tag = screen.selected_tag
|
||||
local prev_layout = nil
|
||||
|
||||
if tag.layout.machi_set_cmd == nil then
|
||||
prev_layout = tag.layout
|
||||
for _, l in ipairs(awful.layout.layouts) do
|
||||
if l.machi_set_cmd ~= nil then
|
||||
awful.layout.set(l, tag)
|
||||
naughty.notify {
|
||||
text = 'Switched layout to machi',
|
||||
timeout = 2
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local gap = tag.gap or 0
|
||||
local layout = tag.layout
|
||||
|
||||
if layout.machi_set_cmd == nil then
|
||||
naughty.notify {
|
||||
text = "The layout to edit is not machi",
|
||||
timeout = 3
|
||||
}
|
||||
return
|
||||
end
|
||||
|
||||
local cmd_index = #data.cmds + 1
|
||||
data.cmds[cmd_index] = ""
|
||||
|
||||
local start_x = screen.workarea.x
|
||||
local start_y = screen.workarea.y
|
||||
|
||||
local kg
|
||||
local infobox = wibox({
|
||||
screen = screen,
|
||||
x = screen.workarea.x,
|
||||
y = screen.workarea.y,
|
||||
width = screen.workarea.width,
|
||||
height = screen.workarea.height,
|
||||
bg = "#ffffff00",
|
||||
opacity = 1,
|
||||
ontop = true,
|
||||
type = "dock",
|
||||
})
|
||||
infobox.visible = true
|
||||
|
||||
workarea = embed_args and embed_args.workarea or screen.workarea
|
||||
|
||||
local closed_areas
|
||||
local open_areas
|
||||
local pending_op
|
||||
local current_cmd
|
||||
local to_exit
|
||||
local to_apply
|
||||
|
||||
local key_translate_tab = {
|
||||
["Return"] = ".",
|
||||
[" "] = "-",
|
||||
}
|
||||
|
||||
local curpos = 0
|
||||
local current_info_pre = ""
|
||||
local current_info_post = ""
|
||||
local current_msg
|
||||
|
||||
local function set_cmd(cmd, arbitrary_input)
|
||||
local new_closed_areas, new_open_areas, new_pending_op = machi_engine.areas_from_command(
|
||||
cmd,
|
||||
{
|
||||
x = workarea.x + gap,
|
||||
y = workarea.y + gap,
|
||||
width = workarea.width - gap * 2,
|
||||
height = workarea.height - gap * 2
|
||||
},
|
||||
gap * 2 + data.minimum_size)
|
||||
if new_closed_areas or not arbitrary_input then
|
||||
if new_closed_areas then
|
||||
closed_areas, open_areas, pending_op =
|
||||
new_closed_areas, new_open_areas, new_pending_op
|
||||
end
|
||||
current_cmd = cmd
|
||||
|
||||
current_info_pre = current_cmd:sub(0, curpos)
|
||||
current_info_post = current_cmd:sub(curpos+1, #current_cmd)
|
||||
if embed_args then
|
||||
current_info_pre = embed_args.cmd_prefix.."["..current_info_pre
|
||||
current_info_post = current_info_post.."]"..embed_args.cmd_suffix
|
||||
end
|
||||
|
||||
current_msg = ""
|
||||
if new_closed_areas and #open_areas == 0 and not pending_op then
|
||||
current_msg = "(enter to apply)"
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local move_cursor = function(n)
|
||||
curpos = curpos + n
|
||||
if curpos > #current_cmd then
|
||||
curpos = #current_cmd
|
||||
elseif curpos < 0 then
|
||||
curpos = 0
|
||||
end
|
||||
-- trigger refresh
|
||||
set_cmd(current_cmd)
|
||||
end
|
||||
|
||||
|
||||
local function handle_key(key)
|
||||
if key_translate_tab[key] ~= nil then
|
||||
key = key_translate_tab[key]
|
||||
end
|
||||
|
||||
return set_cmd(current_cmd:sub(0, curpos)..key..current_cmd:sub(curpos+1, #current_cmd), true)
|
||||
end
|
||||
|
||||
|
||||
local function cleanup()
|
||||
infobox.visible = false
|
||||
if prev_layout ~= nil then
|
||||
awful.layout.set(prev_layout, tag)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_info(context, cr, width, height)
|
||||
cr:set_source_rgba(0, 0, 0, 0)
|
||||
cr:rectangle(0, 0, width, height)
|
||||
cr:fill()
|
||||
|
||||
local msg, ext
|
||||
|
||||
for i, a in ipairs(closed_areas) do
|
||||
if a.habitable then
|
||||
local sa = shrink_area_with_gap(a, gap)
|
||||
local to_highlight = false
|
||||
if pending_op ~= nil then
|
||||
to_highlight = a.group_id == op_count
|
||||
end
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:clip()
|
||||
if to_highlight then
|
||||
cr:set_source(done_color)
|
||||
else
|
||||
cr:set_source(closed_color)
|
||||
end
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:fill()
|
||||
cr:set_source(border_color)
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:set_line_width(10.0)
|
||||
cr:stroke()
|
||||
cr:reset_clip()
|
||||
end
|
||||
end
|
||||
|
||||
for i, a in ipairs(open_areas) do
|
||||
local sa = shrink_area_with_gap(a, gap)
|
||||
local to_highlight = false
|
||||
if not pending_op then
|
||||
to_highlight = i == #open_areas
|
||||
else
|
||||
to_highlight = a.group_id == op_count
|
||||
end
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:clip()
|
||||
if i == #open_areas then
|
||||
cr:set_source(active_color)
|
||||
else
|
||||
cr:set_source(open_color)
|
||||
end
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:fill()
|
||||
|
||||
cr:set_source(border_color)
|
||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||
cr:set_line_width(10.0)
|
||||
if to_highlight then
|
||||
cr:stroke()
|
||||
else
|
||||
cr:set_dash({5, 5}, 0)
|
||||
cr:stroke()
|
||||
cr:set_dash({}, 0)
|
||||
end
|
||||
cr:reset_clip()
|
||||
end
|
||||
|
||||
local pl = lgi.Pango.Layout.create(cr)
|
||||
pl:set_font_description(beautiful.get_merged_font(beautiful.font, info_size))
|
||||
pl:set_alignment("CENTER")
|
||||
pl:set_text(current_info_pre)
|
||||
local w0, _ = pl:get_pixel_size()
|
||||
pl:set_text(current_info_pre..current_info_post)
|
||||
local w, h = pl:get_pixel_size()
|
||||
|
||||
local pl_msg = lgi.Pango.Layout.create(cr)
|
||||
pl_msg:set_font_description(beautiful.get_merged_font(beautiful.font, info_size))
|
||||
pl_msg:set_alignment("CENTER")
|
||||
pl_msg:set_text(current_msg)
|
||||
local w_msg, h_msg = pl_msg:get_pixel_size()
|
||||
local lh = pl_msg:get_line_spacing()
|
||||
|
||||
local draw = function(pl, w, h, y_offset, color)
|
||||
local ext = { width = w, height = h, x_bearing = 0, y_bearing = 0 }
|
||||
cr:move_to(
|
||||
width / 2 - ext.width / 2 - ext.x_bearing,
|
||||
y_offset + height / 2 - ext.height / 2 - ext.y_bearing
|
||||
)
|
||||
if color then
|
||||
cr:set_source(color)
|
||||
else
|
||||
cr:set_source_rgba(1, 1, 1, 1)
|
||||
end
|
||||
cr:show_layout(pl)
|
||||
cr:fill()
|
||||
end
|
||||
local wpad, hpad = dpi(50), dpi(5)
|
||||
local mw, mh = max(w, w_msg) + wpad, h + hpad
|
||||
if current_msg ~= "" then
|
||||
mh = mh + h_msg + lh
|
||||
end
|
||||
if mw < dpi(120) then
|
||||
mw = dpi(120)
|
||||
end
|
||||
cr:rectangle(width / 2 - mw / 2, height / 2 - (h + hpad) / 2, mw, mh)
|
||||
cr:set_source_rgba(0, 0, 0, 1)
|
||||
cr:fill()
|
||||
local cursor_border = 0
|
||||
local cursor_width = 1
|
||||
if cursor_border >= 0 then
|
||||
cr:rectangle(
|
||||
width / 2 - w / 2 + w0,
|
||||
height / 2 - h / 2 + lh,
|
||||
2 * cursor_border + cursor_width,
|
||||
h
|
||||
)
|
||||
cr:set_source_rgba(0, 0, 0, 0.8)
|
||||
cr:fill()
|
||||
end
|
||||
cr:rectangle(
|
||||
cursor_border + width / 2 - w / 2 + w0,
|
||||
cursor_border + height / 2 - h / 2 + lh,
|
||||
cursor_width,
|
||||
h - 2 * cursor_border
|
||||
)
|
||||
cr:set_source_rgba(1, 1, 1, 1)
|
||||
cr:fill()
|
||||
draw(pl, w, h, lh)
|
||||
draw(pl_msg, w_msg, h_msg, h + lh)
|
||||
end
|
||||
|
||||
local function refresh()
|
||||
log(DEBUG, "closed areas:")
|
||||
for i, a in ipairs(closed_areas) do
|
||||
log(DEBUG, " " .. _area_tostring(a))
|
||||
end
|
||||
log(DEBUG, "open areas:")
|
||||
for i, a in ipairs(open_areas) do
|
||||
log(DEBUG, " " .. _area_tostring(a))
|
||||
end
|
||||
infobox.bgimage = draw_info
|
||||
end
|
||||
|
||||
local function get_final_cmd()
|
||||
local final_cmd = current_cmd
|
||||
if embed_args then
|
||||
final_cmd = embed_args.cmd_prefix ..
|
||||
machi_engine.areas_to_command(closed_areas, true) ..
|
||||
embed_args.cmd_suffix
|
||||
end
|
||||
return final_cmd
|
||||
end
|
||||
|
||||
log(DEBUG, "interactive layout editing starts")
|
||||
|
||||
set_cmd("")
|
||||
refresh()
|
||||
|
||||
kg = awful.keygrabber.run(
|
||||
function (mod, key, event)
|
||||
if event == "release" then
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = pcall(
|
||||
function ()
|
||||
if key == "Left" then
|
||||
move_cursor(-1)
|
||||
elseif key == "Right" then
|
||||
move_cursor(1)
|
||||
elseif key == "BackSpace" then
|
||||
local alt = false
|
||||
for _, m in ipairs(mod) do
|
||||
if m == "Shift" then
|
||||
alt = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if alt then
|
||||
if embed_args then
|
||||
set_cmd(embed_args.original_cmd or "")
|
||||
else
|
||||
local _cd, _td, areas = layout.machi_get_instance_data(screen, tag)
|
||||
set_cmd(machi_engine.areas_to_command(areas))
|
||||
end
|
||||
else
|
||||
local s = curpos - 1
|
||||
if s < 0 then
|
||||
s = 0
|
||||
end
|
||||
set_cmd(current_cmd:sub(0, s)..current_cmd:sub(curpos+1, #current_cmd))
|
||||
move_cursor(-1)
|
||||
end
|
||||
elseif key == "Escape" then
|
||||
table.remove(data.cmds, #data.cmds)
|
||||
to_exit = true
|
||||
elseif key == "Up" or key == "Down" then
|
||||
if current_cmd ~= data.cmds[cmd_index] then
|
||||
data.cmds[#data.cmds] = current_cmd
|
||||
end
|
||||
|
||||
if key == "Up" and cmd_index > 1 then
|
||||
cmd_index = cmd_index - 1
|
||||
elseif key == "Down" and cmd_index < #data.cmds then
|
||||
cmd_index = cmd_index + 1
|
||||
end
|
||||
|
||||
log(DEBUG, "restore history #" .. tostring(cmd_index) .. ":" .. data.cmds[cmd_index])
|
||||
set_cmd(data.cmds[cmd_index])
|
||||
move_cursor(#data.cmds[cmd_index])
|
||||
elseif #open_areas > 0 or pending_op or curpos < #current_cmd then
|
||||
if key == "." or key == "Return" then
|
||||
move_cursor(#current_cmd)
|
||||
end
|
||||
if handle_key(key) then
|
||||
move_cursor(1)
|
||||
end
|
||||
else
|
||||
if key == "Return" then
|
||||
local alt = false
|
||||
for _, m in ipairs(mod) do
|
||||
if m == "Shift" then
|
||||
alt = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local instance_name, persistent = layout.machi_get_instance_info(tag)
|
||||
if not alt and persistent then
|
||||
table.remove(data.cmds, #data.cmds)
|
||||
add_cmd(instance_name, get_final_cmd())
|
||||
current_msg = "Saved!"
|
||||
else
|
||||
current_msg = "Applied"
|
||||
end
|
||||
|
||||
to_exit = true
|
||||
to_apply = true
|
||||
end
|
||||
end
|
||||
|
||||
refresh()
|
||||
|
||||
if to_exit then
|
||||
log(DEBUG, "interactive layout editing ends")
|
||||
if to_apply then
|
||||
layout.machi_set_cmd(get_final_cmd(), tag)
|
||||
awful.layout.arrange(screen)
|
||||
gears.timer{
|
||||
timeout = 1,
|
||||
autostart = true,
|
||||
singleshot = true,
|
||||
callback = cleanup,
|
||||
}
|
||||
else
|
||||
cleanup()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
log(ERROR, "Getting error in keygrabber: " .. err)
|
||||
to_exit = true
|
||||
cleanup()
|
||||
end
|
||||
|
||||
if to_exit then
|
||||
awful.keygrabber.stop(kg)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function run_cmd(cmd, screen, tag)
|
||||
local gap = tag.gap
|
||||
local areas, closed = machi_engine.areas_from_command(
|
||||
cmd,
|
||||
{
|
||||
x = screen.workarea.x + gap,
|
||||
y = screen.workarea.y + gap,
|
||||
width = screen.workarea.width - gap * 2,
|
||||
height = screen.workarea.height - gap * 2
|
||||
},
|
||||
gap * 2 + data.minimum_size)
|
||||
if not areas or #closed > 0 then
|
||||
return nil
|
||||
end
|
||||
for _, a in ipairs(areas) do
|
||||
a.x = a.x + gap
|
||||
a.y = a.y + gap
|
||||
a.width = a.width - gap * 2
|
||||
a.height = a.height - gap * 2
|
||||
end
|
||||
return areas
|
||||
end
|
||||
|
||||
local function get_last_cmd(name)
|
||||
return data.last_cmd[name]
|
||||
end
|
||||
|
||||
function adjust_shares(c, axis, adj)
|
||||
if not c:isvisible() or c.floating or c.immobilized then
|
||||
return
|
||||
end
|
||||
local screen = c.screen
|
||||
local tag = screen.selected_tag
|
||||
local layout = tag.layout
|
||||
if not layout.machi_get_instance_data then return end
|
||||
local cd, _td, areas = layout.machi_get_instance_data(screen, tag)
|
||||
local key_shares = axis.."_shares"
|
||||
local key_spare = axis.."_spare"
|
||||
local key_parent_shares = "parent_"..axis.."_shares"
|
||||
|
||||
if not cd[c] or not cd[c].area then
|
||||
return
|
||||
end
|
||||
|
||||
if adj < 0 then
|
||||
if axis == "x" and c.width + adj < data.minimum_size then
|
||||
adj = data.minimum_size - c.width
|
||||
elseif axis == "y" and c.height + adj < data.minimum_size then
|
||||
adj = data.minimum_size - c.height
|
||||
end
|
||||
end
|
||||
|
||||
local function adjust(parent_id, shares, adj)
|
||||
-- The propagation part is questionable. But it is not critical anyway..
|
||||
if type(shares) ~= "table" then
|
||||
local old = areas[parent_id].split[key_shares][shares][2] or 0
|
||||
areas[parent_id].split[key_shares][shares][2] = old + adj
|
||||
else
|
||||
local acc = 0
|
||||
for i = 1, #shares do
|
||||
local old = areas[parent_id].split[key_shares][shares[i]][2] or 0
|
||||
local adj_split = i == #shares and adj - acc or math.floor(adj * i / #shares - acc + 0.5)
|
||||
areas[parent_id].split[key_shares][shares[i]][2] = old + adj_split
|
||||
acc = acc + adj_split
|
||||
end
|
||||
end
|
||||
if adj <= 0 then
|
||||
return #areas[parent_id].split[key_shares] > 1
|
||||
else
|
||||
return areas[parent_id].split[key_spare] >= adj
|
||||
end
|
||||
end
|
||||
|
||||
local area = cd[c].area
|
||||
while areas[area].parent_id do
|
||||
if adjust(areas[area].parent_id, areas[area][key_parent_shares], adj) then
|
||||
break
|
||||
end
|
||||
area = areas[area].parent_id
|
||||
end
|
||||
|
||||
layout.machi_set_cmd(machi_engine.areas_to_command(areas), tag, true)
|
||||
awful.layout.arrange(screen)
|
||||
end
|
||||
|
||||
function adjust_x_shares(c, adj)
|
||||
adjust_shares(c, "x", adj)
|
||||
end
|
||||
|
||||
function adjust_y_shares(c, adj)
|
||||
adjust_shares(c, "y", adj)
|
||||
end
|
||||
|
||||
return {
|
||||
start_interactive = start_interactive,
|
||||
run_cmd = run_cmd,
|
||||
get_last_cmd = get_last_cmd,
|
||||
adjust_x_shares = adjust_x_shares,
|
||||
adjust_y_shares = adjust_y_shares,
|
||||
}
|
||||
end
|
||||
|
||||
module.default_editor = module.create()
|
||||
|
||||
return module
|
||||
Reference in New Issue
Block a user