]> git.decadent.org.uk Git - ion3-doc.git/blob - ionconf/node6.html
[svn-upgrade] Integrating new upstream version, ion3-doc (20080103)
[ion3-doc.git] / ionconf / node6.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2
3 <!--Converted with LaTeX2HTML 2002-2-1 (1.71)
4 original version by:  Nikos Drakos, CBLU, University of Leeds
5 * revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
6 * with significant contributions from:
7   Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
8 <HTML>
9 <HEAD>
10 <TITLE>5. Scripting</TITLE>
11 <META NAME="description" CONTENT="5. Scripting">
12 <META NAME="keywords" CONTENT="ionconf">
13 <META NAME="resource-type" CONTENT="document">
14 <META NAME="distribution" CONTENT="global">
15
16 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
17 <META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
18 <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
19
20 <LINK REL="STYLESHEET" HREF="ionconf.css">
21
22 <LINK REL="next" HREF="node7.html">
23 <LINK REL="previous" HREF="node5.html">
24 <LINK REL="up" HREF="ionconf.html">
25 <LINK REL="next" HREF="node7.html">
26 </HEAD>
27
28 <BODY >
29
30 <DIV CLASS="navigation"><!--Navigation Panel-->
31 <A NAME="tex2html362"
32   HREF="node7.html">
33 <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
34 <A NAME="tex2html356"
35   HREF="ionconf.html">
36 <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
37 <A NAME="tex2html350"
38   HREF="node5.html">
39 <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
40 <A NAME="tex2html358"
41   HREF="node1.html">
42 <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
43 <A NAME="tex2html360"
44   HREF="node11.html">
45 <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> 
46 <BR>
47 <B> Next:</B> <A NAME="tex2html363"
48   HREF="node7.html">6. Function reference</A>
49 <B> Up:</B> <A NAME="tex2html357"
50   HREF="ionconf.html">Configuring and extending Ion3</A>
51 <B> Previous:</B> <A NAME="tex2html351"
52   HREF="node5.html">4. Graphical styles</A>
53  &nbsp; <B>  <A NAME="tex2html359"
54   HREF="node1.html">Contents</A></B> 
55  &nbsp; <B>  <A NAME="tex2html361"
56   HREF="node11.html">Index</A></B> 
57 <BR>
58 <BR></DIV>
59 <!--End of Navigation Panel-->
60 <!--Table of Child-Links-->
61 <A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>
62
63 <UL CLASS="ChildLinks">
64 <LI><A NAME="tex2html364"
65   HREF="node6.html#SECTION00610000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">1</SPAN> Hooks</A>
66 <LI><A NAME="tex2html365"
67   HREF="node6.html#SECTION00620000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN> Referring to regions</A>
68 <UL>
69 <LI><A NAME="tex2html366"
70   HREF="node6.html#SECTION00621000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">1</SPAN> Direct object references</A>
71 <LI><A NAME="tex2html367"
72   HREF="node6.html#SECTION00622000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">2</SPAN> Name-based lookups</A>
73 </UL>
74 <BR>
75 <LI><A NAME="tex2html368"
76   HREF="node6.html#SECTION00630000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">3</SPAN> Alternative winprop selection criteria</A>
77 <LI><A NAME="tex2html369"
78   HREF="node6.html#SECTION00640000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">4</SPAN> Writing <TT>ion-statusd</TT> monitors</A>
79 </UL>
80 <!--End of Table of Child-Links-->
81 <HR>
82
83 <H1><A NAME="SECTION00600000000000000000"></A>
84 <A NAME="chap:tricks"></A>
85 <BR>
86 <SPAN CLASS="arabic">5</SPAN>. Scripting
87 </H1>
88
89 <P>
90 This chapter documents some additional features of the Ion configuration
91 and scripting interface that can be used for more advanced scripting than
92 the basic configuration explained in chapter <A HREF="node4.html#chap:config">3</A>.
93
94 <P>
95
96 <H2><A NAME="SECTION00610000000000000000"></A>
97 <A NAME="sec:hooks"></A>
98 <BR>
99 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">1</SPAN> Hooks
100 </H2>
101
102 <P>
103 Hooks are lists of functions to be called when a certain event occurs.
104 There are two types of them; normal and ``alternative'' hooks. Normal
105 hooks do not return anything, but alt-hooks should return a boolean
106 indicating whether it handled its assigned task successfully. In the case
107 that <TT>true</TT> is returned, remaining handlers are not called.
108
109 <P>
110 Hook handlers are registered by first finding the hook
111 with <A HREF="node7.html#fn:ioncore.get_hook"><TT>ioncore.get_hook</TT></A> and then calling <A HREF="node7.html#fn:WHook.add"><TT>WHook.add</TT></A>
112 on the (successful) result with the handler as parameter. Similarly
113 handlers are unregistered with <A HREF="node7.html#fn:WHook.remove"><TT>WHook.remove</TT></A>. For example:
114
115 <P>
116 <PRE>
117 ioncore.get_hook("ioncore_snapshot_hook"):add(
118     function() print("Snapshot hook called.") end
119 )
120 </PRE>
121
122 <P>
123 In this example the hook handler has no parameters, but many hook
124 handlers do. The types of parameters for each hook are listed in
125 the hook reference, section <A HREF="node7.html#sec:hookref">6.9</A>.
126
127 <P>
128 Note that many of the hooks are called in ``protected mode'' and can not 
129 use any functions that modify Ion's internal state. 
130
131 <P>
132
133 <H2><A NAME="SECTION00620000000000000000">
134 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN> Referring to regions</A>
135 </H2>
136
137 <P>
138
139 <H3><A NAME="SECTION00621000000000000000">
140 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">1</SPAN> Direct object references</A>
141 </H3>
142
143 <P>
144 All Ion objects are passed to Lua scripts as 'userdatas', and you may
145 safely store such object references for future use. The C-side object
146 may be destroyed while Lua still refers to the object. All exported
147 functions gracefully fail in such a case, but if you need to explicitly
148 test that the C-side object still exists, use <A HREF="#fn:obj_exists"><TT>obj_exists</TT></A>.
149
150 <P>
151 As an example, the following short piece of code implements 
152 bookmarking:
153
154 <P>
155 <PRE>
156 local bookmarks={}
157
158 -- Set bookmark bm point to the region reg
159 function set_bookmark(bm, reg)
160     bookmarks[bm]=reg
161 end
162
163 -- Go to bookmark bm
164 function goto_bookmark(bm)
165     if bookmarks[bm] then
166         -- We could check that bookmarks[bm] still exists, if we
167         -- wanted to avoid an error message.
168         bookmarks[bm]:goto()
169     end
170 end
171 </PRE>
172
173 <P>
174
175 <H3><A NAME="SECTION00622000000000000000">
176 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">2</SPAN> Name-based lookups</A>
177 </H3>
178
179 <P>
180 If you want to a single non-WClientWin region with an exact known 
181 name, use <A HREF="node7.html#fn:ioncore.lookup_region"><TT>ioncore.lookup_region</TT></A>. If you want a list of all regions,
182 use <A HREF="#fn:ioncore.region_list"><TT>ioncore.region_list</TT></A>. Both functions accept an optional argument
183 that can be used to specify that the returned region(s) must be of a more 
184 specific type. Client windows live in a different namespace and for them
185 you should use the equivalent functions <A HREF="node7.html#fn:ioncore.lookup_clientwin"><TT>ioncore.lookup_clientwin</TT></A>
186 and <A HREF="#fn:ioncore.clientwin_list"><TT>ioncore.clientwin_list</TT></A>.
187
188 <P>
189 To get the name of an object, use <A HREF="node7.html#fn:WRegion.name"><TT>WRegion.name</TT></A>. Please be
190 aware, that the names of client windows reflect their titles and
191 are subject to changes. To change the name of a non-client window
192 region, use <A HREF="node7.html#fn:WRegion.set_name"><TT>WRegion.set_name</TT></A>.
193
194 <P>
195
196 <H2><A NAME="SECTION00630000000000000000">
197 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">3</SPAN> Alternative winprop selection criteria</A>
198 </H2>
199
200 <P>
201 It is possible to write more complex winprop selection routines than
202 those described in section <A HREF="node4.html#sec:winprops">3.5</A>. To match a particular
203 winprop using whatever way you want to, just set the <TT>match</TT>
204 field of the winprop to a function that receives the as its parameters
205 the triple <TT>(prop, cwin, id)</TT>, where <TT>prop</TT> is the table for 
206 the winprop itself, <TT>cwin</TT> is the client window object,
207 and  <TT>id</TT> is the <A HREF="node7.html#fn:WClientWin.get_ident"><TT>WClientWin.get_ident</TT></A> result.
208 The function should return <TT>true</TT> if the winprop matches, 
209 and <TT>false</TT> otherwise. Note that the <TT>match</TT> function
210 is only called after matching against class/role/instance.
211
212 <P>
213 The title of a client window can be obtained with <A HREF="node7.html#fn:WRegion.name"><TT>WRegion.name</TT></A>.
214 If you want to match against (almost) arbitrary window properties,
215 have a look at the documentation for the following functions, and
216 their standard Xlib counterparts: <A HREF="node7.html#fn:ioncore.x_intern_atom"><TT>ioncore.x_intern_atom</TT></A>
217 (XInternAtom), <A HREF="node7.html#fn:ioncore.x_get_window_property"><TT>ioncore.x_get_window_property</TT></A> (XGetWindowProperty),
218 and <A HREF="node7.html#fn:ioncore.x_get_text_property"><TT>ioncore.x_get_text_property</TT></A> (XGetTextProperty).
219
220 <P>
221
222 <P>
223
224 <H2><A NAME="SECTION00640000000000000000"></A>
225 <A NAME="sec:statusd"></A>
226 <BR>
227 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">4</SPAN> Writing <TT>ion-statusd</TT> monitors
228 </H2>
229
230 <P>
231 All statusbar meters that do not monitor the internal state of Ion should
232 go in the separate <TT>ion-statusd</TT> program. 
233
234 <P>
235 Whenever the user requests a meter `<TT>%foo</TT>' or `<TT>%foo_bar</TT>' to 
236 be  inserted in a statusbar, <SPAN  CLASS="textit">mod_statusbar</SPAN> asks <TT>ion-statusd</TT> 
237 to load <A HREF="#fn:statusd_foo.lua"><TT>statusd_foo.lua</TT></A> on its search path (same as that for Ion-side 
238 scripts). This script should then supply all meters with the initial part
239 `<TT>foo</TT>'.
240
241 <P>
242 To provide this value, the script should simply call <TT>statusd.inform</TT>
243 with the name of the meter and the value as a string.
244 Additionally the script should provide a 'template' for the meter to
245 facilitate expected width calculation by <SPAN  CLASS="textit">mod_statusbar</SPAN>, and
246 may provide a 'hint' for colour-coding the value. The interpretation
247 of hints depends on the graphical style in use, and currently the
248 stock styles support the `<TT>normal</TT>', `<TT>important</TT>' and 
249 `<TT>critical</TT>' hints.
250
251 <P>
252 In our example of the 'foo monitor', at script initialisation we might broadcast
253 the template as follows:
254
255 <P>
256 <PRE>
257 statusd.inform("foo_template", "000")
258 </PRE>
259
260 <P>
261 To inform <SPAN  CLASS="textit">mod_statusbar</SPAN> of the actual value of the meter and
262 indicate that the value is critical if above 100, we might write the
263 following function:
264
265 <P>
266 <PRE>
267 local function inform_foo(foo)
268     statusd.inform("foo", tostring(foo))
269     if foo&gt;100 then
270         statusd.inform("foo_hint", "critical")
271     else
272         statusd.inform("foo_hint", "normal")
273     end
274 end
275 </PRE>
276
277 <P>
278 To periodically update the value of the meter, we must use timers.
279 First we must create one:
280
281 <P>
282 <PRE>
283 local foo_timer=statusd.create_timer()
284 </PRE>
285
286 <P>
287 Then we write a function to be called whenever the timer expires.
288 This function must also restart the timer.
289
290 <P>
291 <PRE>
292 local function update_foo()
293     local foo= ... measure foo somehow ...
294     inform_foo(foo)
295     foo_timer:set(settings.update_interval, update_foo)
296 end
297 </PRE>
298
299 <P>
300 Finally, at the end of our script we want to do the initial
301 measurement, and set up timer for further measurements:
302
303 <P>
304 <PRE>
305 update_foo()
306 </PRE>
307
308 <P>
309 If our scripts supports configurable parameters, the following code
310 (at the beginning of the script) will allow them to be configured in
311 <SPAN  CLASS="textit">cfg_statusbar.lua</SPAN> and passed to the status daemon and our script:
312
313 <P>
314 <PRE>
315 local defaults={
316     update_interval=10*1000, -- 10 seconds
317 }
318                 
319 local settings=table.join(statusd.get_config("foo"), defaults)
320 </PRE>
321
322 <P>
323
324 <DIV CLASS="navigation"><HR>
325 <!--Navigation Panel-->
326 <A NAME="tex2html362"
327   HREF="node7.html">
328 <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
329 <A NAME="tex2html356"
330   HREF="ionconf.html">
331 <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
332 <A NAME="tex2html350"
333   HREF="node5.html">
334 <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
335 <A NAME="tex2html358"
336   HREF="node1.html">
337 <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
338 <A NAME="tex2html360"
339   HREF="node11.html">
340 <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> 
341 <BR>
342 <B> Next:</B> <A NAME="tex2html363"
343   HREF="node7.html">6. Function reference</A>
344 <B> Up:</B> <A NAME="tex2html357"
345   HREF="ionconf.html">Configuring and extending Ion3</A>
346 <B> Previous:</B> <A NAME="tex2html351"
347   HREF="node5.html">4. Graphical styles</A>
348  &nbsp; <B>  <A NAME="tex2html359"
349   HREF="node1.html">Contents</A></B> 
350  &nbsp; <B>  <A NAME="tex2html361"
351   HREF="node11.html">Index</A></B> </DIV>
352 <!--End of Navigation Panel-->
353
354 </BODY>
355 </HTML>