X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/10d2bbefe4cf3ef95b4240fb5dc11994c3224227..fa9fb11a7c3eeb186a17c6d93c5da37eb6929d58:/layout/uselessfair.lua?ds=sidebyside

diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua
index 058dae6..e1284e0 100644
--- a/layout/uselessfair.lua
+++ b/layout/uselessfair.lua
@@ -1,108 +1,108 @@
 
 --[[
-
-     Licensed under GNU General Public License v2
-      * (c) 2014,      projektile
-      * (c) 2013,      Luke Bonham
-      * (c) 2012,      Josh Komoroske
-      * (c) 2010-2012, Peter Hofmann
-
+                                                  
+     Licensed under GNU General Public License v2 
+      * (c) 2014,      projektile, worron         
+      * (c) 2013,      Luke Bonham                
+      * (c) 2012,      Josh Komoroske             
+      * (c) 2010-2012, Peter Hofmann              
+                                                  
 --]]
 
 local beautiful = require("beautiful")
 local ipairs    = ipairs
-local math      = { ceil = math.ceil, sqrt = math.sqrt }
+local math      = { ceil = math.ceil, sqrt = math.sqrt, floor = math.floor, max = math.max }
 local tonumber  = tonumber
 
 local uselessfair = {}
 
-local function fair(p, orientation)
-    -- A useless gap (like the dwm patch) can be defined with
-    -- beautiful.useless_gap_width.
-    local useless_gap = tonumber(beautiful.useless_gap_width) or 0
-    if useless_gap < 0 then useless_gap = 0 end
+-- Transformation functions
+local function swap(geometry)
+    return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width }
+end
 
-    -- A global border can be defined with
-    -- beautiful.global_border_width.
-    local global_border = tonumber(beautiful.global_border_width) or 0
-    if global_border < 0 then global_border = 0 end
+-- Client geometry correction depending on useless gap and window border
+local function size_correction(c, geometry, useless_gap)
+    geometry.width  = math.max(geometry.width  - 2 * c.border_width - useless_gap, 1)
+    geometry.height = math.max(geometry.height - 2 * c.border_width - useless_gap, 1)
+    geometry.x = geometry.x + useless_gap / 2
+    geometry.y = geometry.y + useless_gap / 2
+end
 
-    -- Themes border width requires an offset.
-    local bw = tonumber(beautiful.border_width) or 0
+-- Main tiling function
+local function fair(p, orientation)
 
-    -- Total window size extend
-    local ext = 2 * bw + useless_gap
+    -- Theme vars
+    local useless_gap = beautiful.useless_gap_width or 0
+    local global_border = beautiful.global_border_width or 0
 
-    -- get our orientation right.
+    -- Aliases
     local wa = p.workarea
     local cls = p.clients
 
+    -- Nothing to tile here
+    if #cls == 0 then return end
+
+    -- Workarea size correction depending on useless gap and global border
     wa.height = wa.height - 2 * global_border - useless_gap
     wa.width  = wa.width -  2 * global_border - useless_gap
-    wa.x = wa.x + useless_gap + global_border
-    wa.y = wa.y + useless_gap + global_border
-
-    if #cls > 0 then
-        local cells = math.ceil(math.sqrt(#cls))
-        local strips = math.ceil(#cls / cells)
-
-        local cell = 0
-        local strip = 0
-        for k, c in ipairs(cls) do
-            local g = {}
-
-            if ( orientation == "east" and #cls > 2 )
-            or ( orientation == "south" and #cls <= 2 ) then
-                if #cls < (strips * cells) and strip == strips - 1 then
-                    g.width = wa.width / (cells - ((strips * cells) - #cls))
-                else
-                    g.width = wa.width / cells
-                end
-                g.height = wa.height / strips
-
-                g.x = wa.x + cell * g.width
-                g.y = wa.y + strip * g.height
-
-            else
-                if #cls < (strips * cells) and strip == strips - 1 then
-                    g.height = wa.height / (cells - ((strips * cells) - #cls))
-                else
-                    g.height = wa.height / cells
-                end
-                g.width = wa.width / strips
-
-                g.x = wa.x + strip * g.width
-                g.y = wa.y + cell * g.height
-
-            end
-
-            g.width = g.width - ext
-            g.height = g.height - ext
-
-            c:geometry(g)
-
-            cell = cell + 1
-            if cell == cells then
-                cell = 0
-                strip = strip + 1
-            end
+    wa.x = wa.x + useless_gap / 2 + global_border
+    wa.y = wa.y + useless_gap / 2 + global_border
+
+    -- Geometry calculation
+    local row, col = 0, 0
+
+    local rows = math.ceil(math.sqrt(#cls))
+    local cols = math.ceil(#cls / rows)
+
+    for i, c in ipairs(cls) do
+        local g = {}
+
+        -- find tile orientation for current client and swap geometry if need
+        local need_swap = (orientation == "east" and #cls <= 2) or (orientation == "south" and #cls > 2)
+        local area = need_swap and swap(wa) or wa
+
+        -- calculate geometry
+        if #cls < (cols * rows) and row == cols - 1 then
+            g.width = area.width / (rows - ((cols * rows) - #cls))
+        else
+            g.width = area.width / rows
         end
+
+        g.height = area.height / cols
+        g.x = area.x + col * g.width
+        g.y = area.y + row * g.height
+
+        -- turn back to real if geometry was swapped
+        if need_swap then g = swap(g) end
+
+        -- window size correction depending on useless gap and window border
+        size_correction(c, g, useless_gap)
+
+        -- set geometry
+        c:geometry(g)
+
+        -- update tile grid coordinates
+        col = i % rows
+        row = math.floor(i / rows)
     end
 end
 
---- Horizontal fair layout.
--- @param screen The screen to arrange.
-uselessfair.horizontal = {}
-uselessfair.horizontal.name = "uselessfairh"
-function uselessfair.horizontal.arrange(p)
-    return fair(p, "east")
+-- Layout constructor
+local function construct_layout(name, direction)
+    return {
+        name = name,
+        -- @p screen The screen number to tile
+        arrange = function(p) return fair(p, direction) end
+    }
 end
 
--- Vertical fair layout.
--- @param screen The screen to arrange.
-uselessfair.name = "uselessfair"
-function uselessfair.arrange(p)
-    return fair(p, "south")
-end
+-- Build layouts with different tile direction
+uselessfair.vertical   = construct_layout("uselessfair", "south")
+uselessfair.horizontal = construct_layout("uselessfairh", "east")
+
+-- Module aliase
+uselessfair.arrange = uselessfair.vertical.arrange
+uselessfair.name = uselessfair.vertical.name
 
 return uselessfair