]> git.madduck.net Git - etc/awesome.git/blob - layout/cascade.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge pull request #362 from 2009/fix/pulse-sink
[etc/awesome.git] / layout / cascade.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2014,      projektile
5       * (c) 2013,      Luke Bonham
6       * (c) 2010-2012, Peter Hofmann
7
8 --]]
9
10 local floor  = math.floor
11 local screen = screen
12
13 local cascade = {
14     name     = "cascade",
15     nmaster  = 0,
16     offset_x = 32,
17     offset_y = 8,
18     tile     = {
19         name          = "cascadetile",
20         nmaster       = 0,
21         ncol          = 0,
22         mwfact        = 0,
23         offset_x      = 5,
24         offset_y      = 32,
25         extra_padding = 0
26     }
27 }
28
29 local function do_cascade(p, tiling)
30     local t = p.tag or screen[p.screen].selected_tag
31     local wa = p.workarea
32     local cls = p.clients
33
34     if #cls == 0 then return end
35
36     if not tiling then
37         -- Cascade windows.
38
39         local num_c
40         if cascade.nmaster > 0 then
41             num_c = cascade.nmaster
42         else
43             num_c = t.master_count
44         end
45
46         -- Opening a new window will usually force all existing windows to
47         -- get resized. This wastes a lot of CPU time. So let's set a lower
48         -- bound to "how_many": This wastes a little screen space but you'll
49         -- get a much better user experience.
50         local how_many = (#cls >= num_c and #cls) or num_c
51
52         local current_offset_x = cascade.offset_x * (how_many - 1)
53         local current_offset_y = cascade.offset_y * (how_many - 1)
54
55         -- Iterate.
56         for i = 1,#cls,1 do
57             local c = cls[i]
58             local g = {}
59
60             g.x      = wa.x + (how_many - i) * cascade.offset_x
61             g.y      = wa.y + (i - 1) * cascade.offset_y
62             g.width  = wa.width - current_offset_x
63             g.height = wa.height - current_offset_y
64
65             if g.width  < 1 then g.width  = 1 end
66             if g.height < 1 then g.height = 1 end
67
68             p.geometries[c] = g
69         end
70     else
71         -- Layout with one fixed column meant for a master window. Its
72         -- width is calculated according to mwfact. Other clients are
73         -- cascaded or "tabbed" in a slave column on the right.
74
75         --         (1)                 (2)                 (3)                 (4)
76         --   +----------+---+    +----------+---+    +----------+---+    +----------+---+
77         --   |          |   |    |          | 3 |    |          | 4 |    |         +---+|
78         --   |          |   | -> |          |   | -> |         +---++ -> |        +---+|+
79         --   |  1       | 2 |    |  1      +---++    |  1      | 3 ||    |  1    +---+|+|
80         --   |          |   |    |         | 2 ||    |        +---++|    |      +---+|+ |
81         --   |          |   |    |         |   ||    |        | 2 | |    |      | 2 |+  |
82         --   +----------+---+    +---------+---++    +--------+---+-+    +------+---+---+
83
84         local mwfact
85         if cascade.tile.mwfact > 0 then
86             mwfact = cascade.tile.mwfact
87         else
88             mwfact = t.master_width_factor
89         end
90
91         -- Make slave windows overlap main window? Do this if ncol is 1.
92         local overlap_main
93         if cascade.tile.ncol > 0 then
94             overlap_main = cascade.tile.ncol
95         else
96             overlap_main = t.column_count
97         end
98
99         -- Minimum space for slave windows? See cascade.tile.lua.
100         local num_c
101         if cascade.tile.nmaster > 0 then
102             num_c = cascade.tile.nmaster
103         else
104             num_c = t.master_count
105         end
106
107         local how_many = (#cls - 1 >= num_c and (#cls - 1)) or num_c
108
109         local current_offset_x = cascade.tile.offset_x * (how_many - 1)
110         local current_offset_y = cascade.tile.offset_y * (how_many - 1)
111
112         if #cls <= 0 then return end
113
114         -- Main column, fixed width and height.
115         local c = cls[1]
116         local g = {}
117         -- Rounding is necessary to prevent the rendered size of slavewid
118         -- from being 1 pixel off when the result is not an integer.
119         local mainwid = floor(wa.width * mwfact)
120         local slavewid = wa.width - mainwid
121
122         if overlap_main == 1 then
123             g.width = wa.width
124
125             -- The size of the main window may be reduced a little bit.
126             -- This allows you to see if there are any windows below the
127             -- main window.
128             -- This only makes sense, though, if the main window is
129             -- overlapping everything else.
130             g.width = g.width - cascade.tile.extra_padding
131         else
132             g.width = mainwid
133         end
134
135         g.height = wa.height
136         g.x = wa.x
137         g.y = wa.y
138
139         if g.width < 1  then g.width  = 1 end
140         if g.height < 1 then g.height = 1 end
141
142         p.geometries[c] = g
143
144         -- Remaining clients stacked in slave column, new ones on top.
145         if #cls <= 1 then return end
146         for i = 2,#cls do
147             c = cls[i]
148             g = {}
149
150             g.width  = slavewid - current_offset_x
151             g.height = wa.height - current_offset_y
152
153             g.x = wa.x + mainwid + (how_many - (i - 1)) * cascade.tile.offset_x
154             g.y = wa.y + (i - 2) * cascade.tile.offset_y
155
156             if g.width < 1  then g.width  = 1 end
157             if g.height < 1 then g.height = 1 end
158
159             p.geometries[c] = g
160         end
161     end
162 end
163
164 function cascade.tile.arrange(p)
165     return do_cascade(p, true)
166 end
167
168 function cascade.arrange(p)
169     return do_cascade(p, false)
170 end
171
172 return cascade