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

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