]> 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:

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