awesomerc: use byidx()
[awesome.git] / lib / revelation.lua.in
blobd4ea09ffa66b776d866b99ca35d34e360b809c8b
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 elseif key == "Left" or key == "Right" or
88 key == "Up" or key == "Down" then
89 awful.client.focus.bydirection(key:lower())
90 end
91 return true
92 end
93 end
95 --- Implement Exposé (from Mac OS X).
96 -- @param class The class of clients to expose, or nil for all clients.
97 -- @param fn A binary function f(t, n) to set the layout for tag t for n clients, or nil for the default layout.
98 -- @param s The screen to consider clients of, or nil for "current screen".
99 function revelation(class, fn, s)
100 local screen = s or capi.mouse.screen
101 local layout_fn = fn or layout.default
102 local data = otable()
104 local clients = clients(class, screen)
105 if #clients == 0 then
106 return
109 local tag = capi.tag({ name = "Revelation" })
110 tag.screen = screen
112 layout_fn(tag, #clients)
114 local function restore()
115 for k, cl in pairs(tag:clients()) do
116 -- Clear revelation tag
117 local tags = cl:tags()
118 if tags[tag] then
119 tags[tags[tag]] = nil
121 cl:tags(tags)
122 -- Restore client mouse bindings
123 cl:buttons(data[cl])
124 data[cl] = nil
126 tag.screen = nil
127 capi.keygrabber.stop()
130 for k, c in pairs(clients) do
131 data[c] = c:buttons()
132 c:buttons({ button({}, 1, selectfn(restore)) })
134 tag:clients(clients)
135 awful.tag.viewonly(tag)
136 capi.keygrabber.run(keyboardhandler(restore))