X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/1ed42223a2857770aa85da863213cdfb29f7d426..f4870b8858835726ea6f6562a0a3d7e092425595:/layout/cascade.lua

diff --git a/layout/cascade.lua b/layout/cascade.lua
index 999c599..204ce40 100644
--- a/layout/cascade.lua
+++ b/layout/cascade.lua
@@ -8,73 +8,166 @@
                                                   
 --]]
 
-local tag       = require("awful.tag")
-local beautiful = require("beautiful")
+local floor  = math.floor
+local screen = screen
 
-local cascade =
-{
+local cascade = {
     name     = "cascade",
     nmaster  = 0,
     offset_x = 32,
-    offset_y = 8
+    offset_y = 8,
+    tile     = {
+        name          = "cascadetile",
+        nmaster       = 0,
+        ncol          = 0,
+        mwfact        = 0,
+        offset_x      = 5,
+        offset_y      = 32,
+        extra_padding = 0
+    }
 }
 
-function cascade.arrange(p)
+local function do_cascade(p, tiling)
+    local t = p.tag or screen[p.screen].selected_tag
+    local wa = p.workarea
+    local cls = p.clients
 
-    -- Cascade windows.
+    if #cls == 0 then return 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
+    if not tiling then
+        -- Cascade windows.
 
-    -- Themes border width requires an offset.
-    local bw = tonumber(beautiful.border_width) or 0
+        local num_c
+        if cascade.nmaster > 0 then
+            num_c = cascade.nmaster
+        else
+            num_c = t.master_count
+        end
 
-    -- Screen.
-    local wa = p.workarea
-    local cls = p.clients
+        -- Opening a new window will usually force all existing windows to
+        -- get resized. This wastes a lot of CPU time. So let's set a lower
+        -- bound to "how_many": This wastes a little screen space but you'll
+        -- get a much better user experience.
+        local how_many = (#cls >= num_c and #cls) or num_c
 
-    wa.height = wa.height - ((global_border * 2) + (bw * 2))
-    wa.width = wa.width - ((global_border * 2) + (bw * 2))
-    wa.x = wa.x + global_border
-    wa.y = wa.y + global_border
-
-    -- Opening a new window will usually force all existing windows to
-    -- get resized. This wastes a lot of CPU time. So let's set a lower
-    -- bound to "how_many": This wastes a little screen space but you'll
-    -- get a much better user experience.
-    local t = tag.selected(p.screen)
-    local num_c
-    if cascade.nmaster > 0
-    then
-        num_c = cascade.nmaster
-    else
-        num_c = tag.getnmaster(t)
-    end
+        local current_offset_x = cascade.offset_x * (how_many - 1)
+        local current_offset_y = cascade.offset_y * (how_many - 1)
 
-    local how_many = #cls
-    if how_many < num_c
-    then
-        how_many = num_c
-    end
+        -- Iterate.
+        for i = 1,#cls,1 do
+            local c = cls[i]
+            local g = {}
 
-    local current_offset_x = cascade.offset_x * (how_many - 1)
-    local current_offset_y = cascade.offset_y * (how_many - 1)
+            g.x      = wa.x + (how_many - i) * cascade.offset_x
+            g.y      = wa.y + (i - 1) * cascade.offset_y
+            g.width  = wa.width - current_offset_x
+            g.height = wa.height - current_offset_y
 
-    -- Iterate.
-    for i = 1,#cls,1
-    do
-        local c = cls[i]
+            if g.width  < 1 then g.width  = 1 end
+            if g.height < 1 then g.height = 1 end
+
+            p.geometries[c] = g
+        end
+    else
+        -- Layout with one fixed column meant for a master window. Its
+        -- width is calculated according to mwfact. Other clients are
+        -- cascaded or "tabbed" in a slave column on the right.
+
+        --         (1)                 (2)                 (3)                 (4)
+        --   +----------+---+    +----------+---+    +----------+---+    +----------+---+
+        --   |          |   |    |          | 3 |    |          | 4 |    |         +---+|
+        --   |          |   | -> |          |   | -> |         +---++ -> |        +---+|+
+        --   |  1       | 2 |    |  1      +---++    |  1      | 3 ||    |  1    +---+|+|
+        --   |          |   |    |         | 2 ||    |        +---++|    |      +---+|+ |
+        --   |          |   |    |         |   ||    |        | 2 | |    |      | 2 |+  |
+        --   +----------+---+    +---------+---++    +--------+---+-+    +------+---+---+
+
+        local mwfact
+        if cascade.tile.mwfact > 0 then
+            mwfact = cascade.tile.mwfact
+        else
+            mwfact = t.master_width_factor
+        end
+
+        -- Make slave windows overlap main window? Do this if ncol is 1.
+        local overlap_main
+        if cascade.tile.ncol > 0 then
+            overlap_main = cascade.tile.ncol
+        else
+            overlap_main = t.column_count
+        end
+
+        -- Minimum space for slave windows? See cascade.tile.lua.
+        local num_c
+        if cascade.tile.nmaster > 0 then
+            num_c = cascade.tile.nmaster
+        else
+            num_c = t.master_count
+        end
+
+        local how_many = (#cls - 1 >= num_c and (#cls - 1)) or num_c
+
+        local current_offset_x = cascade.tile.offset_x * (how_many - 1)
+        local current_offset_y = cascade.tile.offset_y * (how_many - 1)
+
+        if #cls <= 0 then return end
+
+        -- Main column, fixed width and height.
+        local c = cls[1]
         local g = {}
+        -- Rounding is necessary to prevent the rendered size of slavewid
+        -- from being 1 pixel off when the result is not an integer.
+        local mainwid = floor(wa.width * mwfact)
+        local slavewid = wa.width - mainwid
+
+        if overlap_main == 1 then
+            g.width = wa.width
+
+            -- The size of the main window may be reduced a little bit.
+            -- This allows you to see if there are any windows below the
+            -- main window.
+            -- This only makes sense, though, if the main window is
+            -- overlapping everything else.
+            g.width = g.width - cascade.tile.extra_padding
+        else
+            g.width = mainwid
+        end
+
+        g.height = wa.height
+        g.x = wa.x
+        g.y = wa.y
+
+        if g.width < 1  then g.width  = 1 end
+        if g.height < 1 then g.height = 1 end
+
+        p.geometries[c] = g
+
+        -- Remaining clients stacked in slave column, new ones on top.
+        if #cls <= 1 then return end
+        for i = 2,#cls do
+            c = cls[i]
+            g = {}
+
+            g.width  = slavewid - current_offset_x
+            g.height = wa.height - current_offset_y
+
+            g.x = wa.x + mainwid + (how_many - (i - 1)) * cascade.tile.offset_x
+            g.y = wa.y + (i - 2) * cascade.tile.offset_y
+
+            if g.width < 1  then g.width  = 1 end
+            if g.height < 1 then g.height = 1 end
+
+            p.geometries[c] = g
+        end
+    end
+end
 
-        g.x = wa.x + (how_many - i) * cascade.offset_x
-        g.y = wa.y + (i - 1) * cascade.offset_y
-        g.width = wa.width - current_offset_x
-        g.height = wa.height - current_offset_y
+function cascade.tile.arrange(p)
+    return do_cascade(p, true)
+end
 
-        c:geometry(g)
-    end
+function cascade.arrange(p)
+    return do_cascade(p, false)
 end
 
 return cascade