2008-06-11 07:47:57 +02:00
|
|
|
----------------------------------------------------
|
|
|
|
-- tabulous: Fabulous tabs for awesome --
|
|
|
|
-- --
|
|
|
|
-- © 2008 Julien Danjou <julien@danjou.info> --
|
|
|
|
-- © 2008 Lucas de Vries <lucasdevries@gmail.com> --
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
require('awful')
|
2008-06-10 10:18:56 +02:00
|
|
|
|
|
|
|
--------------------
|
|
|
|
-- Module loading --
|
|
|
|
--------------------
|
|
|
|
local P = {}
|
|
|
|
if _REQUIREDNAME == nil then
|
|
|
|
tabulous = P
|
|
|
|
else
|
|
|
|
_G[_REQUIREDNAME] = P
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Grab environment we need
|
|
|
|
local client = client
|
|
|
|
local table = table
|
|
|
|
local pairs = pairs
|
2008-06-11 07:47:57 +02:00
|
|
|
local awful = awful
|
2008-06-11 13:24:38 +02:00
|
|
|
local print = print
|
2008-06-10 10:18:56 +02:00
|
|
|
|
|
|
|
-- Reset env
|
|
|
|
setfenv(1, P)
|
|
|
|
|
|
|
|
local tabbed = {}
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
awful.hooks.userhook_create('tabbed')
|
|
|
|
awful.hooks.userhook_create('untabbed')
|
|
|
|
awful.hooks.userhook_create('tabdisplay')
|
|
|
|
awful.hooks.userhook_create('tabhide')
|
|
|
|
|
|
|
|
---------------
|
|
|
|
-- Functions --
|
|
|
|
---------------
|
|
|
|
|
|
|
|
-- Find the key in a table
|
|
|
|
local function findkey(table, cl)
|
|
|
|
for i, c in pairs(table) do
|
|
|
|
if c == cl then
|
|
|
|
return i
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Swap which tab is displayed
|
|
|
|
local function client_display(tabindex, cl)
|
|
|
|
local p = tabbed[tabindex][1]
|
|
|
|
|
|
|
|
if cl and p ~= cl then
|
2008-06-24 13:44:15 +02:00
|
|
|
cl:hide(false)
|
2008-06-11 07:47:57 +02:00
|
|
|
cl:swap(p)
|
2008-06-24 13:44:15 +02:00
|
|
|
p:hide(true)
|
2008-06-11 07:47:57 +02:00
|
|
|
cl:focus_set()
|
|
|
|
|
|
|
|
tabbed[tabindex][1] = cl
|
|
|
|
|
|
|
|
awful.hooks.userhook_call('tabhide', {p})
|
|
|
|
awful.hooks.userhook_call('tabdisplay', {cl})
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Check if the client is in the given tabindex
|
|
|
|
local function client_in_tabindex(tabindex, cl)
|
|
|
|
local c = cl or client.focus_get()
|
|
|
|
return findkey(tabbed[tabindex], c)
|
|
|
|
end
|
2008-06-10 10:18:56 +02:00
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Find the tab index or return nil if not tabbed
|
|
|
|
local function client_find_tabindex(cl)
|
|
|
|
local c = cl or client.focus_get()
|
|
|
|
|
|
|
|
for tabindex, tabdisplay in pairs(tabbed) do
|
|
|
|
-- Loop through all tab displays
|
|
|
|
local me = client_in_tabindex(tabindex, c)
|
2008-06-10 10:18:56 +02:00
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
if me ~= nil then
|
|
|
|
return tabindex
|
|
|
|
end
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
2008-06-11 07:47:57 +02:00
|
|
|
|
|
|
|
return nil
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
|
2008-06-11 12:32:50 +02:00
|
|
|
-- Get all clients on a tabbed display
|
|
|
|
local function client_get_clients(tabindex)
|
2008-06-11 12:57:12 +02:00
|
|
|
if tabbed[tabindex] == nil then return nil end
|
2008-06-11 12:32:50 +02:00
|
|
|
return tabbed[tabindex][2]
|
2008-06-11 07:47:57 +02:00
|
|
|
end
|
|
|
|
|
2008-06-11 12:32:50 +02:00
|
|
|
-- Get the displayed client on a tabbed display
|
|
|
|
local function client_get_displayed(tabindex)
|
2008-06-11 12:57:12 +02:00
|
|
|
if tabbed[tabindex] == nil then return nil end
|
2008-06-11 12:32:50 +02:00
|
|
|
return tabbed[tabindex][1]
|
|
|
|
end
|
2008-06-11 07:47:57 +02:00
|
|
|
|
2008-06-11 12:32:50 +02:00
|
|
|
-- Get a client by tab number
|
|
|
|
local function client_get_position(tabindex, pos)
|
|
|
|
if tabbed[tabindex] == nil then return nil end
|
|
|
|
return tabbed[tabindex][2][pos]
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Get the next client in a tabdisplay
|
|
|
|
local function client_next(tabindex, cl)
|
|
|
|
local c = cl or tabbed[tabindex][1]
|
|
|
|
|
|
|
|
local i = findkey(tabbed[tabindex][2], c)
|
|
|
|
|
|
|
|
if i == nil then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
if tabbed[tabindex][2][i+1] == nil then
|
|
|
|
return tabbed[tabindex][2][1]
|
|
|
|
else
|
|
|
|
return tabbed[tabindex][2][i+1]
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Get the previous client in a tabdisplay
|
|
|
|
local function client_prev(tabindex, cl)
|
|
|
|
local c = cl or tabbed[tabindex][1]
|
|
|
|
|
|
|
|
local i = findkey(tabbed[tabindex][2], c)
|
|
|
|
|
|
|
|
if i == nil then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
if tabbed[tabindex][2][i-1] == nil then
|
|
|
|
return tabbed[tabindex][2][table.maxn(tabbed[tabindex][2])]
|
|
|
|
else
|
|
|
|
return tabbed[tabindex][2][i-1]
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Remove a client from a tabbed display
|
|
|
|
local function client_untab(cl)
|
|
|
|
local c = cl or client.focus_get()
|
|
|
|
local tabindex = client_find_tabindex(c)
|
|
|
|
if tabindex == nil then return false end
|
|
|
|
|
|
|
|
local cindex = findkey(tabbed[tabindex][2], c)
|
|
|
|
|
|
|
|
if tabbed[tabindex][1] == c then
|
|
|
|
client_display(tabindex, client_next(tabindex, c))
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
2008-06-11 07:47:57 +02:00
|
|
|
|
|
|
|
table.remove(tabbed[tabindex][2], cindex)
|
|
|
|
|
2008-06-11 11:09:23 +02:00
|
|
|
if table.maxn(tabbed[tabindex][2]) == 0 then
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Table is empty now, remove the tabbed display
|
|
|
|
table.remove(tabbed, tabindex)
|
|
|
|
end
|
|
|
|
|
2008-06-24 13:44:15 +02:00
|
|
|
c:hide(false)
|
2008-06-11 07:47:57 +02:00
|
|
|
awful.hooks.userhook_call('untabbed', {c})
|
2008-06-10 10:18:56 +02:00
|
|
|
end
|
|
|
|
|
2008-06-11 12:57:12 +02:00
|
|
|
-- Untab all clients in a tabbed display
|
|
|
|
local function client_untab_all(tabindex)
|
|
|
|
for i,c in pairs(tabbed[tabindex][2]) do
|
2008-06-24 13:44:15 +02:00
|
|
|
c:hide(false)
|
2008-06-11 12:57:12 +02:00
|
|
|
awful.hooks.userhook_call('untabbed', {c})
|
|
|
|
end
|
|
|
|
|
|
|
|
if tabbed[tabindex] ~= nil then
|
|
|
|
table.remove(tabbed, tabindex)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-06-11 12:32:50 +02:00
|
|
|
-- Create a new tabbed display with client as the master
|
|
|
|
local function client_tab_create(cl)
|
|
|
|
local c = cl or client.focus_get()
|
|
|
|
|
|
|
|
table.insert(tabbed, {
|
|
|
|
c, -- Window currently being displayed
|
|
|
|
{ c } -- List of windows in tabbed display
|
|
|
|
})
|
|
|
|
|
|
|
|
awful.hooks.userhook_call('tabbed', {c})
|
|
|
|
return client_find_tabindex(c)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Add a client to a tabbed display
|
|
|
|
local function client_tab(tabindex, cl)
|
|
|
|
local c = cl or client.focus_get()
|
|
|
|
|
|
|
|
if tabbed[tabindex] ~= nil then
|
|
|
|
local x = client_find_tabindex(c)
|
|
|
|
|
|
|
|
if x == nil then
|
|
|
|
-- Add untabbed client to tabindex
|
|
|
|
table.insert(tabbed[tabindex][2], c)
|
|
|
|
client_display(tabindex, c)
|
|
|
|
|
|
|
|
awful.hooks.userhook_call('tabbed', {c})
|
2008-06-11 13:24:38 +02:00
|
|
|
elseif x ~= tabindex then
|
2008-06-11 12:32:50 +02:00
|
|
|
-- Merge two tabbed views
|
2008-06-11 13:24:38 +02:00
|
|
|
local cc = tabbed[tabindex][1]
|
2008-06-11 12:57:12 +02:00
|
|
|
local clients = client_get_clients(x)
|
|
|
|
client_untab_all(x)
|
2008-06-11 12:32:50 +02:00
|
|
|
|
2008-06-11 13:24:38 +02:00
|
|
|
tabindex = client_find_tabindex(cc)
|
|
|
|
|
2008-06-11 12:57:12 +02:00
|
|
|
for i,b in pairs(clients) do
|
2008-06-11 12:32:50 +02:00
|
|
|
client_tab(tabindex, b)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-06-11 07:47:57 +02:00
|
|
|
-- Start autotabbing, this automatically
|
|
|
|
-- tabs new clients when the current client
|
|
|
|
-- is tabbed
|
|
|
|
local function autotab_start()
|
|
|
|
awful.hooks.manage(function (c)
|
|
|
|
local sel = client.focus_get()
|
|
|
|
local index = client_find_tabindex(sel)
|
|
|
|
|
|
|
|
if index ~= nil then
|
|
|
|
-- Currently focussed client is tabbed,
|
|
|
|
-- add the new window to the tabbed display
|
|
|
|
client_tab(index, c)
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Set up hook so we don't leave lost hidden clients
|
|
|
|
awful.hooks.unmanage(function (c) client_untab(c) end)
|
|
|
|
|
|
|
|
P.findkey = findkey
|
|
|
|
P.display = client_display
|
|
|
|
P.tabindex_check = client_in_tabindex
|
|
|
|
P.tabindex_get = client_find_tabindex
|
|
|
|
|
|
|
|
P.tab_create = client_tab_create
|
2008-06-10 10:18:56 +02:00
|
|
|
P.tab = client_tab
|
|
|
|
P.untab = client_untab
|
2008-06-11 07:47:57 +02:00
|
|
|
P.untab_all = client_untab_all
|
|
|
|
|
|
|
|
P.next = client_next
|
|
|
|
P.prev = client_prev
|
|
|
|
|
|
|
|
P.clients_get = client_get_clients
|
|
|
|
P.displayed_get = client_get_displayed
|
|
|
|
P.position_get = client_get_position
|
|
|
|
|
|
|
|
P.autotab_start = autotab_start
|
|
|
|
|
|
|
|
P.tabbed = tabbed
|
|
|
|
|
2008-06-10 10:18:56 +02:00
|
|
|
return P
|