diff options
Diffstat (limited to 'awesome/lib/awful/mouse/snap.lua')
-rw-r--r-- | awesome/lib/awful/mouse/snap.lua | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/awesome/lib/awful/mouse/snap.lua b/awesome/lib/awful/mouse/snap.lua deleted file mode 100644 index 048a679..0000000 --- a/awesome/lib/awful/mouse/snap.lua +++ /dev/null @@ -1,266 +0,0 @@ ---------------------------------------------------------------------------- ---- Mouse snapping related functions --- --- @author Julien Danjou <julien@danjou.info> --- @copyright 2008 Julien Danjou --- @submodule mouse ---------------------------------------------------------------------------- - -local aclient = require("awful.client") -local resize = require("awful.mouse.resize") -local aplace = require("awful.placement") -local wibox = require("wibox") -local beautiful = require("beautiful") -local color = require("gears.color") -local shape = require("gears.shape") -local cairo = require("lgi").cairo - -local capi = { - root = root, - mouse = mouse, - screen = screen, - client = client, - mousegrabber = mousegrabber, -} - -local module = { - default_distance = 8 -} - -local placeholder_w = nil - -local function show_placeholder(geo) - if not geo then - if placeholder_w then - placeholder_w.visible = false - end - return - end - - placeholder_w = placeholder_w or wibox { - ontop = true, - bg = color(beautiful.snap_bg or beautiful.bg_urgent or "#ff0000"), - } - - placeholder_w:geometry(geo) - - local img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height) - local cr = cairo.Context(img) - - cr:set_operator(cairo.Operator.CLEAR) - cr:set_source_rgba(0,0,0,1) - cr:paint() - cr:set_operator(cairo.Operator.SOURCE) - cr:set_source_rgba(1,1,1,1) - - local line_width = beautiful.snap_border_width or 5 - cr:set_line_width(beautiful.xresources.apply_dpi(line_width)) - - local f = beautiful.snap_shape or function() - cr:translate(line_width,line_width) - shape.rounded_rect(cr,geo.width-2*line_width,geo.height-2*line_width, 10) - end - - f(cr, geo.width, geo.height) - - cr:stroke() - - placeholder_w.shape_bounding = img._native - - placeholder_w.visible = true -end - -local function build_placement(snap, axis) - return aplace.scale - + aplace[snap] - + ( - axis and aplace["maximize_"..axis] or nil - ) -end - -local function detect_screen_edges(c, snap) - local coords = capi.mouse.coords() - - local sg = c.screen.geometry - - local v, h = nil - - if math.abs(coords.x) <= snap + sg.x and coords.x >= sg.x then - h = "left" - elseif math.abs((sg.x + sg.width) - coords.x) <= snap then - h = "right" - end - - if math.abs(coords.y) <= snap + sg.y and coords.y >= sg.y then - v = "top" - elseif math.abs((sg.y + sg.height) - coords.y) <= snap then - v = "bottom" - end - - return v, h -end - -local current_snap, current_axis = nil - -local function detect_areasnap(c, distance) - local old_snap = current_snap - local v, h = detect_screen_edges(c, distance) - - if v and h then - current_snap = v.."_"..h - else - current_snap = v or h or nil - end - - if old_snap == current_snap then return end - - current_axis = ((v and not h) and "horizontally") - or ((h and not v) and "vertically") - or nil - - -- Show the expected geometry outline - show_placeholder( - current_snap and build_placement(current_snap, current_axis)(c, { - to_percent = 0.5, - honor_workarea = true, - pretend = true - }) or nil - ) - -end - -local function apply_areasnap(c, args) - if not current_snap then return end - - -- Remove the move offset - args.offset = {} - - placeholder_w.visible = false - - return build_placement(current_snap, current_axis)(c,{ - to_percent = 0.5, - honor_workarea = true, - }) -end - -local function snap_outside(g, sg, snap) - if g.x < snap + sg.x + sg.width and g.x > sg.x + sg.width then - g.x = sg.x + sg.width - elseif g.x + g.width < sg.x and g.x + g.width > sg.x - snap then - g.x = sg.x - g.width - end - if g.y < snap + sg.y + sg.height and g.y > sg.y + sg.height then - g.y = sg.y + sg.height - elseif g.y + g.height < sg.y and g.y + g.height > sg.y - snap then - g.y = sg.y - g.height - end - return g -end - -local function snap_inside(g, sg, snap) - local edgev = 'none' - local edgeh = 'none' - if math.abs(g.x) < snap + sg.x and g.x > sg.x then - edgev = 'left' - g.x = sg.x - elseif math.abs((sg.x + sg.width) - (g.x + g.width)) < snap then - edgev = 'right' - g.x = sg.x + sg.width - g.width - end - if math.abs(g.y) < snap + sg.y and g.y > sg.y then - edgeh = 'top' - g.y = sg.y - elseif math.abs((sg.y + sg.height) - (g.y + g.height)) < snap then - edgeh = 'bottom' - g.y = sg.y + sg.height - g.height - end - - -- What is the dominant dimension? - if g.width > g.height then - return g, edgeh - else - return g, edgev - end -end - ---- Snap a client to the closest client or screen edge. --- @function awful.mouse.snap --- @param c The client to snap. --- @param snap The pixel to snap clients. --- @param x The client x coordinate. --- @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 module.snap(c, snap, x, y, fixed_x, fixed_y) - snap = snap or module.default_distance - c = c or capi.client.focus - local cur_geom = c:geometry() - local geom = c:geometry() - geom.width = geom.width + (2 * c.border_width) - geom.height = geom.height + (2 * c.border_width) - local edge - geom.x = x or geom.x - geom.y = y or geom.y - - geom, edge = snap_inside(geom, c.screen.geometry, snap) - geom = snap_inside(geom, c.screen.workarea, snap) - - -- Allow certain windows to snap to the edge of the workarea. - -- Only allow docking to workarea for consistency/to avoid problems. - if c.dockable then - local struts = c:struts() - struts['left'] = 0 - struts['right'] = 0 - struts['top'] = 0 - struts['bottom'] = 0 - if edge ~= "none" and c.floating then - if edge == "left" or edge == "right" then - struts[edge] = cur_geom.width - elseif edge == "top" or edge == "bottom" then - struts[edge] = cur_geom.height - end - end - c:struts(struts) - end - - for _, snapper in ipairs(aclient.visible(c.screen)) do - if snapper ~= c then - local snapper_geom = snapper:geometry() - snapper_geom.width = snapper_geom.width + (2 * snapper.border_width) - snapper_geom.height = snapper_geom.height + (2 * snapper.border_width) - geom = snap_outside(geom, snapper_geom, snap) - end - end - - geom.width = geom.width - (2 * c.border_width) - geom.height = geom.height - (2 * c.border_width) - - -- It's easiest to undo changes afterwards if they're not allowed - if fixed_x then geom.x = cur_geom.x end - if fixed_y then geom.y = cur_geom.y end - - return geom -end - --- Enable edge snapping -resize.add_move_callback(function(c, geo, args) - -- Screen edge snapping (areosnap) - if (module.edge_enabled ~= false) - and args and (args.snap == nil or args.snap) then - detect_areasnap(c, 16) - end - - -- Snapping between clients - if (module.client_enabled ~= false) - and args and (args.snap == nil or args.snap) then - return module.snap(c, args.snap, geo.x, geo.y) - end -end, "mouse.move") - --- Apply the aerosnap -resize.add_leave_callback(function(c, _, args) - if module.edge_enabled == false then return end - return apply_areasnap(c, args) -end, "mouse.move") - -return setmetatable(module, {__call = function(_, ...) return module.snap(...) end}) |