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

rockspec updated; @aajjbb: please update luarocks entry
[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             if g.width < 1 then g.width = 1 end
81             if g.height < 1 then g.height = 1 end
82             g.x = offset_x + (i - 1) * (width + useless_gap)
83             c:geometry(g)
84         end
85     else
86         -- More clients than the number of columns, let's arrange it!
87         -- Master client deserves a special treatement
88         local c = cls[1]
89         local g = {}
90         g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width
91         g.height = wa.height - 2*useless_gap - 2*c.border_width
92         if g.width < 1 then g.width = 1 end
93         if g.height < 1 then g.height = 1 end
94         g.x = wa.x + useless_gap
95         g.y = wa.y + useless_gap
96
97         c:geometry(g)
98
99         -- Treat the other clients
100
101         -- Compute distribution of clients among columns
102         local num_y ={}
103         do
104             local remaining_clients = #cls-1
105             local ncol_min = math.ceil(remaining_clients/(num_x-1))
106             if ncol >= ncol_min
107             then
108                 for i = (num_x-1), 1, -1 do
109                     if (remaining_clients-i+1) < ncol
110                     then
111                         num_y[i] = remaining_clients-i + 1
112                     else
113                         num_y[i] = ncol
114                     end
115                     remaining_clients = remaining_clients - num_y[i]
116                 end
117             else
118                 local rem = remaining_clients % (num_x-1)
119                 if rem ==0
120                 then
121                     for i = 1, num_x-1 do
122                         num_y[i] = ncol_min
123                     end
124                 else
125                     for i = 1, num_x-1 do
126                         num_y[i] = ncol_min - 1
127                     end
128                     for i = 0, rem-1 do
129                         num_y[num_x-1-i] = num_y[num_x-1-i] + 1
130                     end
131                 end
132             end
133         end
134
135         -- Compute geometry of the other clients
136         local nclient = 2 -- we start with the 2nd client
137         g.x = g.x + g.width + useless_gap + 2*c.border_width
138
139         for i = 1, (num_x-1) do
140             local height = math.floor((wa.height - (num_y[i] + 1)*useless_gap) / num_y[i])
141             g.y = wa.y + useless_gap
142             for j = 0, (num_y[i]-2) do
143                 local c = cls[nclient]
144                 g.height = height - 2*c.border_width
145                 g.width = width - 2*c.border_width
146                 if g.width < 1 then g.width = 1 end
147                 if g.height < 1 then g.height = 1 end
148                 c:geometry(g)
149                 nclient = nclient + 1
150                 g.y = g.y + height + useless_gap
151             end
152             local c = cls[nclient]
153             g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*height - 2*c.border_width
154             g.width = width - 2*c.border_width
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             nclient = nclient + 1
159             g.x = g.x + width + useless_gap
160         end
161     end
162 end
163
164 return centerfair