Commit e0036e20229dc35130764b5ec8c5b6e3d278a28b
1 parent
4aa54d8784
Exists in
master
new layouts
Showing 4 changed files with 612 additions and 0 deletions Side-by-side Diff
awesome/awesome/layouts/browse.lua
View file @
e0036e2
1 | +-- Grab environment. | |
2 | +local awful = require("awful") | |
3 | +local beautiful = require("beautiful") | |
4 | +local ipairs = ipairs | |
5 | +local tonumber = tonumber | |
6 | +local math = math | |
7 | + | |
8 | +module("vain.layout.browse") | |
9 | + | |
10 | +extra_padding = 0 | |
11 | + | |
12 | +name = "browse" | |
13 | + | |
14 | +function arrange(p) | |
15 | + | |
16 | + -- Layout with one fixed column meant for the browser window. Its | |
17 | + -- width is calculated according to mwfact. Other clients are | |
18 | + -- stacked vertically in a slave column on the right. | |
19 | + | |
20 | + -- (1) (2) (3) (4) | |
21 | + -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ | |
22 | + -- | | | | | | | | 3 | | | 4 | | |
23 | + -- | | | | | | | | | | +---+ | |
24 | + -- | 1 | | -> | 1 | 2 | -> | 1 +---+ -> | 1 | 3 | | |
25 | + -- | | | | | | | | 2 | | +---+ | |
26 | + -- | | | | | | | | | | | 2 | | |
27 | + -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ | |
28 | + | |
29 | + -- A useless gap (like the dwm patch) can be defined with | |
30 | + -- beautiful.useless_gap_width. | |
31 | + local useless_gap = tonumber(beautiful.useless_gap_width) | |
32 | + if useless_gap == nil | |
33 | + then | |
34 | + useless_gap = 0 | |
35 | + end | |
36 | + | |
37 | + -- Screen. | |
38 | + local wa = p.workarea | |
39 | + local cls = p.clients | |
40 | + | |
41 | + -- Width of main column? | |
42 | + local t = awful.tag.selected(p.screen) | |
43 | + local mwfact = awful.tag.getmwfact(t) | |
44 | + | |
45 | + -- Make slave windows overlap main window? Do this if ncol is 1. | |
46 | + local overlap_main = awful.tag.getncol(t) | |
47 | + | |
48 | + if #cls > 0 | |
49 | + then | |
50 | + -- Main column, fixed width and height. | |
51 | + local c = cls[#cls] | |
52 | + local g = {} | |
53 | + local mainwid = math.floor(wa.width * mwfact) | |
54 | + local slavewid = wa.width - mainwid | |
55 | + | |
56 | + if overlap_main == 1 | |
57 | + then | |
58 | + g.width = wa.width | |
59 | + | |
60 | + -- The size of the main window may be reduced a little bit. | |
61 | + -- This allows you to see if there are any windows below the | |
62 | + -- main window. | |
63 | + -- This only makes sense, though, if the main window is | |
64 | + -- overlapping everything else. | |
65 | + g.width = g.width - extra_padding | |
66 | + else | |
67 | + g.width = mainwid | |
68 | + end | |
69 | + | |
70 | + g.height = wa.height | |
71 | + g.x = wa.x | |
72 | + g.y = wa.y | |
73 | + if useless_gap > 0 | |
74 | + then | |
75 | + -- Reduce width once and move window to the right. Reduce | |
76 | + -- height twice, however. | |
77 | + g.width = g.width - useless_gap | |
78 | + g.height = g.height - 2 * useless_gap | |
79 | + g.x = g.x + useless_gap | |
80 | + g.y = g.y + useless_gap | |
81 | + | |
82 | + -- When there's no window to the right, add an additional | |
83 | + -- gap. | |
84 | + if overlap_main == 1 | |
85 | + then | |
86 | + g.width = g.width - useless_gap | |
87 | + end | |
88 | + end | |
89 | + c:geometry(g) | |
90 | + | |
91 | + -- Remaining clients stacked in slave column, new ones on top. | |
92 | + if #cls > 1 | |
93 | + then | |
94 | + local slavehei = math.floor(wa.height / (#cls - 1)) | |
95 | + for i = (#cls - 1),1,-1 | |
96 | + do | |
97 | + c = cls[i] | |
98 | + g = {} | |
99 | + g.width = slavewid | |
100 | + if i == (#cls - 1) | |
101 | + then | |
102 | + g.height = wa.height - (#cls - 2) * slavehei | |
103 | + else | |
104 | + g.height = slavehei | |
105 | + end | |
106 | + g.x = wa.x + mainwid | |
107 | + g.y = wa.y + (i - 1) * slavehei | |
108 | + if useless_gap > 0 | |
109 | + then | |
110 | + g.width = g.width - 2 * useless_gap | |
111 | + if i == 1 | |
112 | + then | |
113 | + -- This is the topmost client. Push it away from | |
114 | + -- the screen border (add to g.y and subtract | |
115 | + -- useless_gap once) and additionally shrink its | |
116 | + -- height. | |
117 | + g.height = g.height - 2 * useless_gap | |
118 | + g.y = g.y + useless_gap | |
119 | + else | |
120 | + -- All other clients. | |
121 | + g.height = g.height - useless_gap | |
122 | + end | |
123 | + g.x = g.x + useless_gap | |
124 | + end | |
125 | + c:geometry(g) | |
126 | + end | |
127 | + end | |
128 | + end | |
129 | +end | |
130 | + | |
131 | +-- vim: set et : |
awesome/awesome/layouts/termfair.lua
View file @
e0036e2
1 | +-- Grab environment. | |
2 | +local tag = require("awful.tag") | |
3 | +local beautiful = require("beautiful") | |
4 | +local math = math | |
5 | +local tonumber = tonumber | |
6 | + | |
7 | +module("vain.layout.termfair") | |
8 | + | |
9 | +name = "termfair" | |
10 | + | |
11 | +function arrange(p) | |
12 | + | |
13 | + -- Layout with fixed number of vertical columns (read from nmaster). | |
14 | + -- New windows align from left to right. When a row is full, a now | |
15 | + -- one above it is created. Like this: | |
16 | + | |
17 | + -- (1) (2) (3) | |
18 | + -- +---+---+---+ +---+---+---+ +---+---+---+ | |
19 | + -- | | | | | | | | | | | | | |
20 | + -- | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> | |
21 | + -- | | | | | | | | | | | | | |
22 | + -- +---+---+---+ +---+---+---+ +---+---+---+ | |
23 | + | |
24 | + -- (4) (5) (6) | |
25 | + -- +---+---+---+ +---+---+---+ +---+---+---+ | |
26 | + -- | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | | |
27 | + -- +---+---+---+ -> +---+---+---+ -> +---+---+---+ | |
28 | + -- | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | | |
29 | + -- +---+---+---+ +---+---+---+ +---+---+---+ | |
30 | + | |
31 | + -- A useless gap (like the dwm patch) can be defined with | |
32 | + -- beautiful.useless_gap_width. | |
33 | + local useless_gap = tonumber(beautiful.useless_gap_width) | |
34 | + if useless_gap == nil | |
35 | + then | |
36 | + useless_gap = 0 | |
37 | + end | |
38 | + | |
39 | + -- Screen. | |
40 | + local wa = p.workarea | |
41 | + local cls = p.clients | |
42 | + | |
43 | + -- How many vertical columns? Read from nmaster on the tag. | |
44 | + local t = tag.selected(p.screen) | |
45 | + local num_x = tag.getnmaster(t) | |
46 | + | |
47 | + -- Do at least "desired_y" rows. Read this from ncol. (Yes, I use a | |
48 | + -- *column* setting to set the number of *rows*. That's because | |
49 | + -- num_x is the *master* setting -- it's the setting that's most | |
50 | + -- important to me.) | |
51 | + local desired_y = tag.getncol(t) | |
52 | + | |
53 | + if #cls > 0 | |
54 | + then | |
55 | + local num_y = math.max(math.ceil(#cls / num_x), desired_y) | |
56 | + local cur_num_x = num_x | |
57 | + local at_x = 0 | |
58 | + local at_y = 0 | |
59 | + local remaining_clients = #cls | |
60 | + local width = math.floor(wa.width / num_x) | |
61 | + local height = math.floor(wa.height / num_y) | |
62 | + | |
63 | + -- We start the first row. Left-align by limiting the number of | |
64 | + -- available slots. | |
65 | + if remaining_clients < num_x | |
66 | + then | |
67 | + cur_num_x = remaining_clients | |
68 | + end | |
69 | + | |
70 | + -- Iterate in reversed order. | |
71 | + for i = #cls,1,-1 | |
72 | + do | |
73 | + -- Get x and y position. | |
74 | + local c = cls[i] | |
75 | + local this_x = cur_num_x - at_x - 1 | |
76 | + local this_y = num_y - at_y - 1 | |
77 | + | |
78 | + -- Calc geometry. | |
79 | + local g = {} | |
80 | + if this_x == (num_x - 1) | |
81 | + then | |
82 | + g.width = wa.width - (num_x - 1) * width | |
83 | + else | |
84 | + g.width = width | |
85 | + end | |
86 | + if this_y == (num_y - 1) | |
87 | + then | |
88 | + g.height = wa.height - (num_y - 1) * height | |
89 | + else | |
90 | + g.height = height | |
91 | + end | |
92 | + g.x = wa.x + this_x * width | |
93 | + g.y = wa.y + this_y * height | |
94 | + if useless_gap > 0 | |
95 | + then | |
96 | + -- Top and left clients are shrinked by two steps and | |
97 | + -- get moved away from the border. Other clients just | |
98 | + -- get shrinked in one direction. | |
99 | + if this_x == 0 | |
100 | + then | |
101 | + g.width = g.width - 2 * useless_gap | |
102 | + g.x = g.x + useless_gap | |
103 | + else | |
104 | + g.width = g.width - useless_gap | |
105 | + end | |
106 | + | |
107 | + if this_y == 0 | |
108 | + then | |
109 | + g.height = g.height - 2 * useless_gap | |
110 | + g.y = g.y + useless_gap | |
111 | + else | |
112 | + g.height = g.height - useless_gap | |
113 | + end | |
114 | + end | |
115 | + c:geometry(g) | |
116 | + remaining_clients = remaining_clients - 1 | |
117 | + | |
118 | + -- Next grid position. | |
119 | + at_x = at_x + 1 | |
120 | + if at_x == num_x | |
121 | + then | |
122 | + -- Row full, create a new one above it. | |
123 | + at_x = 0 | |
124 | + at_y = at_y + 1 | |
125 | + | |
126 | + -- We start a new row. Left-align. | |
127 | + if remaining_clients < num_x | |
128 | + then | |
129 | + cur_num_x = remaining_clients | |
130 | + end | |
131 | + end | |
132 | + end | |
133 | + end | |
134 | +end | |
135 | + | |
136 | +-- vim: set et : |
awesome/awesome/layouts/uselessfair.lua
View file @
e0036e2
1 | +--------------------------------------------------------------------------- | |
2 | +-- @author Julien Danjou <julien@danjou.info> | |
3 | +-- @copyright 2008 Julien Danjou | |
4 | +-- @copyright 2010 Vain | |
5 | +-- @release v3.4.6 | |
6 | +--------------------------------------------------------------------------- | |
7 | + | |
8 | +-- Grab environment we need | |
9 | +local beautiful = require("beautiful") | |
10 | +local ipairs = ipairs | |
11 | +local math = math | |
12 | +local tonumber = tonumber | |
13 | + | |
14 | +module("vain.layout.uselessfair") | |
15 | + | |
16 | +local function fair(p, orientation) | |
17 | + -- A useless gap (like the dwm patch) can be defined with | |
18 | + -- beautiful.useless_gap_width . | |
19 | + local useless_gap = tonumber(beautiful.useless_gap_width) | |
20 | + if useless_gap == nil | |
21 | + then | |
22 | + useless_gap = 0 | |
23 | + end | |
24 | + | |
25 | + -- Mostly copied. | |
26 | + local wa = p.workarea | |
27 | + local cls = p.clients | |
28 | + | |
29 | + if #cls > 0 then | |
30 | + local cells = math.ceil(math.sqrt(#cls)) | |
31 | + local strips = math.ceil(#cls / cells) | |
32 | + | |
33 | + local cell = 0 | |
34 | + local strip = 0 | |
35 | + for k, c in ipairs(cls) do | |
36 | + local g = {} | |
37 | + -- Save actual grid index for use in the useless_gap | |
38 | + -- routine. | |
39 | + local this_x = 0 | |
40 | + local this_y = 0 | |
41 | + if ( orientation == "east" and #cls > 2 ) | |
42 | + or ( orientation == "south" and #cls <= 2 ) then | |
43 | + if #cls < (strips * cells) and strip == strips - 1 then | |
44 | + g.width = wa.width / (cells - ((strips * cells) - #cls)) | |
45 | + else | |
46 | + g.width = wa.width / cells | |
47 | + end | |
48 | + g.height = wa.height / strips | |
49 | + | |
50 | + this_x = cell | |
51 | + this_y = strip | |
52 | + | |
53 | + g.x = wa.x + cell * g.width | |
54 | + g.y = wa.y + strip * g.height | |
55 | + | |
56 | + else | |
57 | + if #cls < (strips * cells) and strip == strips - 1 then | |
58 | + g.height = wa.height / (cells - ((strips * cells) - #cls)) | |
59 | + else | |
60 | + g.height = wa.height / cells | |
61 | + end | |
62 | + g.width = wa.width / strips | |
63 | + | |
64 | + this_x = strip | |
65 | + this_y = cell | |
66 | + | |
67 | + g.x = wa.x + strip * g.width | |
68 | + g.y = wa.y + cell * g.height | |
69 | + end | |
70 | + | |
71 | + -- Useless gap. | |
72 | + if useless_gap > 0 | |
73 | + then | |
74 | + -- Top and left clients are shrinked by two steps and | |
75 | + -- get moved away from the border. Other clients just | |
76 | + -- get shrinked in one direction. | |
77 | + if this_x == 0 | |
78 | + then | |
79 | + g.width = g.width - 2 * useless_gap | |
80 | + g.x = g.x + useless_gap | |
81 | + else | |
82 | + g.width = g.width - useless_gap | |
83 | + end | |
84 | + | |
85 | + if this_y == 0 | |
86 | + then | |
87 | + g.height = g.height - 2 * useless_gap | |
88 | + g.y = g.y + useless_gap | |
89 | + else | |
90 | + g.height = g.height - useless_gap | |
91 | + end | |
92 | + end | |
93 | + -- End of useless gap. | |
94 | + | |
95 | + c:geometry(g) | |
96 | + | |
97 | + cell = cell + 1 | |
98 | + if cell == cells then | |
99 | + cell = 0 | |
100 | + strip = strip + 1 | |
101 | + end | |
102 | + end | |
103 | + end | |
104 | +end | |
105 | + | |
106 | +--- Horizontal fair layout. | |
107 | +-- @param screen The screen to arrange. | |
108 | +horizontal = {} | |
109 | +horizontal.name = "fairh" | |
110 | +function horizontal.arrange(p) | |
111 | + return fair(p, "east") | |
112 | +end | |
113 | + | |
114 | +-- Vertical fair layout. | |
115 | +-- @param screen The screen to arrange. | |
116 | +name = "fairv" | |
117 | +function arrange(p) | |
118 | + return fair(p, "south") | |
119 | +end |
awesome/awesome/layouts/uselesstile.lua
View file @
e0036e2
1 | +--------------------------------------------------------------------------- | |
2 | +-- @author Donald Ephraim Curtis <dcurtis@cs.uiowa.edu> | |
3 | +-- @author Julien Danjou <julien@danjou.info> | |
4 | +-- @copyright 2009 Donald Ephraim Curtis | |
5 | +-- @copyright 2008 Julien Danjou | |
6 | +-- @release v3.4.11 | |
7 | +--------------------------------------------------------------------------- | |
8 | + | |
9 | +-- Grab environment we need | |
10 | +local tag = require("awful.tag") | |
11 | +local beautiful = require("beautiful") | |
12 | +local ipairs = ipairs | |
13 | +local math = math | |
14 | + | |
15 | +module("vain.layout.uselesstile") | |
16 | + | |
17 | +local function tile_group(cls, wa, orientation, fact, group) | |
18 | + -- A useless gap (like the dwm patch) can be defined with | |
19 | + -- beautiful.useless_gap_width . | |
20 | + local useless_gap = tonumber(beautiful.useless_gap_width) | |
21 | + if useless_gap == nil | |
22 | + then | |
23 | + useless_gap = 0 | |
24 | + end | |
25 | + | |
26 | + -- get our orientation right | |
27 | + local height = "height" | |
28 | + local width = "width" | |
29 | + local x = "x" | |
30 | + local y = "y" | |
31 | + if orientation == "top" or orientation == "bottom" then | |
32 | + height = "width" | |
33 | + width = "height" | |
34 | + x = "y" | |
35 | + y = "x" | |
36 | + end | |
37 | + | |
38 | + -- make this more generic (not just width) | |
39 | + available = wa[width] - (group.coord - wa[x]) | |
40 | + | |
41 | + -- find our total values | |
42 | + local total_fact = 0 | |
43 | + local min_fact = 1 | |
44 | + local size = group.size | |
45 | + for c = group.first,group.last do | |
46 | + -- determine the width/height based on the size_hint | |
47 | + local i = c - group.first +1 | |
48 | + local size_hints = cls[c].size_hints | |
49 | + local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0 | |
50 | + size_hint = size_hint + cls[c].border_width*2 | |
51 | + size = math.max(size_hint, size) | |
52 | + | |
53 | + -- calculate the height | |
54 | + if not fact[i] then | |
55 | + fact[i] = min_fact | |
56 | + else | |
57 | + min_fact = math.min(fact[i],min_fact) | |
58 | + end | |
59 | + total_fact = total_fact + fact[i] | |
60 | + end | |
61 | + size = math.min(size, available) | |
62 | + | |
63 | + local coord = wa[y] | |
64 | + local geom = {} | |
65 | + local used_size = 0 | |
66 | + local unused = wa[height] | |
67 | + local stat_coord = wa[x] | |
68 | + --stat_coord = size | |
69 | + for c = group.first,group.last do | |
70 | + local i = c - group.first +1 | |
71 | + geom[width] = size | |
72 | + geom[height] = math.floor(unused * fact[i] / total_fact) | |
73 | + geom[x] = group.coord | |
74 | + geom[y] = coord | |
75 | + | |
76 | + coord = coord + geom[height] | |
77 | + unused = unused - geom[height] | |
78 | + total_fact = total_fact - fact[i] | |
79 | + used_size = math.max(used_size, geom[width]) | |
80 | + | |
81 | + -- Useless gap | |
82 | + if useless_gap > 0 | |
83 | + then | |
84 | + -- Top and left clients are shrinked by two steps and | |
85 | + -- get moved away from the border. Other clients just | |
86 | + -- get shrinked in one direction. | |
87 | + | |
88 | + top = false | |
89 | + left = false | |
90 | + | |
91 | + if geom[y] == wa[y] then | |
92 | + top = true | |
93 | + end | |
94 | + | |
95 | + if geom[x] == 0 or geom[x] == wa[x] then | |
96 | + left = true | |
97 | + end | |
98 | + | |
99 | + if top then | |
100 | + geom[height] = geom[height] - 2 * useless_gap | |
101 | + geom[y] = geom[y] + useless_gap | |
102 | + else | |
103 | + geom[height] = geom[height] - useless_gap | |
104 | + end | |
105 | + | |
106 | + if left then | |
107 | + geom[width] = geom[width] - 2 * useless_gap | |
108 | + geom[x] = geom[x] + useless_gap | |
109 | + else | |
110 | + geom[width] = geom[width] - useless_gap | |
111 | + end | |
112 | + end | |
113 | + -- End of useless gap. | |
114 | + | |
115 | + geom = cls[c]:geometry(geom) | |
116 | + end | |
117 | + | |
118 | + return used_size | |
119 | +end | |
120 | + | |
121 | +local function tile(param, orientation) | |
122 | + local t = tag.selected(param.screen) | |
123 | + orientation = orientation or "right" | |
124 | + | |
125 | + -- this handles are different orientations | |
126 | + local height = "height" | |
127 | + local width = "width" | |
128 | + local x = "x" | |
129 | + local y = "y" | |
130 | + if orientation == "top" or orientation == "bottom" then | |
131 | + height = "width" | |
132 | + width = "height" | |
133 | + x = "y" | |
134 | + y = "x" | |
135 | + end | |
136 | + | |
137 | + local cls = param.clients | |
138 | + local nmaster = math.min(tag.getnmaster(t), #cls) | |
139 | + local nother = math.max(#cls - nmaster,0) | |
140 | + | |
141 | + local mwfact = tag.getmwfact(t) | |
142 | + local wa = param.workarea | |
143 | + local ncol = tag.getncol(t) | |
144 | + | |
145 | + local data = tag.getdata(t).windowfact | |
146 | + | |
147 | + if not data then | |
148 | + data = {} | |
149 | + tag.getdata(t).windowfact = data | |
150 | + end | |
151 | + | |
152 | + local coord = wa[x] | |
153 | + local place_master = true | |
154 | + if orientation == "left" or orientation == "top" then | |
155 | + -- if we are on the left or top we need to render the other windows first | |
156 | + place_master = false | |
157 | + end | |
158 | + | |
159 | + -- this was easier than writing functions because there is a lot of data we need | |
160 | + for d = 1,2 do | |
161 | + if place_master and nmaster > 0 then | |
162 | + local size = wa[width] | |
163 | + if nother > 0 then | |
164 | + size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x])) | |
165 | + end | |
166 | + if not data[0] then | |
167 | + data[0] = {} | |
168 | + end | |
169 | + coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}) | |
170 | + end | |
171 | + | |
172 | + if not place_master and nother > 0 then | |
173 | + local last = nmaster | |
174 | + | |
175 | + -- we have to modify the work area size to consider left and top views | |
176 | + local wasize = wa[width] | |
177 | + if nmaster > 0 and (orientation == "left" or orientation == "top") then | |
178 | + wasize = wa[width] - wa[width]*mwfact | |
179 | + end | |
180 | + for i = 1,ncol do | |
181 | + -- Try to get equal width among remaining columns | |
182 | + local size = math.min( (wasize - (coord - wa[x])) / (ncol - i + 1) ) | |
183 | + local first = last + 1 | |
184 | + last = last + math.floor((#cls - last)/(ncol - i + 1)) | |
185 | + -- tile the column and update our current x coordinate | |
186 | + if not data[i] then | |
187 | + data[i] = {} | |
188 | + end | |
189 | + coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }) | |
190 | + end | |
191 | + end | |
192 | + place_master = not place_master | |
193 | + end | |
194 | + | |
195 | +end | |
196 | + | |
197 | +right = {} | |
198 | +right.name = "uselesstile" | |
199 | +right.arrange = tile | |
200 | + | |
201 | +--- The main tile algo, on left. | |
202 | +-- @param screen The screen number to tile. | |
203 | +left = {} | |
204 | +left.name = "uselesstileleft" | |
205 | +function left.arrange(p) | |
206 | + return tile(p, "left") | |
207 | +end | |
208 | + | |
209 | +--- The main tile algo, on bottom. | |
210 | +-- @param screen The screen number to tile. | |
211 | +bottom = {} | |
212 | +bottom.name = "uselesstilebottom" | |
213 | +function bottom.arrange(p) | |
214 | + return tile(p, "bottom") | |
215 | +end | |
216 | + | |
217 | +--- The main tile algo, on top. | |
218 | +-- @param screen The screen number to tile. | |
219 | +top = {} | |
220 | +top.name = "uselesstiletop" | |
221 | +function top.arrange(p) | |
222 | + return tile(p, "top") | |
223 | +end | |
224 | + | |
225 | +arrange = right.arrange | |
226 | +name = right.name |