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

597edce8d7d68a433b6a85acdb29b8d93affb403
[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     -- Screen.
53     local wa = p.workarea
54     local cls = p.clients
55
56     -- Borders are factored in.
57     wa.height = wa.height - (global_border * 2)
58     wa.width = wa.width - (global_border * 2)
59
60     -- How many vertical columns? Read from nmaster on the tag.
61     local t = tag.selected(p.screen)
62     local num_x = centerfair.nmaster or tag.getnmaster(t)
63     local ncol = centerfair.ncol or tag.getncol(t)
64     if num_x <= 2 then num_x = 2 end
65
66     local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x)
67
68     local offset_y = wa.y + useless_gap
69     if #cls < num_x
70     then
71         -- Less clients than the number of columns, let's center it!
72         local offset_x = wa.x + (wa.width - #cls*width - (#cls - 1)*useless_gap) / 2
73         local g = {}
74         g.y = offset_y + global_border
75         for i = 1, #cls do
76             local c = cls[i]
77             g.width = width - 2*c.border_width
78             g.height = wa.height - 2*useless_gap - 2*c.border_width
79             g.x = offset_x + (i - 1) * (width + useless_gap) + global_border
80             c:geometry(g)
81         end
82     else
83         -- More clients than the number of columns, let's arrange it!
84         local offset_x = wa.x + useless_gap
85
86         -- Master client deserves a special treatement
87         local c = cls[1]
88         local g = {}
89         g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width
90         g.height = wa.height - 2*useless_gap - 2*c.border_width
91         g.x = offset_x + global_border
92         g.y = offset_y + global_border
93
94         c:geometry(g)
95
96         -- Treat the other clients
97
98         -- Compute distribution of clients among columns
99         local num_y ={}
100         do
101             local remaining_clients = #cls-1
102             local ncol_min = math.ceil(remaining_clients/(num_x-1))
103             if ncol >= ncol_min
104             then
105                 for i = (num_x-1), 1, -1 do
106                     if (remaining_clients-i+1) < ncol
107                     then
108                         num_y[i] = remaining_clients-i + 1
109                     else
110                         num_y[i] = ncol
111                     end
112                     remaining_clients = remaining_clients - num_y[i]
113                 end
114             else
115                 local rem = remaining_clients % (num_x-1)
116                 if rem ==0
117                 then
118                     for i = 1, num_x-1 do
119                         num_y[i] = ncol_min
120                     end
121                 else
122                     for i = 1, num_x-1 do
123                         num_y[i] = ncol_min - 1
124                     end
125                     for i = 0, rem-1 do
126                         num_y[num_x-1-i] = num_y[num_x-1-i] + 1
127                     end
128                 end
129             end
130         end
131
132         -- Compute geometry of the other clients
133         local nclient = 2 -- we start with the 2nd client
134         g.x = g.x + g.width + useless_gap + 2*c.border_width
135
136         for i = 1, (num_x-1) do
137             local height = math.floor((wa.height - (num_y[i] + 1)*useless_gap) / num_y[i])
138             g.y = offset_y + global_border
139             for j = 0, (num_y[i]-2) do
140                 local c = cls[nclient]
141                 g.height = height - 2*c.border_width
142                 g.width = width - 2*c.border_width
143                 c:geometry(g)
144                 nclient = nclient + 1
145                 g.y = g.y + height + useless_gap
146             end
147             local c = cls[nclient]
148             g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*height - 2*c.border_width
149             g.width = width - 2*c.border_width
150             c:geometry(g)
151             nclient = nclient + 1
152             g.x = g.x + width + useless_gap
153         end
154     end
155 end
156
157 return centerfair