Hello,
I have played around with awesome for quite a couple of years, but
although I *love* the programability, tiled window managing is just
something I can not readily adjust to.
To be able to use it efficiently I need edge resize. I love to just
throw a window into a corner or side and it resizes in the corner or
over the side. I always buy laptops with a nipple-mouse in the keyboard
so it works extremely well for me and my workflows.
Because it is basically the only missing feature I need to switch from
KDE I dug into the sources and wrote the attached patch. if you use
mouse.client.move_edgeresize instead of mouse.client.move it resizes on
coming near the edges.
I think I will work on it in the future because I am not really sure
what I want when touching the middle top and bottom zones, but it would
be great if it could be merged.
Also if you have any suggestions I'l be greatful.
Thank you,
Best
Ray
--- init.lua.original 2015-05-03 12:18:20.446237302 +0200
+++ init.lua 2015-05-03 16:20:55.572569401 +0200
@@ -64,6 +64,95 @@
return g
end
+local function snap_edge(g, sg, mg)
+ local snap = snap or 8
+ local edges = { vertical = {upper = math.abs((sg.height + sg.y) / 3),
+ middle = math.abs(((sg.height + sg.y) / 3) * 2),
+ lower = sg.height},
+
+ horizontal = {left = math.abs(sg.width / 3),
+ middle = math.abs((sg.width / 3) * 2),
+ right = sg.width + sg.y}}
+
+ local edge_pos = nil
+
+ if mg.x <= (sg.x + 8) and not (mg.y >= (sg.height + sg.y - 8))then
+ edge_pos = 'left'
+ elseif mg.x >= (sg.width - 8) and not (mg.y >= (sg.height + sg.y - 8)) then
+ edge_pos = 'right'
+ elseif mg.y <= (sg.y + 8) then
+ edge_pos = 'top'
+ elseif mg.y >= (sg.height + sg.y - 8) then
+ edge_pos = 'bottom'
+ end
+
+ if edge_pos then
+ if edge_pos == 'left' then
+ if mg.y < edges['vertical']['upper'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.y
+ g.x = sg.x
+ elseif mg.y < edges['vertical']['middle'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = sg.height
+ g.y = sg.y
+ g.x = sg.x
+ elseif mg.y < edges['vertical']['lower'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.height - g.height + sg.y
+ g.x = sg.x
+ end
+ elseif edge_pos == 'right' then
+ if mg.y < edges['vertical']['upper'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.y
+ g.x = sg.width - g.width + 1
+ elseif mg.y < edges['vertical']['middle'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = sg.height
+ g.y = sg.y
+ g.x = sg.width - g.width + 1
+ elseif mg.y < edges['vertical']['lower'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.height - g.height + sg.y
+ g.x = sg.width - g.width + 1
+ end
+ elseif edge_pos == 'top' then
+ if mg.x < edges['horizontal']['left'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.y
+ g.x = sg.x
+ elseif mg.x < edges['horizontal']['middle'] then
+ elseif mg.x < edges['horizontal']['right'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.y
+ g.x = sg.width - g.width + 1
+ end
+ elseif edge_pos == 'bottom' then
+ if mg.x < edges['horizontal']['left'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.height - g.height + sg.y
+ g.x = sg.x
+ elseif mg.x < edges['horizontal']['middle'] then
+ elseif mg.x < edges['horizontal']['right'] then
+ g.width = math.abs(sg.width / 2)
+ g.height = math.abs(sg.height / 2)
+ g.y = sg.height - g.height + sg.y
+ g.x = sg.width - g.width + 1
+ end
+ end
+ end
+
+ return g
+end
+
local function snap_inside(g, sg, snap)
local edgev = 'none'
local edgeh = 'none'
@@ -97,8 +186,9 @@
-- @param y The client y coordinate.
-- @param fixed_x True if the client isn't allowed to move in the x direction.
-- @param fixed_y True if the client isn't allowed to move in the y direction.
-function mouse.client.snap(c, snap, x, y, fixed_x, fixed_y)
+function mouse.client.snap(c, snap, x, y, fixed_x, fixed_y, edge_resize)
local snap = snap or 8
+ local edge_resize = edge_resize or false
local c = c or mouse.client.focus
local cur_geom = c:geometry()
local geom = c:geometry()
@@ -109,9 +199,13 @@
geom.x = x or geom.x
geom.y = y or geom.y
- geom, edge = snap_inside(geom, capi.screen[c.screen].geometry, snap)
- geom = snap_inside(geom, capi.screen[c.screen].workarea, snap)
-
+ if edge_resize then
+ geom = snap_edge(geom, capi.screen[c.screen].workarea, capi.mouse.coords())
+ else
+ geom, edge = snap_inside(geom, capi.screen[c.screen].geometry, snap)
+ geom = snap_inside(geom, capi.screen[c.screen].workarea, snap)
+ end
+
-- Allow certain windows to snap to the edge of the workarea.
-- Only allow docking to workarea for consistency/to avoid problems.
if aclient.dockable.get(c) then
@@ -133,10 +227,12 @@
geom.x = geom.x - (2 * c.border_width)
geom.y = geom.y - (2 * c.border_width)
- for k, snapper in ipairs(aclient.visible(c.screen)) do
- if snapper ~= c then
- geom = snap_outside(geom, snapper:geometry(), snap)
- end
+ if not edge_resize then
+ for k, snapper in ipairs(aclient.visible(c.screen)) do
+ if snapper ~= c then
+ geom = snap_outside(geom, snapper:geometry(), snap)
+ end
+ end
end
geom.width = geom.width - (2 * c.border_width)
@@ -151,10 +247,18 @@
return geom
end
+--- Move a client, on Edges resize the client.
+-- @param c The client to move, or the focused one if nil.
+-- @param snap The pixel to snap clients.
+function mouse.client.move_edgeresize(c, snap)
+ mouse.client.move(c, snap, true)
+end
+
--- Move a client.
-- @param c The client to move, or the focused one if nil.
-- @param snap The pixel to snap clients.
-function mouse.client.move(c, snap)
+-- @param edge_resize resize the window on screen edges
+function mouse.client.move(c, snap, edge_resize)
local c = c or capi.client.focus
if not c
@@ -165,6 +269,10 @@
return
end
+ if not edge_resize then
+ edge_resize = false
+ end
+
local orig = c:geometry()
local m_c = capi.mouse.coords()
local dist_x = m_c.x - orig.x
@@ -180,7 +288,7 @@
if lay == layout.suit.floating or aclient.floating.get(c) then
local x = _mouse.x - dist_x
local y = _mouse.y - dist_y
- c:geometry(mouse.client.snap(c, snap, x, y, fixed_x, fixed_y))
+ c:geometry(mouse.client.snap(c, snap, x, y, fixed_x, fixed_y, edge_resize))
elseif lay ~= layout.suit.magnifier then
-- Only move the client to the mouse
-- screen if the target screen is not