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

Aux window navigation in centerwork using default key bindings now makes even more...
[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)
61     wa.width = wa.width - (global_border * 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*2*bw) / 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 + (wa.width - #cls*width - #cls*2*bw - (#cls - 1)*useless_gap) / 2
76         local g = {}
77         g.width = width
78         g.height = wa.height - 2*useless_gap - 2*bw
79         g.y = offset_y + global_border
80         for i = 1, #cls do
81             g.x = offset_x + (i - 1) * (width + useless_gap + 2*bw) + 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 + useless_gap
87
88         -- Master client deserves a special treatement
89         local g = {}
90         g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - num_x*2*bw
91         g.height = wa.height - 2*useless_gap - 2*bw
92         g.x = offset_x + global_border
93         g.y = offset_y + global_border
94
95         cls[1]:geometry(g)
96
97         -- Treat the other clients
98
99         -- Compute distribution of clients among columns
100         local num_y ={}
101         do
102             local remaining_clients = #cls-1
103             local ncol_min = math.ceil(remaining_clients/(num_x-1))
104             if ncol >= ncol_min
105             then
106                 for i = (num_x-1), 1, -1 do
107                     if (remaining_clients-i+1) < ncol
108                     then
109                         num_y[i] = remaining_clients-i + 1
110                     else
111                         num_y[i] = ncol
112                     end
113                     remaining_clients = remaining_clients - num_y[i]
114                 end
115             else
116                 local rem = remaining_clients % (num_x-1)
117                 if rem ==0
118                 then
119                     for i = 1, num_x-1 do
120                         num_y[i] = ncol_min
121                     end
122                 else
123                     for i = 1, num_x-1 do
124                         num_y[i] = ncol_min - 1
125                     end
126                     for i = 0, rem-1 do
127                         num_y[num_x-1-i] = num_y[num_x-1-i] + 1
128                     end
129                 end
130             end
131         end
132
133         -- Compute geometry of the other clients
134         local nclient = 2 -- we start with the 2nd client
135         g.x = g.x + g.width + useless_gap + 2*bw
136         g.width = width
137
138         for i = 1, (num_x-1) do
139             g.height = math.floor((wa.height - (num_y[i] + 1)*useless_gap - num_y[i]*2*bw) / num_y[i])
140             g.y = offset_y + global_border
141             for j = 0, (num_y[i]-2) do
142                 cls[nclient]:geometry(g)
143                 nclient = nclient + 1
144                 g.y = g.y + g.height + useless_gap + 2*bw
145             end
146             g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*g.height - num_y[i]*2*bw
147             cls[nclient]:geometry(g)
148             nclient = nclient + 1
149             g.x = g.x + g.width + useless_gap + 2*bw
150         end
151     end
152 end
153
154 return centerfair