-- Offers window tiling functionnality local awful = require("awful") local grect = require("gears.geometry").rectangle -- Placements local leftTileGeometry = awful.placement.scale + awful.placement.left + awful.placement['maximize_vertically'] local rightTileGeometry = awful.placement.scale + awful.placement.right + awful.placement['maximize_vertically'] local maximizedTileGeometry = awful.placement.scale + awful.placement['maximize'] -- Check if geometries are the same local geometryEquals = function(geo1, geo2) return geo1.width == geo2.width and geo1.height == geo2.height and geo1.x == geo2.x and geo1.y == geo2.y end -- Try to apply a tile placement to a client -- return false if it changed nothing local applyTile = function(c, geometry) local initialGeometry = { x = c.x, y = c.y, width = c.width, height = c.height } local newGeometry = geometry(c, {honor_workarea=true, to_percent = 0.5}) return not geometryEquals(initialGeometry, newGeometry) end local screenLeft = function(geo) return function (c) local newScreen = c.screen.get_next_in_direction(c.screen, "left") if newScreen ~= nil then c.screen = newScreen applyTile(c, geo) end end end local screenRight = function(geo) return function (c) local newScreen = c.screen.get_next_in_direction(c.screen, "right") if newScreen ~= nil then c.screen = newScreen applyTile(c, geo) end end end local swapClient = function(c, dir) local sel = c or capi.client.focus if sel then local cltbl = sel.screen.tiled_clients local geomtbl = {} for i,cl in ipairs(cltbl) do if not cl.maximized then geomtbl[i] = cl:geometry() end end local target = grect.get_in_direction(dir, geomtbl, sel:geometry()) -- If we found a client to swap with, then go for it if target then cltbl[target]:swap(sel) return true end end return false end client.connect_signal("manage", function (c) if awesome.startup and not c.size_hints.user_position and not c.size_hints.program_position then -- Prevent clients from being unreachable after screen count changes. awful.placement.no_offscreen(c) end if c.maximized then applyTile(c, maximizedTileGeometry) end end) return { key = { tileRight = function (c) if c.maximized then c:raise() if not applyTile(c, rightTileGeometry) then screenRight(leftTileGeometry)(c) end else swapClient(c, 'right') end end, tileLeft = function (c) if c.maximized then c:raise() if not applyTile(c, leftTileGeometry) then screenLeft(rightTileGeometry)(c) end else swapClient(c, 'left') end end, screenLeft = screenLeft(maximizedTileGeometry), screenRight = screenRight(maximizedTileGeometry), toggleMaximized = function (c) if not c.maximized then if not swapClient(c, 'up') then c.maximized = true c:raise() end else if not applyTile(c, maximizedTileGeometry) then c.maximized = false end end end, minimize = function(c) if c.maximized or not swapClient(c, 'down') then c.minimized = true end end } }