]> git.madduck.net Git - etc/awesome.git/blob - layout/centerfair.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:

e2ecb3391c5ac8035d0983babdadeeb910776346
[etc/awesome.git] / layout / centerfair.lua
1
2 --[[
3                                                  
4      Licensed under GNU General Public License v2
5       * (c) 2014,      projektile                
6       * (c) 2013,      Luke Bonham               
7       * (c) 2010,      Nicolas Estibals          
8       * (c) 2010-2012, Peter Hofmann             
9                                                  
10 --]]
11
12 local tag       = require("awful.tag")
13 local beautiful = require("beautiful")
14 local math      = { ceil  = math.ceil,
15                     floor = math.floor,
16                     max   = math.max }
17 local tonumber  = tonumber
18
19 local centerfair  = { name = "centerfair" }
20
21 function centerfair.arrange(p)
22     -- Layout with fixed number of vertical columns (read from nmaster).
23     -- Cols are centerded until there is nmaster columns, then windows
24     -- are stacked in the slave columns, with at most ncol clients per
25     -- column if possible.
26
27     -- with nmaster=3 and ncol=1 you'll have
28     --        (1)                (2)                (3)
29     --   +---+---+---+      +-+---+---+-+      +---+---+---+
30     --   |   |   |   |      | |   |   | |      |   |   |   |
31     --   |   | 1 |   |  ->  | | 1 | 2 | | ->   | 1 | 2 | 3 |  ->
32     --   |   |   |   |      | |   |   | |      |   |   |   |
33     --   +---+---+---+      +-+---+---+-+      +---+---+---+
34
35     --        (4)                (5)
36     --   +---+---+---+      +---+---+---+
37     --   |   |   | 3 |      |   | 2 | 4 |
38     --   + 1 + 2 +---+  ->  + 1 +---+---+
39     --   |   |   | 4 |      |   | 3 | 5 |
40     --   +---+---+---+      +---+---+---+
41
42     -- A useless gap (like the dwm patch) can be defined with
43     -- beautiful.useless_gap_width .
44     local useless_gap = tonumber(beautiful.useless_gap_width) or 0
45     if useless_gap < 0 then useless_gap = 0 end
46
47     -- A global border can be defined with
48     -- beautiful.global_border_width
49     local global_border = tonumber(beautiful.global_border_width) or 0
50     if global_border < 0 then global_border = 0 end
51
52     -- Themes border width requires an offset
53     local bw = tonumber(beautiful.border_width) or 0
54
55     -- Screen.
56     local wa = p.workarea
57     local cls = p.clients
58
59     -- Borders are factored in.
60     wa.height = wa.height - ((global_border * 2) + (bw * 2))
61     wa.width = wa.width - ((global_border * 2) + (bw * 2))
62
63     -- How many vertical columns? Read from nmaster on the tag.
64     local t = tag.selected(p.screen)
65     local num_x = centerfair.nmaster or tag.getnmaster(t)
66     local ncol = centerfair.ncol or tag.getncol(t)
67     if num_x <= 2 then num_x = 2 end
68     if num_x > #cls then num_x = #cls end
69
70     local width = math.floor((wa.width-(num_x+1)*useless_gap) / num_x)
71
72     local offset_y = wa.y + useless_gap
73     if #cls < num_x
74     then
75         -- Less clients than the number of columns, let's center it!
76         local offset_x = wa.x + useless_gap + (wa.width - #cls*width - (#cls+1)*useless_gap) / 2
77         local g = {}
78         g.width = width
79         g.height = wa.height - 2*useless_gap - 2
80         g.y = offset_y + global_border
81         for i = 1, #cls do
82             g.x = offset_x + (i - 1) * (width + useless_gap + 2) + global_border
83             cls[i]:geometry(g)
84         end
85     else
86         -- More clients than the number of columns, let's arrange it!
87         local offset_x = wa.x
88         if useless_gap > 0 then
89            offset_x = offset_x
90         end
91
92         -- Master client deserves a special treatement
93         local g = {}
94         g.width = wa.width - (num_x  - 1) * width - num_x * useless_gap
95         g.height = wa.height - 2*useless_gap - 2
96         g.x = offset_x + useless_gap + global_border
97         g.y = offset_y + global_border
98
99         if cls[1] then
100             cls[1]:geometry(g)
101         end
102
103         -- Treat the other clients
104
105         -- Compute distribution of clients among columns
106         local num_y ={}
107         do
108             local remaining_clients = #cls-1
109             local ncol_min = math.ceil(remaining_clients/(num_x-1))
110             if ncol >= ncol_min
111             then
112                 for i = (num_x-1), 1, -1 do
113                     if (remaining_clients-i+1) < ncol
114                     then
115                         num_y[i] = remaining_clients-i + 1
116                     else
117                         num_y[i] = ncol
118                     end
119                     remaining_clients = remaining_clients - num_y[i]
120                 end
121             else
122                 local rem = remaining_clients % (num_x-1)
123                 if rem ==0
124                 then
125                     for i = 1, num_x-1 do
126                         num_y[i] = ncol_min
127                     end
128                 else
129                     for i = 1, num_x-1 do
130                         num_y[i] = ncol_min - 1
131                     end
132                     for i = 0, rem-1 do
133                         num_y[num_x-1-i] = num_y[num_x-1-i] + 1
134                     end
135                 end
136             end
137         end
138
139         -- Compute geometry of the other clients
140         local nclient = 2
141         g.x = g.x + g.width+useless_gap + 2
142         g.width = width
143
144         if useless_gap > 0 then
145             g.width = g.width - useless_gap/2 - 2
146         end
147
148         for i = 1, (num_x-1) do
149             to_remove = 2
150             g.height = math.floor((wa.height - (num_y[i] * useless_gap)) / num_y[i])
151             g.y = offset_y + global_border
152             for j = 0, (num_y[i]-2) do
153                 cls[nclient]:geometry(g)
154                 nclient = nclient + 1
155                 g.y = g.y + g.height+useless_gap + 2
156                 to_remove = to_remove + 2
157             end
158             g.height = wa.height - num_y[i]*useless_gap - (num_y[i]-1)*g.height - useless_gap - to_remove
159             cls[nclient]:geometry(g)
160             nclient = nclient + 1
161             g.x = g.x+g.width+useless_gap + 2
162         end
163     end
164 end
165
166 return centerfair