lib: add @release tag
[awesome.git] / lib / tabulous.lua.in
blobcec465c5708bae8bc7c347960fc1cef17cdadbaa
1 ---------------------------------------------------------------------------
2 -- @author Lucas de Vries <lucasdevries@gmail.com>
3 -- @author Julien Danjou <julien@danjou.info>
4 -- @copyright 2008 Julien Danjou, Lucas de Vries
5 -- @release @AWESOME_VERSION@
6 ---------------------------------------------------------------------------
8 -- Grab environment we need
9 local capi = { client = client }
10 local table = table
11 local pairs = pairs
12 local awful = require('awful')
14 --- tabulous: fabulous tabs for awesome
15 module("tabulous")
17 local tabbed = {}
19 -- Hook creation
20 awful.hooks.user.create('tabbed')
21 awful.hooks.user.create('untabbed')
22 awful.hooks.user.create('tabdisplay')
23 awful.hooks.user.create('tabhide')
25 ---------------
26 -- Functions --
27 ---------------
29 --- Find a key in a table.
30 -- @param table The table to look into
31 -- @param value The value to find.
32 -- @return The key or nil if not found.
33 function findkey(table, value)
34 for k, v in pairs(table) do
35 if v == value then
36 return k
37 end
38 end
39 end
41 --- Swaand select which client in tab is displayed.
42 -- @param tabindex The tab index.
43 -- @param cl The client to show.
44 function display(tabindex, cl)
45 local p = tabbed[tabindex][1]
46 if cl and p ~= cl then
47 cl.hide = false
48 cl:swap(p)
49 p.hide = true
50 cl:focus_set()
52 tabbed[tabindex][1] = cl
54 awful.hooks.user.call('tabhide', p)
55 awful.hooks.user.call('tabdisplay', cl)
56 end
57 end
59 --- Check if the client is in the given tabindex.
60 -- @param tabindex The tab index.
61 -- @param cl The client
62 -- @return The key.
63 function tabindex_check(tabindex, cl)
64 local c = cl or capi.client.focus_get()
65 return findkey(tabbed[tabindex], c)
66 end
68 --- Find the tab index or return nil if not tabbed.
69 -- @param cl The client to search.
70 -- @return The tab index.
71 function tabindex_get(cl)
72 local c = cl or capi.client.focus_get()
74 for tabindex, tabdisplay in pairs(tabbed) do
75 -- Loop through all tab displays
76 local me = tabindex_check(tabindex, c)
78 if me ~= nil then
79 return tabindex
80 end
81 end
83 return nil
84 end
86 --- Get all clients on a tabbed display.
87 -- @param tabindex The tab index.
88 -- @return All tabbed clients.
89 function clients_get(tabindex)
90 if tabbed[tabindex] == nil then return nil end
91 return tabbed[tabindex][2]
92 end
94 --- Get the displayed client on a tabbed display.
95 -- @param tabindex The tab index.
96 -- @return The displayed client.
97 function displayed_get(tabindex)
98 if tabbed[tabindex] == nil then return nil end
99 return tabbed[tabindex][1]
102 --- Get a client by tab number.
103 -- @param tabindex The tab index.
104 -- @param pos The position in the tab.
105 -- @return The client at the given position.
106 function position_get(tabindex, pos)
107 if tabbed[tabindex] == nil then return nil end
108 return tabbed[tabindex][2][pos]
111 --- Get the next client in a tab display.
112 -- @param tabindex The tab index.
113 -- @param cl The current client.
114 -- @return The next client.
115 function next(tabindex, cl)
116 local c = cl or tabbed[tabindex][1]
118 local i = findkey(tabbed[tabindex][2], c)
120 if i == nil then
121 return nil
124 if tabbed[tabindex][2][i+1] == nil then
125 return tabbed[tabindex][2][1]
128 return tabbed[tabindex][2][i + 1]
131 --- Get the previous client in a tabdisplay
132 -- @param tabindex The tab index.
133 -- @param cl The current client.
134 -- @return The previous client.
135 function prev(tabindex, cl)
136 local c = cl or tabbed[tabindex][1]
138 local i = findkey(tabbed[tabindex][2], c)
140 if i == nil then
141 return nil
144 if tabbed[tabindex][2][i-1] == nil then
145 return tabbed[tabindex][2][table.maxn(tabbed[tabindex][2])]
148 return tabbed[tabindex][2][i - 1]
151 --- Remove a client from a tabbed display.
152 -- @param cl The client to remove.
153 -- @return True if the client has been untabbed.
154 function untab(cl)
155 local c = cl or capi.client.focus_get()
156 local tabindex = tabindex_get(c)
158 if tabindex == nil then return false end
160 local cindex = findkey(tabbed[tabindex][2], c)
162 if tabbed[tabindex][1] == c then
163 display(tabindex, next(tabindex, c))
166 table.remove(tabbed[tabindex][2], cindex)
168 if table.maxn(tabbed[tabindex][2]) == 0 then
169 -- Table is empty now, remove the tabbed display
170 table.remove(tabbed, tabindex)
173 c.hide = false
174 awful.hooks.user.call('untabbed', c)
177 --- Untab all clients in a tabbed display.
178 -- @param tabindex The tab index.
179 function untab_all(tabindex)
180 for i,c in pairs(tabbed[tabindex][2]) do
181 c.hide = false
182 awful.hooks.user.call('untabbed', c)
185 if tabbed[tabindex] ~= nil then
186 table.remove(tabbed, tabindex)
190 --- Create a new tabbed display with client as the master.
191 -- @param cl The client to set into the tab, focused one otherwise.
192 -- @return The created tab index.
193 function tab_create(cl)
194 local c = cl or capi.client.focus_get()
196 if not c then return end
198 table.insert(tabbed, {
199 c, -- Window currently being displayed
200 { c } -- List of windows in tabbed display
203 awful.hooks.user.call('tabbed', c)
204 return tabindex_get(c)
207 --- Add a client to a tabbed display.
208 -- @param tabindex The tab index.
209 -- @param cl The client to add, or the focused one otherwise.
210 function tab(tabindex, cl)
211 local c = cl or capi.client.focus_get()
213 if tabbed[tabindex] ~= nil then
214 local x = tabindex_get(c)
216 if x == nil then
217 -- Add untabbed client to tabindex
218 table.insert(tabbed[tabindex][2], c)
219 display(tabindex, c)
221 awful.hooks.user.call('tabbed', c)
222 elseif x ~= tabindex then
223 -- Merge two tabbed views
224 local cc = tabbed[tabindex][1]
225 local clients = clients_get(x)
226 untab_all(x)
228 tabindex = tabindex_get(cc)
230 for i,b in pairs(clients) do
231 tab(tabindex, b)
237 --- Start autotabbing, this automatically tabs new clients when the current
238 -- client is tabbed.
239 function autotab_start()
240 awful.hooks.manage.register(function (c)
241 local sel = capi.client.focus_get()
242 local index = tabindex_get(sel)
244 if index ~= nil then
245 -- Currently focussed client is tabbed,
246 -- add the new window to the tabbed display
247 tab(index, c)
249 end)
252 -- Set up hook so we don't leave lost hidden clients
253 awful.hooks.unmanage.register(untab)
255 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80