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

383bf9ebc8dd3a9f1bec96c7b299d10b157b2414
[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
69     local width = math.floor((wa.width-(num_x+1)*useless_gap) / num_x)
70
71     local offset_y = wa.y + useless_gap
72     if #cls < num_x
73     then
74         -- Less clients than the number of columns, let's center it!
75         local offset_x = wa.x + useless_gap + (wa.width - #cls*width - (#cls+1)*useless_gap) / 2
76         local g = {}
77         g.width = width
78         g.height = wa.height - 2*useless_gap - 2
79         g.y = offset_y + global_border
80         for i = 1, #cls do
81             g.x = offset_x + (#cls - i) * (width + useless_gap + 2) + global_border
82             cls[i]:geometry(g)
83         end
84     else
85         -- More clients than the number of columns, let's arrange it!
86         local offset_x = wa.x
87         if useless_gap > 0 then
88            offset_x = offset_x
89         end
90
91         -- Master client deserves a special treatement
92         local g = {}
93         g.width = wa.width - (num_x  - 1) * width - num_x * 2*useless_gap - 2 
94         g.height = wa.height - 2*useless_gap - 2
95         g.x = offset_x + useless_gap + global_border
96         g.y = offset_y + global_border
97
98         cls[#cls]: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 = #cls-1 -- we start with the 2nd client
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
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 = 1, (num_y[i]-1) 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