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

01a2fe06f064fe04858a0d85118cb304fa8f23b7
[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         cls[1]:geometry(g)
99
100         -- Treat the other clients
101
102         -- Compute distribution of clients among columns
103         local num_y ={}
104         do
105             local remaining_clients = #cls-1
106             local ncol_min = math.ceil(remaining_clients/(num_x-1))
107             if ncol >= ncol_min
108             then
109                 for i = (num_x-1), 1, -1 do
110                     if (remaining_clients-i+1) < ncol
111                     then
112                         num_y[i] = remaining_clients-i + 1
113                     else
114                         num_y[i] = ncol
115                     end
116                     remaining_clients = remaining_clients - num_y[i]
117                 end
118             else
119                 local rem = remaining_clients % (num_x-1)
120                 if rem ==0
121                 then
122                     for i = 1, num_x-1 do
123                         num_y[i] = ncol_min
124                     end
125                 else
126                     for i = 1, num_x-1 do
127                         num_y[i] = ncol_min - 1
128                     end
129                     for i = 0, rem-1 do
130                         num_y[num_x-1-i] = num_y[num_x-1-i] + 1
131                     end
132                 end
133             end
134         end
135
136         -- Compute geometry of the other clients
137         local nclient = 2
138         g.x = g.x + g.width+useless_gap + 2
139         g.width = width
140
141         if useless_gap > 0 then
142             g.width = g.width - useless_gap/2 - 2
143         end
144
145         for i = 1, (num_x-1) do
146             to_remove = 2
147             g.height = math.floor((wa.height - (num_y[i] * useless_gap)) / num_y[i])
148             g.y = offset_y + global_border
149             for j = 0, (num_y[i]-2) do
150                 cls[nclient]:geometry(g)
151                 nclient = nclient + 1
152                 g.y = g.y + g.height+useless_gap + 2
153                 to_remove = to_remove + 2
154             end
155             g.height = wa.height - num_y[i]*useless_gap - (num_y[i]-1)*g.height - useless_gap - to_remove
156             cls[nclient]:geometry(g)
157             nclient = nclient + 1
158             g.x = g.x+g.width+useless_gap + 2
159         end
160     end
161 end
162
163 return centerfair