]> git.madduck.net Git - etc/awesome.git/blob - layout/uselesstile.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:

47aa4a443ebcd6695b2d76bdcce94c8a903346a2
[etc/awesome.git] / layout / uselesstile.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2014       projektile                 
6       * (c) 2013       Luke Bonham                
7       * (c) 2009       Donald Ephraim Curtis      
8       * (c) 2008       Julien Danjolu             
9                                                   
10 --]]
11
12 local naughty = require("naughty")
13 local tag       = require("awful.tag")
14 local beautiful = require("beautiful")
15 local ipairs    = ipairs
16 local math      = { floor = math.floor,
17                     max   = math.max,
18                     min   = math.min }
19 local tonumber  = tonumber
20
21 local uselesstile = {}
22
23 local function tile_group(cls, wa, orientation, fact, group)
24     -- A useless gap (like the dwm patch) can be defined with
25     -- beautiful.useless_gap_width .
26     local useless_gap = tonumber(beautiful.useless_gap_width) or 0
27     if useless_gap < 0 then useless_gap = 0 end
28
29     -- A global border can be defined with
30     -- beautiful.global_border_width
31     global_border = tonumber(beautiful.global_border_width) or 0
32     if global_border < 0 then global_border = 0 end
33
34     -- BW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
35
36     -- get our orientation right
37     local height = "height"
38     local width = "width"
39     local x = "x"
40     local y = "y"
41     if orientation == "top" or orientation == "bottom" then
42         height = "width"
43         width = "height"
44         x = "y"
45         y = "x"
46     end
47
48     -- make this more generic (not just width)
49     --if for top
50     available = wa[width] - (group.coord - wa[x]) -- it's truly not here
51
52     -- find our total values
53     local total_fact = 0
54     local min_fact = 1
55     local size = group.size
56     for c = group.first,group.last do
57         -- determine the width/height based on the size_hint
58         local i = c - group.first +1
59         local size_hints = cls[c].size_hints
60         local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0
61         size_hint = size_hint + cls[c].border_width*2
62         size = math.max(size_hint, size)
63
64         -- calculate the height
65         if not fact[i] then
66             fact[i] = min_fact
67         else
68             min_fact = math.min(fact[i],min_fact)
69         end
70         total_fact = total_fact + fact[i]
71     end
72     size = math.min(size, (available - global_border))
73     local coord = wa[y]
74     local geom = {}
75     local used_size = 0
76     local unused = wa[height] - (global_border * 2)
77     local stat_coord = wa[x]
78     --stat_coord = size
79     for c = group.first,group.last do
80         local i = c - group.first +1
81         geom[width] = size - global_border
82         geom[height] = math.floor(unused * fact[i] / total_fact)
83         geom[x] = group.coord + global_border + (useless_gap / 2)
84         geom[y] = coord + global_border + (useless_gap / 2)
85
86         coord = coord + geom[height]
87         unused = unused - geom[height]
88         total_fact = total_fact - fact[i]
89         used_size = math.max(used_size, geom[width])
90
91         -- Useless gap
92         if useless_gap > 0
93         then
94             -- Top and left clients are shrinked by two steps and
95             -- get moved away from the border. Other clients just
96             -- get shrinked in one direction.
97
98             top = false
99             left = false
100
101             if geom[y] == wa[y] then
102                 top = true
103             end
104
105             if geom[x] == 0 or geom[x] == wa[x] then
106                 left = true
107             end
108
109             if top then
110                 geom[height] = geom[height] - (2 * useless_gap)
111                 geom[y] = geom[y] + useless_gap
112             else
113                 geom[height] = geom[height] - useless_gap
114             end
115
116             if left then
117                 geom[width] = geom[width] - (2 * useless_gap)
118                 geom[x] = geom[x] + useless_gap
119             else
120                 geom[width] = geom[width] - useless_gap
121             end
122         end
123         -- End of useless gap.
124
125         geom = cls[c]:geometry(geom)
126     end
127
128     return used_size
129 end
130
131 local function tile(param, orientation)
132     local t = tag.selected(param.screen)
133     orientation = orientation or "right"
134
135     -- this handles are different orientations
136     local height = "height"
137     local width = "width"
138     local x = "x"
139     local y = "y"
140     if orientation == "top" or orientation == "bottom" then
141         height = "width"
142         width = "height"
143         x = "y"
144         y = "x"
145     end
146
147     -- A global border can be defined with
148     -- beautiful.global_border_width
149     global_border = tonumber(beautiful.global_border_width) or 0
150     if global_border < 0 then global_border = 0 end
151
152     local cls = param.clients
153     local nmaster = math.min(tag.getnmaster(t), #cls)
154     local nother = math.max(#cls - nmaster,0)
155
156     local mwfact = tag.getmwfact(t)
157     local wa = param.workarea
158     local ncol = tag.getncol(t)
159
160     local data = tag.getdata(t).windowfact
161
162     if not data then
163         data = {}
164         tag.getdata(t).windowfact = data
165     end
166
167     local coord = wa[x]
168     local place_master = true
169     if orientation == "left" or orientation == "top" then
170         -- if we are on the left or top we need to render the other windows first
171         place_master = false
172     end
173
174     -- this was easier than writing functions because there is a lot of data we need
175     for d = 1,2 do
176         if place_master and nmaster > 0 then
177             local size = wa[width]
178             if nother > 0 then
179                 size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x]))
180             end
181             if not data[0] then
182                 data[0] = {}
183             end
184             coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size})
185         end
186
187         if not place_master and nother > 0 then
188             local last = nmaster
189
190             -- we have to modify the work area size to consider left and top views
191             local wasize = wa[width]
192             if nmaster > 0 and (orientation == "left" or orientation == "top") then
193                 wasize = wa[width] - wa[width]*mwfact
194             end
195             for i = 1,ncol do
196                 -- Try to get equal width among remaining columns
197                 local size = math.min((wasize - (coord - wa[x]))  / (ncol - i + 1)) --+ (global_border/(ncol))/(ncol+i^2)
198                 local first = last + 1
199                 last = last + math.floor((#cls - last)/(ncol - i + 1))
200                 -- tile the column and update our current x coordinate
201                 if not data[i] then
202                     data[i] = {}
203                 end
204                 coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size })
205             end
206         end
207         place_master = not place_master
208     end
209
210 end
211
212 uselesstile.right = {}
213 uselesstile.right.name = "uselesstile"
214 uselesstile.right.arrange = tile
215
216 --- The main tile algo, on left.
217 -- @param screen The screen number to tile.
218 uselesstile.left = {}
219 uselesstile.left.name = "uselesstileleft"
220 function uselesstile.left.arrange(p)
221     return tile(p, "left")
222 end
223
224 --- The main tile algo, on bottom.
225 -- @param screen The screen number to tile.
226 uselesstile.bottom = {}
227 uselesstile.bottom.name = "uselesstilebottom"
228 function uselesstile.bottom.arrange(p)
229     return tile(p, "bottom")
230 end
231
232 --- The main tile algo, on top.
233 -- @param screen The screen number to tile.
234 uselesstile.top = {}
235 uselesstile.top.name = "uselesstiletop"
236 function uselesstile.top.arrange(p)
237     return tile(p, "top")
238 end
239
240 uselesstile.arrange = uselesstile.right.arrange
241 uselesstile.name = uselesstile.right.name
242
243 return uselesstile
244