Layouts can define their own resizing handler (FS#1267)
This commit is contained in:
parent
daeb9aee19
commit
8d7b0feedd
|
@ -5,9 +5,78 @@
|
|||
---------------------------------------------------------------------------
|
||||
|
||||
--- Dummy function for floating layout
|
||||
-- Grab environment we need
|
||||
local math = math
|
||||
local ipairs = ipairs
|
||||
local capi =
|
||||
{
|
||||
mouse = mouse,
|
||||
mousegrabber = mousegrabber
|
||||
}
|
||||
|
||||
-- awful.layout.suit.floating
|
||||
local floating = {}
|
||||
|
||||
function floating.mouse_resize_handler(c, corner, x, y)
|
||||
local g = c:geometry()
|
||||
|
||||
-- Do not allow maximized clients to be resized by mouse
|
||||
local fixed_x = c.maximized_horizontal
|
||||
local fixed_y = c.maximized_vertical
|
||||
|
||||
-- Warp mouse pointer
|
||||
capi.mouse.coords({ x = x, y = y })
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local ng
|
||||
if corner == "bottom_right" then
|
||||
ng = { width = _mouse.x - g.x,
|
||||
height = _mouse.y - g.y }
|
||||
elseif corner == "bottom_left" then
|
||||
ng = { x = _mouse.x,
|
||||
width = (g.x + g.width) - _mouse.x,
|
||||
height = _mouse.y - g.y }
|
||||
elseif corner == "top_left" then
|
||||
ng = { x = _mouse.x,
|
||||
width = (g.x + g.width) - _mouse.x,
|
||||
y = _mouse.y,
|
||||
height = (g.y + g.height) - _mouse.y }
|
||||
else
|
||||
ng = { width = _mouse.x - g.x,
|
||||
y = _mouse.y,
|
||||
height = (g.y + g.height) - _mouse.y }
|
||||
end
|
||||
if ng.width <= 0 then ng.width = nil end
|
||||
if ng.height <= 0 then ng.height = nil end
|
||||
if fixed_x then ng.width = g.width ng.x = g.x end
|
||||
if fixed_y then ng.height = g.height ng.y = g.y end
|
||||
c:geometry(ng)
|
||||
-- Get real geometry that has been applied
|
||||
-- in case we honor size hints
|
||||
-- XXX: This should be rewritten when size
|
||||
-- hints are available from Lua.
|
||||
local rg = c:geometry()
|
||||
|
||||
if corner == "bottom_right" then
|
||||
ng = {}
|
||||
elseif corner == "bottom_left" then
|
||||
ng = { x = (g.x + g.width) - rg.width }
|
||||
elseif corner == "top_left" then
|
||||
ng = { x = (g.x + g.width) - rg.width,
|
||||
y = (g.y + g.height) - rg.height }
|
||||
else
|
||||
ng = { y = (g.y + g.height) - rg.height }
|
||||
end
|
||||
c:geometry({ x = ng.x, y = ng.y })
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, corner .. "_corner")
|
||||
end
|
||||
|
||||
function floating.arrange()
|
||||
end
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@ local tag = require("awful.tag")
|
|||
local capi =
|
||||
{
|
||||
client = client,
|
||||
screen = screen
|
||||
screen = screen,
|
||||
mouse = mouse,
|
||||
mousegrabber = mousegrabber
|
||||
}
|
||||
local client = require("awful.client")
|
||||
|
||||
|
@ -19,6 +21,31 @@ local client = require("awful.client")
|
|||
-- awful.layout.suit.magnifier
|
||||
local magnifier = {}
|
||||
|
||||
function magnifier.mouse_resize_handler(c, corner, x, y)
|
||||
capi.mouse.coords({ x = x, y = y })
|
||||
|
||||
local wa = capi.screen[c.screen].workarea
|
||||
local center_x = wa.x + wa.width / 2
|
||||
local center_y = wa.y + wa.height / 2
|
||||
local maxdist_pow = (wa.width^2 + wa.height^2) / 4
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local dx = center_x - _mouse.x
|
||||
local dy = center_y - _mouse.y
|
||||
local dist = dx^2 + dy^2
|
||||
|
||||
-- New master width factor
|
||||
local mwfact = dist / maxdist_pow
|
||||
tag.setmwfact(math.min(math.max(0.01, mwfact), 0.99), tag.selected(c.screen))
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, corner .. "_corner")
|
||||
end
|
||||
|
||||
function magnifier.arrange(p)
|
||||
-- Fullscreen?
|
||||
local area = p.workarea
|
||||
|
|
|
@ -7,14 +7,116 @@
|
|||
---------------------------------------------------------------------------
|
||||
|
||||
-- Grab environment we need
|
||||
local tag = require("awful.tag")
|
||||
local client = require("awful.client")
|
||||
local ipairs = ipairs
|
||||
local math = math
|
||||
local tag = require("awful.tag")
|
||||
local capi =
|
||||
{
|
||||
mouse = mouse,
|
||||
screen = screen,
|
||||
mousegrabber = mousegrabber
|
||||
}
|
||||
|
||||
--- Tiled layouts module for awful
|
||||
-- awful.layout.suit.tile
|
||||
local tile = {}
|
||||
|
||||
local function mouse_resize_handler(c, corner, x, y, orientation)
|
||||
local orientation = orientation or "tile"
|
||||
local wa = capi.screen[c.screen].workarea
|
||||
local mwfact = tag.getmwfact()
|
||||
local cursor
|
||||
local g = c:geometry()
|
||||
local offset = 0
|
||||
local x,y
|
||||
if orientation == "tile" then
|
||||
cursor = "cross"
|
||||
if g.height+15 > wa.height then
|
||||
offset = g.height * .5
|
||||
cursor = "sb_h_double_arrow"
|
||||
elseif not (g.y+g.height+15 > wa.y+wa.height) then
|
||||
offset = g.height
|
||||
end
|
||||
capi.mouse.coords({ x = wa.x + wa.width * mwfact, y = g.y + offset })
|
||||
elseif orientation == "left" then
|
||||
cursor = "cross"
|
||||
if g.height+15 >= wa.height then
|
||||
offset = g.height * .5
|
||||
cursor = "sb_h_double_arrow"
|
||||
elseif not (g.y+g.height+15 > wa.y+wa.height) then
|
||||
offset = g.height
|
||||
end
|
||||
capi.mouse.coords({ x = wa.x + wa.width * (1 - mwfact), y = g.y + offset })
|
||||
elseif orientation == "bottom" then
|
||||
cursor = "cross"
|
||||
if g.width+15 >= wa.width then
|
||||
offset = g.width * .5
|
||||
cursor = "sb_v_double_arrow"
|
||||
elseif not (g.x+g.width+15 > wa.x+wa.width) then
|
||||
offset = g.width
|
||||
end
|
||||
capi.mouse.coords({ y = wa.y + wa.height * mwfact, x = g.x + offset})
|
||||
else
|
||||
cursor = "cross"
|
||||
if g.width+15 >= wa.width then
|
||||
offset = g.width * .5
|
||||
cursor = "sb_v_double_arrow"
|
||||
elseif not (g.x+g.width+15 > wa.x+wa.width) then
|
||||
offset = g.width
|
||||
end
|
||||
capi.mouse.coords({ y = wa.y + wa.height * (1 - mwfact), x= g.x + offset })
|
||||
end
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local fact_x = (_mouse.x - wa.x) / wa.width
|
||||
local fact_y = (_mouse.y - wa.y) / wa.height
|
||||
local mwfact
|
||||
|
||||
local g = c:geometry()
|
||||
|
||||
|
||||
-- we have to make sure we're not on the last visible client where we have to use different settings.
|
||||
local wfact
|
||||
local wfact_x, wfact_y
|
||||
if (g.y+g.height+15) > (wa.y+wa.height) then
|
||||
wfact_y = (g.y + g.height - _mouse.y) / wa.height
|
||||
else
|
||||
wfact_y = (_mouse.y - g.y) / wa.height
|
||||
end
|
||||
|
||||
if (g.x+g.width+15) > (wa.x+wa.width) then
|
||||
wfact_x = (g.x + g.width - _mouse.x) / wa.width
|
||||
else
|
||||
wfact_x = (_mouse.x - g.x) / wa.width
|
||||
end
|
||||
|
||||
|
||||
if orientation == "tile" then
|
||||
mwfact = fact_x
|
||||
wfact = wfact_y
|
||||
elseif orientation == "left" then
|
||||
mwfact = 1 - fact_x
|
||||
wfact = wfact_y
|
||||
elseif orientation == "bottom" then
|
||||
mwfact = fact_y
|
||||
wfact = wfact_x
|
||||
else
|
||||
mwfact = 1 - fact_y
|
||||
wfact = wfact_x
|
||||
end
|
||||
|
||||
tag.setmwfact(math.min(math.max(mwfact, 0.01), 0.99), tag.selected(c.screen))
|
||||
client.setwfact(math.min(math.max(wfact,0.01), 0.99), c)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, cursor)
|
||||
end
|
||||
|
||||
local function tile_group(cls, wa, orientation, fact, group)
|
||||
-- get our orientation right
|
||||
local height = "height"
|
||||
|
@ -152,6 +254,9 @@ end
|
|||
tile.right = {}
|
||||
tile.right.name = "tile"
|
||||
tile.right.arrange = do_tile
|
||||
function tile.right.mouse_resize_handler(c, corner, x, y)
|
||||
return mouse_resize_handler(c, corner, x, y)
|
||||
end
|
||||
|
||||
--- The main tile algo, on left.
|
||||
-- @param screen The screen number to tile.
|
||||
|
@ -160,6 +265,9 @@ tile.left.name = "tileleft"
|
|||
function tile.left.arrange(p)
|
||||
return do_tile(p, "left")
|
||||
end
|
||||
function tile.left.mouse_resize_handler(c, corner, x, y)
|
||||
return mouse_resize_handler(c, corner, x, y, "left")
|
||||
end
|
||||
|
||||
--- The main tile algo, on bottom.
|
||||
-- @param screen The screen number to tile.
|
||||
|
@ -168,6 +276,9 @@ tile.bottom.name = "tilebottom"
|
|||
function tile.bottom.arrange(p)
|
||||
return do_tile(p, "bottom")
|
||||
end
|
||||
function tile.bottom.mouse_resize_handler(c, corner, x, y)
|
||||
return mouse_resize_handler(c, corner, x, y, "bottom")
|
||||
end
|
||||
|
||||
--- The main tile algo, on top.
|
||||
-- @param screen The screen number to tile.
|
||||
|
@ -176,8 +287,12 @@ tile.top.name = "tiletop"
|
|||
function tile.top.arrange(p)
|
||||
return do_tile(p, "top")
|
||||
end
|
||||
function tile.top.mouse_resize_handler(c, corner, x, y)
|
||||
return mouse_resize_handler(c, corner, x, y, "top")
|
||||
end
|
||||
|
||||
tile.arrange = tile.right.arrange
|
||||
tile.mouse_resize_handler = tile.right.mouse_resize_handler
|
||||
tile.name = tile.right.name
|
||||
|
||||
return tile
|
||||
|
|
|
@ -335,183 +335,6 @@ function mouse.client.corner(c, corner)
|
|||
return corner, x, y
|
||||
end
|
||||
|
||||
local function client_resize_magnifier(c, corner)
|
||||
local corner, x, y = mouse.client.corner(c, corner)
|
||||
capi.mouse.coords({ x = x, y = y })
|
||||
|
||||
local wa = capi.screen[c.screen].workarea
|
||||
local center_x = wa.x + wa.width / 2
|
||||
local center_y = wa.y + wa.height / 2
|
||||
local maxdist_pow = (wa.width^2 + wa.height^2) / 4
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local dx = center_x - _mouse.x
|
||||
local dy = center_y - _mouse.y
|
||||
local dist = dx^2 + dy^2
|
||||
|
||||
-- New master width factor
|
||||
local mwfact = dist / maxdist_pow
|
||||
tag.setmwfact(math.min(math.max(0.01, mwfact), 0.99), tag.selected(c.screen))
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, corner .. "_corner")
|
||||
end
|
||||
|
||||
local function client_resize_tiled(c, lay)
|
||||
local wa = capi.screen[c.screen].workarea
|
||||
local mwfact = tag.getmwfact()
|
||||
local cursor
|
||||
local g = c:geometry()
|
||||
local offset = 0
|
||||
local x,y
|
||||
if lay == layout.suit.tile then
|
||||
cursor = "cross"
|
||||
if g.height+15 > wa.height then
|
||||
offset = g.height * .5
|
||||
cursor = "sb_h_double_arrow"
|
||||
elseif not (g.y+g.height+15 > wa.y+wa.height) then
|
||||
offset = g.height
|
||||
end
|
||||
capi.mouse.coords({ x = wa.x + wa.width * mwfact, y = g.y + offset })
|
||||
elseif lay == layout.suit.tile.left then
|
||||
cursor = "cross"
|
||||
if g.height+15 >= wa.height then
|
||||
offset = g.height * .5
|
||||
cursor = "sb_h_double_arrow"
|
||||
elseif not (g.y+g.height+15 > wa.y+wa.height) then
|
||||
offset = g.height
|
||||
end
|
||||
capi.mouse.coords({ x = wa.x + wa.width * (1 - mwfact), y = g.y + offset })
|
||||
elseif lay == layout.suit.tile.bottom then
|
||||
cursor = "cross"
|
||||
if g.width+15 >= wa.width then
|
||||
offset = g.width * .5
|
||||
cursor = "sb_v_double_arrow"
|
||||
elseif not (g.x+g.width+15 > wa.x+wa.width) then
|
||||
offset = g.width
|
||||
end
|
||||
capi.mouse.coords({ y = wa.y + wa.height * mwfact, x = g.x + offset})
|
||||
else
|
||||
cursor = "cross"
|
||||
if g.width+15 >= wa.width then
|
||||
offset = g.width * .5
|
||||
cursor = "sb_v_double_arrow"
|
||||
elseif not (g.x+g.width+15 > wa.x+wa.width) then
|
||||
offset = g.width
|
||||
end
|
||||
capi.mouse.coords({ y = wa.y + wa.height * (1 - mwfact), x= g.x + offset })
|
||||
end
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local fact_x = (_mouse.x - wa.x) / wa.width
|
||||
local fact_y = (_mouse.y - wa.y) / wa.height
|
||||
local mwfact
|
||||
|
||||
local g = c:geometry()
|
||||
|
||||
|
||||
-- we have to make sure we're not on the last visible client where we have to use different settings.
|
||||
local wfact
|
||||
local wfact_x, wfact_y
|
||||
if (g.y+g.height+15) > (wa.y+wa.height) then
|
||||
wfact_y = (g.y + g.height - _mouse.y) / wa.height
|
||||
else
|
||||
wfact_y = (_mouse.y - g.y) / wa.height
|
||||
end
|
||||
|
||||
if (g.x+g.width+15) > (wa.x+wa.width) then
|
||||
wfact_x = (g.x + g.width - _mouse.x) / wa.width
|
||||
else
|
||||
wfact_x = (_mouse.x - g.x) / wa.width
|
||||
end
|
||||
|
||||
|
||||
if lay == layout.suit.tile then
|
||||
mwfact = fact_x
|
||||
wfact = wfact_y
|
||||
elseif lay == layout.suit.tile.left then
|
||||
mwfact = 1 - fact_x
|
||||
wfact = wfact_y
|
||||
elseif lay == layout.suit.tile.bottom then
|
||||
mwfact = fact_y
|
||||
wfact = wfact_x
|
||||
else
|
||||
mwfact = 1 - fact_y
|
||||
wfact = wfact_x
|
||||
end
|
||||
|
||||
tag.setmwfact(math.min(math.max(mwfact, 0.01), 0.99), tag.selected(c.screen))
|
||||
aclient.setwfact(math.min(math.max(wfact,0.01), 0.99), c)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, cursor)
|
||||
end
|
||||
|
||||
local function client_resize_floating(c, corner, fixed_x, fixed_y)
|
||||
local corner, x, y = mouse.client.corner(c, corner)
|
||||
local g = c:geometry()
|
||||
|
||||
-- Warp mouse pointer
|
||||
capi.mouse.coords({ x = x, y = y })
|
||||
|
||||
capi.mousegrabber.run(function (_mouse)
|
||||
for k, v in ipairs(_mouse.buttons) do
|
||||
if v then
|
||||
local ng
|
||||
if corner == "bottom_right" then
|
||||
ng = { width = _mouse.x - g.x,
|
||||
height = _mouse.y - g.y }
|
||||
elseif corner == "bottom_left" then
|
||||
ng = { x = _mouse.x,
|
||||
width = (g.x + g.width) - _mouse.x,
|
||||
height = _mouse.y - g.y }
|
||||
elseif corner == "top_left" then
|
||||
ng = { x = _mouse.x,
|
||||
width = (g.x + g.width) - _mouse.x,
|
||||
y = _mouse.y,
|
||||
height = (g.y + g.height) - _mouse.y }
|
||||
else
|
||||
ng = { width = _mouse.x - g.x,
|
||||
y = _mouse.y,
|
||||
height = (g.y + g.height) - _mouse.y }
|
||||
end
|
||||
if ng.width <= 0 then ng.width = nil end
|
||||
if ng.height <= 0 then ng.height = nil end
|
||||
if fixed_x then ng.width = g.width ng.x = g.x end
|
||||
if fixed_y then ng.height = g.height ng.y = g.y end
|
||||
c:geometry(ng)
|
||||
-- Get real geometry that has been applied
|
||||
-- in case we honor size hints
|
||||
-- XXX: This should be rewritten when size
|
||||
-- hints are available from Lua.
|
||||
local rg = c:geometry()
|
||||
|
||||
if corner == "bottom_right" then
|
||||
ng = {}
|
||||
elseif corner == "bottom_left" then
|
||||
ng = { x = (g.x + g.width) - rg.width }
|
||||
elseif corner == "top_left" then
|
||||
ng = { x = (g.x + g.width) - rg.width,
|
||||
y = (g.y + g.height) - rg.height }
|
||||
else
|
||||
ng = { y = (g.y + g.height) - rg.height }
|
||||
end
|
||||
c:geometry({ x = ng.x, y = ng.y })
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, corner .. "_corner")
|
||||
end
|
||||
|
||||
--- Resize a client.
|
||||
-- @param c The client to resize, or the focused one by default.
|
||||
-- @param corner The corner to grab on resize. Auto detected by default.
|
||||
|
@ -527,22 +350,13 @@ function mouse.client.resize(c, corner)
|
|||
return
|
||||
end
|
||||
|
||||
-- Do not allow maximized clients to be resized by mouse
|
||||
local fixed_x = c.maximized_horizontal
|
||||
local fixed_y = c.maximized_vertical
|
||||
|
||||
local lay = layout.get(c.screen)
|
||||
local corner, x, y = mouse.client.corner(c, corner)
|
||||
|
||||
if lay == layout.suit.floating or aclient.floating.get(c) then
|
||||
return client_resize_floating(c, corner, fixed_x, fixed_y)
|
||||
elseif lay == layout.suit.tile
|
||||
or lay == layout.suit.tile.left
|
||||
or lay == layout.suit.tile.top
|
||||
or lay == layout.suit.tile.bottom
|
||||
then
|
||||
return client_resize_tiled(c, lay)
|
||||
elseif lay == layout.suit.magnifier then
|
||||
return client_resize_magnifier(c, corner)
|
||||
return layout.suit.floating.mouse_resize_handler(c, corner, x, y)
|
||||
elseif lay.mouse_resize_handler then
|
||||
return lay.mouse_resize_handler(c, corner, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue