revelation: import
[awesome.git] / lib / revelation.lua.in
blob91ec984914bb934404716b5cf7923aa141211d44
1 ---------------------------------------------------------------------------
2 -- @author Espen Wiborg <espenhw@grumblesmurf.org>
3 -- @author Julien Danjou <julien@danjou.info>
4 -- @copyright 2008 Espen Wiborg, Julien Danjou
5 -- @release @AWESOME_VERSION@
6 ---------------------------------------------------------------------------
8 local math = math
9 local table = table
10 local pairs = pairs
11 local button = button
12 local otable = otable
13 local awful =
15 tag = require("awful.tag"),
16 client = require("awful.client")
18 local capi =
20 tag = tag,
21 client = client,
22 keygrabber = keygrabber,
23 mouse = mouse
26 --- Exposé implementation
27 module("revelation")
29 -- Layout functions
30 layout = {}
32 --- The default layout function for revelation
33 -- Tries to arrange clients in an approximated square grid, by
34 -- calculating c = floor(sqrt(n)) and arranging for c columns in a
35 -- tile layout.
36 -- @param t The tag to do revelation on.
37 -- @param n The number of clients to reveal.
38 function layout.default (t, n)
39 t.layout = "tile"
40 local columns = math.floor(math.sqrt(n))
42 if columns > 1 then
43 t.mwfact = 1 / columns
44 t.ncol = columns - 1
45 end
46 t.nmaster = n / columns
47 end
49 function clients(class, s)
50 local clients
51 if class then
52 clients = {}
53 for k, c in pairs(capi.client.get(s)) do
54 if c.class == class then
55 table.insert(clients, c)
56 end
57 end
58 else
59 clients = capi.client.get(s)
60 end
61 return clients
62 end
64 function selectfn(restore)
65 return function(c)
66 restore()
67 -- Pop to client tag
68 awful.tag.viewonly(c:tags()[1])
69 -- Focus and raise
70 capi.client.focus = c
71 c:raise()
72 end
73 end
75 --- Returns keyboardhandler.
76 -- Arrow keys move focus, Return selects, Escape cancels.
77 -- Ignores modifiers.
78 function keyboardhandler (restore)
79 return function (mod, key)
80 if key == "Escape" then
81 restore()
82 awful.tag.history.restore()
83 return false
84 elseif key == "Return" then
85 selectfn(restore)(capi.client.focus)
86 return false
87 end
88 return true
89 end
90 end
92 --- Implement Exposé (from Mac OS X).
93 -- @param class The class of clients to expose, or nil for all clients.
94 -- @param fn A binary function f(t, n) to set the layout for tag t for n clients, or nil for the default layout.
95 -- @param s The screen to consider clients of, or nil for "current screen".
96 function revelation(class, fn, s)
97 local screen = s or capi.mouse.screen
98 local layout_fn = fn or layout.default
99 local data = otable()
101 local clients = clients(class, screen)
102 if #clients == 0 then
103 return
106 local tag = capi.tag({ name = "Revelation" })
107 tag.screen = screen
109 layout_fn(tag, #clients)
111 local function restore()
112 for k, cl in pairs(tag:clients()) do
113 -- Clear revelation tag
114 local tags = cl:tags()
115 if tags[tag] then
116 tags[tags[tag]] = nil
118 cl:tags(tags)
119 -- Restore client mouse bindings
120 cl:buttons(data[cl])
121 data[cl] = nil
123 tag.screen = nil
124 capi.keygrabber.stop()
127 for k, c in pairs(clients) do
128 data[c] = c:buttons()
129 c:buttons({ button({}, 1, selectfn(restore)) })
131 tag:clients(clients)
132 awful.tag.viewonly(tag)
133 capi.keygrabber.run(keyboardhandler(restore))