]> git.decadent.org.uk Git - ion3.git/blob - doc/ionconf/node6.html
[svn-upgrade] Integrating new upstream version, ion3 (20070506)
[ion3.git] / doc / 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="tex2html363"
32   HREF="node7.html">
33 <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
34 <A NAME="tex2html357"
35   HREF="ionconf.html">
36 <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
37 <A NAME="tex2html351"
38   HREF="node5.html">
39 <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
40 <A NAME="tex2html359"
41   HREF="node1.html">
42 <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
43 <A NAME="tex2html361"
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="tex2html364"
48   HREF="node7.html">6. Function reference</A>
49 <B> Up:</B> <A NAME="tex2html358"
50   HREF="ionconf.html">Configuring and extending Ion3</A>
51 <B> Previous:</B> <A NAME="tex2html352"
52   HREF="node5.html">4. Graphical styles</A>
53  &nbsp; <B>  <A NAME="tex2html360"
54   HREF="node1.html">Contents</A></B> 
55  &nbsp; <B>  <A NAME="tex2html362"
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="tex2html365"
65   HREF="node6.html#SECTION00610000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">1</SPAN> Hooks</A>
66 <LI><A NAME="tex2html366"
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="tex2html367"
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="tex2html368"
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="tex2html369"
76   HREF="node6.html#SECTION00630000000000000000"><SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">3</SPAN> Alternative winprop selection criteria</A>
77 <LI><A NAME="tex2html370"
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. TODO: More detailed 
130 documentation when this is final.
131
132 <P>
133
134 <H2><A NAME="SECTION00620000000000000000">
135 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN> Referring to regions</A>
136 </H2>
137
138 <P>
139
140 <H3><A NAME="SECTION00621000000000000000">
141 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">1</SPAN> Direct object references</A>
142 </H3>
143
144 <P>
145 All Ion objects are passed to Lua scripts as 'userdatas', and you may
146 safely store such object references for future use. The C-side object
147 may be destroyed while Lua still refers to the object. All exported
148 functions gracefully fail in such a case, but if you need to explicitly
149 test that the C-side object still exists, use <A HREF="#fn:obj_exists"><TT>obj_exists</TT></A>.
150
151 <P>
152 As an example, the following short piece of code implements 
153 bookmarking:
154
155 <P>
156 <PRE>
157 local bookmarks={}
158
159 -- Set bookmark bm point to the region reg
160 function set_bookmark(bm, reg)
161     bookmarks[bm]=reg
162 end
163
164 -- Go to bookmark bm
165 function goto_bookmark(bm)
166     if bookmarks[bm] then
167         -- We could check that bookmarks[bm] still exists, if we
168         -- wanted to avoid an error message.
169         bookmarks[bm]:goto()
170     end
171 end
172 </PRE>
173
174 <P>
175
176 <H3><A NAME="SECTION00622000000000000000">
177 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">2</SPAN> Name-based lookups</A>
178 </H3>
179
180 <P>
181 If you want to a single non-WClientWin region with an exact known 
182 name, use <A HREF="node7.html#fn:ioncore.lookup_region"><TT>ioncore.lookup_region</TT></A>. If you want a list of all regions,
183 use <A HREF="#fn:ioncore.region_list"><TT>ioncore.region_list</TT></A>. Both functions accept an optional argument
184 that can be used to specify that the returned region(s) must be of a more 
185 specific type. Client windows live in a different namespace and for them
186 you should use the equivalent functions <A HREF="node7.html#fn:ioncore.lookup_clientwin"><TT>ioncore.lookup_clientwin</TT></A>
187 and <A HREF="#fn:ioncore.clientwin_list"><TT>ioncore.clientwin_list</TT></A>.
188
189 <P>
190 To get the name of an object, use <A HREF="node7.html#fn:WRegion.name"><TT>WRegion.name</TT></A>. Please be
191 aware, that the names of client windows reflect their titles and
192 are subject to changes. To change the name of a non-client window
193 region, use <A HREF="node7.html#fn:WRegion.set_name"><TT>WRegion.set_name</TT></A>.
194
195 <P>
196
197 <H2><A NAME="SECTION00630000000000000000">
198 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">3</SPAN> Alternative winprop selection criteria</A>
199 </H2>
200
201 <P>
202 It is possible to write more complex winprop selection routines than
203 those described in section <A HREF="node4.html#sec:winprops">3.5</A>. To match a particular
204 winprop using whatever way you want to, just set the <TT>match</TT>
205 field of the winprop to a function that receives the client window
206 as its sole parameter, and that returns <TT>true</TT> if the winprop
207 matches, and <TT>false</TT> otherwise.
208
209 <P>
210 The class, instance and role properties can be obtained with
211 <A HREF="node7.html#fn:WClientWin.get_ident"><TT>WClientWin.get_ident</TT></A>, and the title with <A HREF="node7.html#fn:WRegion.name"><TT>WRegion.name</TT></A>.
212 If you want to match against (almost) arbitrary window properties,
213 have a look at the documentation for the following functions, and
214 their standard Xlib counterparts: <A HREF="node7.html#fn:ioncore.x_intern_atom"><TT>ioncore.x_intern_atom</TT></A>
215 (XInternAtom), <A HREF="node7.html#fn:ioncore.x_get_window_property"><TT>ioncore.x_get_window_property</TT></A> (XGetWindowProperty),
216 and <A HREF="node7.html#fn:ioncore.x_get_text_property"><TT>ioncore.x_get_text_property</TT></A> (XGetTextProperty).
217
218 <P>
219
220 <P>
221
222 <H2><A NAME="SECTION00640000000000000000"></A>
223 <A NAME="sec:statusd"></A>
224 <BR>
225 <SPAN CLASS="arabic">5</SPAN>.<SPAN CLASS="arabic">4</SPAN> Writing <TT>ion-statusd</TT> monitors
226 </H2>
227
228 <P>
229 All statusbar meters that do not monitor the internal state of Ion should
230 go in the separate <TT>ion-statusd</TT> program. 
231
232 <P>
233 Whenever the user requests a meter `<TT>%foo</TT>' or `<TT>%foo_bar</TT>' to 
234 be  inserted in a statusbar, <SPAN  CLASS="textit">mod_statusbar</SPAN> asks <TT>ion-statusd</TT> 
235 to load <A HREF="#fn:statusd_foo.lua"><TT>statusd_foo.lua</TT></A> on its search path (same as that for Ion-side 
236 scripts). This script should then supply all meters with the initial part
237 `<TT>foo</TT>'.
238
239 <P>
240 To provide this value, the script should simply call <TT>statusd.inform</TT>
241 with the name of the meter and the value as a string.
242 Additionally the script should provide a 'template' for the meter to
243 facilitate expected width calculation by <SPAN  CLASS="textit">mod_statusbar</SPAN>, and
244 may provide a 'hint' for colour-coding the value. The interpretation
245 of hints depends on the graphical style in use, and currently the
246 stock styles support the `<TT>normal</TT>', `<TT>important</TT>' and 
247 `<TT>critical</TT>' hints.
248
249 <P>
250 In our example of the 'foo monitor', at script initialisation we might broadcast
251 the template as follows:
252
253 <P>
254 <PRE>
255 statusd.inform("foo_template", "000")
256 </PRE>
257
258 <P>
259 To inform <SPAN  CLASS="textit">mod_statusbar</SPAN> of the actual value of the meter and
260 indicate that the value is critical if above 100, we might write the
261 following function:
262
263 <P>
264 <PRE>
265 local function inform_foo(foo)
266     statusd.inform("foo", tostring(foo))
267     if foo&gt;100 then
268         statusd.inform("foo_hint", "critical")
269     else
270         statusd.inform("foo_hint", "normal")
271     end
272 end
273 </PRE>
274
275 <P>
276 To periodically update the value of the meter, we must use timers.
277 First we must create one:
278
279 <P>
280 <PRE>
281 local foo_timer=statusd.create_timer()
282 </PRE>
283
284 <P>
285 Then we write a function to be called whenever the timer expires.
286 This function must also restart the timer.
287
288 <P>
289 <PRE>
290 local function update_foo()
291     local foo= ... measure foo somehow ...
292     inform_foo(foo)
293     foo_timer:set(settings.update_interval, update_foo)
294 end
295 </PRE>
296
297 <P>
298 Finally, at the end of our script we want to do the initial
299 measurement, and set up timer for further measurements:
300
301 <P>
302 <PRE>
303 update_foo()
304 </PRE>
305
306 <P>
307 If our scripts supports configurable parameters, the following code
308 (at the beginning of the script) will allow them to be configured in
309 <SPAN  CLASS="textit">cfg_statusbar.lua</SPAN> and passed to the status daemon and our script:
310
311 <P>
312 <PRE>
313 local defaults={
314     update_interval=10*1000, -- 10 seconds
315 }
316                 
317 local settings=table.join(statusd.get_config("foo"), defaults)
318 </PRE>
319
320 <P>
321
322 <DIV CLASS="navigation"><HR>
323 <!--Navigation Panel-->
324 <A NAME="tex2html363"
325   HREF="node7.html">
326 <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
327 <A NAME="tex2html357"
328   HREF="ionconf.html">
329 <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
330 <A NAME="tex2html351"
331   HREF="node5.html">
332 <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
333 <A NAME="tex2html359"
334   HREF="node1.html">
335 <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
336 <A NAME="tex2html361"
337   HREF="node11.html">
338 <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> 
339 <BR>
340 <B> Next:</B> <A NAME="tex2html364"
341   HREF="node7.html">6. Function reference</A>
342 <B> Up:</B> <A NAME="tex2html358"
343   HREF="ionconf.html">Configuring and extending Ion3</A>
344 <B> Previous:</B> <A NAME="tex2html352"
345   HREF="node5.html">4. Graphical styles</A>
346  &nbsp; <B>  <A NAME="tex2html360"
347   HREF="node1.html">Contents</A></B> 
348  &nbsp; <B>  <A NAME="tex2html362"
349   HREF="node11.html">Index</A></B> </DIV>
350 <!--End of Navigation Panel-->
351
352 </BODY>
353 </HTML>