1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
7
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
9
<title>Debian Menu System - The internals of the menu package</title>
18
[ <a href="ch6.html">previous</a> ]
19
[ <a href="index.html#contents">Contents</a> ]
20
[ <a href="ch1.html">1</a> ]
21
[ <a href="ch2.html">2</a> ]
22
[ <a href="ch3.html">3</a> ]
23
[ <a href="ch4.html">4</a> ]
24
[ <a href="ch5.html">5</a> ]
25
[ <a href="ch6.html">6</a> ]
27
[ <a href="ch8.html">8</a> ]
28
[ <a href="ch8.html">next</a> ]
34
<br>Chapter 7 - The internals of the menu package
40
<h2>7.1 The update-menus program</h2>
43
On startup, update-menus checks the file <samp>/var/run/update-menus.pid</samp>
44
and the pid in it. If there's an <code>update-menus</code> process with that
45
pid it kills it. If <samp>/var/lib/dpkg/lock</samp> exists, it forks to
46
background and returns control to dpkg. The background process checks the
47
<samp>/var/lib/dpkg/lock</samp> file approx. every second until the file's
51
After that, <code>update-menus</code> reads the menu-entry-files in the
52
following directories:<samp>/etc/menu /usr/lib/menu
53
/usr/share/menu/default</samp> (if a user runs <code>update-menus</code>, it
54
will add ~/.menu to the front of that list). For every menu entry line in each
55
file it checks if the corresponding package is installed (works on file bases
56
for old syntax menu entry files). The menu entries of all
57
"installed" packages are added together in one big buffer that is
58
kept in memory (exception: executable menu entry files are executed, and stdout
59
is placed in the buffer).
62
Once it's read all menu entry files, <code>update-menus</code> starts all
63
executable scripts in /etc/menu-methods/, hands the scripts the previously
64
created buffer via stdin. (If <code>update-menus</code> is ran by a user, it
65
will first try to run the scripts in ~/.menu-methods, and only if that
66
directory doesn't exist, it will run the scripts in /etc/menu-methods).
69
Note that as an aid to debugging, one can use
72
update-menus --stdout > /tmp/menu-stdin
76
and then view the file /tmp/menu-stdin to see exactly what
77
<samp>update-menus</samp> handed the menu-methods on their stdin.
80
This may also be useful for people writing /etc/menu-method/* scripts: Running
81
<code>update-menus</code> every time you changed something in the script may be
82
quite time-consuming. So, it's much easier to run <code>update-menus
83
--stdout</code> once, and then run
86
/etc/menu-methods/mymethod < /tmp/menu-stdin
90
(and, if that also takes too long, just try editing /tmp/menu-stdin, and
91
removing 90% or so of all entries)
96
<h2>7.2 The install-menu program</h2>
99
The files <samp>/etc/menu-methods/$wm</samp> are executable config files that
103
#!/usr/sbin/install-menu
107
and thus start that program, handing it the configuration file for the specific
108
window manager in the first command line argument. This configuration consists
110
<ol type="1" start="1" >
112
the compatibility mode ("menu-1" or "menu-2").
115
<ol type="1" start="2" >
117
where the various files should be stored/read.
120
<ol type="1" start="3" >
122
what "needs" are supported, and what wrapper files should be used for
123
each "type".
128
See <samp>/usr/share/doc/menu/examples/</samp> of the menu package for more
132
Options to <code>install-menu</code>:
136
-d Produce loads of debugging output
140
Some window managers don't support an `include' like statement in their
141
<samp>system.*rc</samp> files (like <code>m4</code> or <code>cpp</code>
142
preprocessing), they cannot read the <samp>menudefs.hook</samp> file generated
143
by install-menu from their <samp>system.*rc</samp> config file. To still be
144
able to use them, <code>install-menu</code> will copy the file
145
<samp>$path/$examplercfile</samp> to <samp>$path/$rcfile</samp> (with
146
<samp>$examplercfile</samp> and <samp>$rcfile</samp> defined in the
147
<code>install-menu</code> config file, and <samp>$path</samp> either the
148
<samp>$rootprefix</samp> or <samp>${HOME}/$userprefix</samp>, depending on
149
whether root or user executed the file.), and replace all occurrences of
150
``install-menu-defs'' with the <samp>$genmenu</samp> file it just generated.
153
As an example, consider the following:
154
<samp>examplercfile=system.foo-wm-example</samp>,
155
<samp>rcfile=system.foo-wm</samp>, <samp>genmenu=menudefs.hook</samp> and
156
<samp>rootprefix=/etc/X11/foo-wm</samp>. Now, if <code>install-menu</code>
157
gets run, it will first generate the file
158
<samp>/etc/X11/foo-wm/menudefs.hook</samp>. Next, it will line-by-line read
159
the file <samp>/etc/X11/foo-wm/system.foo-wm-example</samp> and copy it's
160
contents to <samp>/etc/X11/foo-wm/system.foo-wm</samp>, replacing every
161
occurrence of the string <samp>install-menu-defs</samp> by the contents of the
162
file <samp>/etc/X11/foo-wm/menudefs.hook</samp>.
165
To activate the file copying in this way, simply define the
166
<samp>$examplercfile</samp> and <samp>$rcfile</samp> variables in the
167
<code>install-menu</code> configuration file (for example, see
168
<samp>/etc/menu-methods/fvwm</samp>), and make sure there is a
169
<samp>$path/$examplercfile</samp> (<samp>$path</samp> being either
170
<samp>$rootprefix</samp>, or <samp>$userprefix</samp>.)
173
If you are wringing a menu method, you can use the following to debug it
175
<ol type="1" start="1" >
177
use <samp>update-menus --stdout > /tmp/menu-stdin</samp> to create a list of
178
menu entries in <samp>/tmp/menu-stdin</samp> and then
181
<ol type="1" start="2" >
183
you can run just your menu-method with (if it's called wm):
186
./wm -v < /tmp/menu-stdin
190
(Use <samp>-v</samp> for verbose, <samp>-d</samp> for debugging, and you'll get
198
<h2>7.3 The install-menu config script definitions</h2>
201
The menu-methods in <samp>/etc/menu-methods/*</samp> are basically made up of a
202
lot of ``tag=string'' definitions, explaining <code>install-menu</code> how to
203
generate a <samp>system.$wmrc</samp> script. This way you can tune the look of
204
generated <samp>system.$wmrc</samp> to your needs.
207
In the following, something like
210
treewalk="c(m)"
214
means that the treewalk variable by default has the value "c(m)".
217
For examples of what these scripts can look like, see
218
<samp>/usr/share/doc/menu/examples/*</samp>.
220
<dt><samp>compat="menu-1"</samp></dt>
222
Two mode are defined:
224
<dt><samp>"menu-1"</samp></dt>
226
menu directives are terminated by an end-of-line character.
230
<dt><samp>"menu-2"</samp></dt>
232
menu directives are terminated by semi-comma character.
237
This must be just after the <samp>!include "menu.h"</samp> directive
238
so that <code>menu.h</code> can use its own compat mode.
242
<dt><samp>outputencoding="UTF-8"</samp></dt>
244
Set the encoding used for output files. Use <samp>iconv --list</samp> to get
245
the list of supported encoding. Useful values include "UTF-8" and
246
"ISO-8859-1". The special value "LOCALE" means that the
247
current locale encoding will be used. If set to an empty string, no
248
translations are performed. This is the default.
252
<dt><samp>outputlanguage=""</samp></dt>
254
If set to "C" automatic translations will be disabled. Note that you
255
can still use translate() to perform explicit translation.
259
<dt><samp>supported</samp></dt>
260
<dt><samp>endsupported</samp></dt>
262
Between the <samp>supported</samp> and <samp>endsupported</samp> keywords you
263
define what "needs" are supported by this window manager. So, the
264
following is an example for a wm that supports both needs=x11 and needs=text:
267
function q($s) = "\"" esc($s,"\\\"") "\""
269
x11 =" ShowEntry(" q(title()) ", " q($command) ")"
270
text=" ShowEntry(" q(title()) ", " q(term()) ")"
275
For the variable substitution (and functions, not shown above), see the next
276
paragraph. In the above example, you'll notice that for the menu entries that
277
"need=text", the term() function is used. This is an user-supplied
278
function that will run $command in a X terminal emulator. Also, as x11 is
279
higher up in the supported list above than text, a package that supplies both a
280
"needs=x11" and a "needs=text" entry will have the
281
needs=x11 entry installed, in favour of the needs=text entry. You can continue
282
lines on the next line with a \, but do make sure you don't add any spaces
287
<dt><samp>startmenu=""</samp></dt>
288
<dt><samp>endmenu=""</samp></dt>
289
<dt><samp>submenutitle=""</samp></dt>
291
These define what to print for the beginning/end of a menu, and how to the
292
print a menu entry that pops up another menu entry. They are substituted the
293
same way as the "supported" stuff is. (see next paragraph).
297
<dt><samp>treewalk="c(m)"</samp></dt>
299
This string defines in what order to dump the <samp>$startmenu</samp>,
300
<samp>$endmenu</samp>, and <samp>$submenutitle</samp> (and its children). Each
301
char in the string refers to:
304
c : dump children of menu.
305
m : dump this menu's $submenutitles
308
M : dump all $submenutitles of this menu and this menu's children.
312
The default is "c(m)". For olvwm, one needs: "(M)"
316
<dt><samp>genmenu=""</samp></dt>
318
The menu file to generate (usually something like
319
<samp>system."$wm"rc</samp>). The file itself may depend on the
320
level or title that is currently being worked on, like
323
genmenu="/subdir/" replacewith($section," ","_") "/rc.menu"
327
(Substitution works just like in the supported stuff, see above). Note that
328
the files made this way are truncated upon opening, so if you have a genmenu
329
like the example above, then your <samp>endmenu=</samp> will override the
330
startmenu stuff (but you probably only need one of the two anyway).
334
<dt><samp>rootsection="/Debian"</samp></dt>
336
the prefix, every <samp>$section</samp> variable gets.
340
<dt><samp>prerun=""</samp></dt>
341
<dt><samp>postrun=""</samp></dt>
343
The commands to run before resp. after the actual generation of the
344
<samp>menudefs.hook</samp> (genmenu) file. Commands will be executed by
345
<code>sh</code>. Example:
348
prerun="rm -rf " prefix() "/*"
349
postrun="killall -USR1 fvwm2"
353
(Substitution works just like the supported stuff, see below).
357
<dt><samp>preruntest=""</samp></dt>
359
Just like prerun, but if the return value of the command is non-zero, menu will
364
<dt><samp>also_run=""</samp></dt>
366
If non-zero, install-menus will, after generating the output files, also load
367
the file also_run, and use the new assignments to treewalk, genmenu, etc to
368
generate more output. This second time, variables like <samp>prerun</samp> and
369
all of the hint stuff are ignored.
372
Note: NOT just like <samp>prerun</samp> etc: <samp>prerun</samp> etc start a
373
command with /bin/sh, <samp>also_run</samp> doesn't exec any other command,
374
just tells install-menu to also load another binary, and generate the output.
378
<dt><samp>onlyrunasroot=false</samp></dt>
379
<dt><samp>onlyrunasuser=false</samp></dt>
381
If <samp>onlyrunasroot</samp> is set to true, menu will quit silently when run
382
as user. Similarly for <samp>onlyrunasuser</samp>.
383
<var><samp>onlyrunasroot</samp> is deprecated since it is simpler to just not
384
define <samp>userprefix</samp>.</var> On the other hand,
385
<samp>onlyrunasuser</samp> might be needed if you use <samp>rcfile</samp> since
386
<samp>rootprefix</samp> is used as a fallback location for the template.
390
<dt><samp>preoutput="#Automatically generated file. Do not edit (see /usr/share/doc/menu/html)\n\n"</samp></dt>
391
<dt><samp>postoutput=""</samp></dt>
393
Text to put at the beginning resp. end of the generated file ($genmenu).
397
<dt><samp>command=""</samp></dt>
399
A command to run instead of <code>install-menus</code>. This command used to
400
be needed to get around limitations due to compatibility stuff. But that
401
compatibility with pre menu-1 stuff has been dropped, and isn't needed any
408
command="cat > /tmp/menu-stdin"
413
<dt><samp>hotkeyexclude=""</samp></dt>
415
Keys not to use for hotkey generation. You can use the same variables and
416
functions here as in for example the startmenu sections.
422
hotkeyexclude="q" $section
427
<dt><samp>hotkeycase="insensitive"</samp></dt>
429
can be either "insensitive" or "sensitive". Determines
430
whether the hotkeys can be of mixed case (<samp>fvwm2</samp> reads the hotkeys
431
case-insensitive, <samp>pdmenu</samp> case-sensitive). In case of the titles
432
"Xa" and "xb", hotkey case-insensitive will generate
433
"X" and "b", whereas case-sensitive would generate
434
"X" and "x".
438
<dt><samp>sort=$sort ":" $title</samp></dt>
440
Entries within one menu will be alphabetically sorted by whatever sort returns.
441
So, if you do <samp>sort=ifelse($command, "1",
442
"0"):$title</samp>, then all submenus will appear above the commands
443
in a submenu. (A submenu always has <samp>$command=""</samp>). Or,
447
You can add another field to the menu items, with whatever name you like,
448
let's say it's called priority. Then add this line to
451
sort=ifelse($priority, $priority, "9")
453
This has the result of sorting things so items with a low priority sort to the
454
top, and items with no priority default to priority 9 and sort to the bottom.
456
(Note that it compares the strings alphabetically, not numerically.)
461
<dt><samp>rcfile=""</samp></dt>
463
If the window manager doesn't support an "include filename" or
464
"read(filename)" statement in it's config file, you can rename the
465
wm's config file to <samp>system."$wm"rc-menu</samp>, and insert a
466
"install-menu-defs" line (without the quotes, or whitespace around
467
it, and "install-menu-defs" must be the only thing on the line) in
468
the <samp>system."$wm"rc-menu</samp> file. This will then get
469
replaced by the <samp>$genmenu</samp> file that was just created (see also
470
<samp>$examplercfile</samp>).
474
<dt><samp>examplercfile=""</samp></dt>
476
if needed (see <samp>rcfile</samp>), this is the
477
<samp>system.rc"$wm"-menu</samp> file. In that case, make
478
<samp>rcfile=system.rc"$wm"</samp>.
482
<dt><samp>rootprefix=""</samp></dt>
484
The prefix to use when running as root (applies to $genmenu, $rcfile,
485
$examplercfile and other old cache files). If it is not defined, the
486
menu-method will be skipped when run as root.
490
<dt><samp>userprefix=""</samp></dt>
492
As <samp>rootprefix</samp>, but when running as user. userprefix is relative
493
to the user home directory, unless it start with 2 slashes, in which case it is
494
treated as an absolute path. If it is not defined, the menu-method will be
495
skipped when run as a user.
499
<dt><samp>hint_optimize=false</samp></dt>
501
If set to true, menu will try to generate an `optimal' tree, using the
502
variables below. If set to false, menu will keep the sections as they are
503
specified in the menu entry files (and ignore any hint stuff).
507
<dt><samp>hint_nentry=6</samp></dt>
509
Optimal number of entries in a submenu. It's a float, so you can set it to 5.5
510
if you cannot decide between 5 and 6. Also, values less than 3 probably don't
511
work very well at the moment.
515
<dt><samp>hint_topnentry=5</samp></dt>
517
Same as hint_nentry, but for the top level menu. Often here are other entries,
518
added by the Window Manager itself (like Exit, Xterm, whatever) that menu
519
doesn't know about, so that you may want to instruct menu to put less entries
520
in the top level menu.
524
<dt><samp>hint_mixedpenalty=15.0</samp></dt>
526
Penalty for `mixed' menus. Mixed menus are those with both submenus and direct
531
<dt><samp>hint_minhintfreq=0.1</samp></dt>
533
Minimal relative frequency for the hints before they are considered. Internal
534
variable to speed up the tree generation. If you find menu slow, increase this
535
value (to, say 0.2 or 0.3).
539
<dt><samp>hint_mlpenalty=2000</samp></dt>
541
`max local penalty', while evaluating the possible trees, menu gives
542
`penalties' for submenus that don't contain the desired number of submenus.
543
The penalty is sqrt(n_entry_opt-n_entry), and eventually will be calculated as
544
a sum of all nodes. But to speed things up, menu will discard possibilities in
545
which any node has a `local' penalty of more than hint_mlpenalty. Increase
546
this value if you think menu is overlooking your favorite tree (also decrease
547
minhintfreq), decrease this value if you think menu is wasting too much time.
548
Because of hint_max_ntry, the influence of this variable is nearly zero
553
<dt><samp>hint_max_ntry=4</samp></dt>
555
menu will recursively, for each node, try the hint_max_ntry best local
560
<dt><samp>hints_max_iter_hint=5</samp></dt>
562
The search for what hints to use in one menu is rather expensive. But due to
563
the way things are sorted, menu seems to always find the `best' match in the
564
first 2% of iterations. Thus, a way to speedup things is simply to cut of menu
565
searching after `some' iterations are done. This value controls this, and
566
limits the number of iterations to
567
5+hint_max_iter_hint*number_of_possible_hints. Set this value to negative to
572
<dt><samp>hint_debug=false</samp></dt>
574
Set to true if you want to see loads and loads of debug output.
581
<h2>7.4 Hints, tree optimization</h2>
584
The hints actually work in a rather strange way: when
585
<samp>hint_optimize=true</samp> then all <samp>$section</samp> elements are
586
added to the specified <samp>$hints</samp> variable, and the order
587
(/Apps/Editors or /Editors/Apps) of the resulting hints is completely ignored.
588
Then, the hints for each menu entry are handed to the optimization routine,
589
that will calculate a reasonable tree for those hints. That tree must comply
593
When a user looks for a program "Program" with, say, hints
594
"Good,Bulky,Heaven", then, while walking through the tree, it should
595
at every node visited be clear for the user what submenu to select (or the menu
596
should have "Program" directly in it). So, the toplevel menu may
606
because then a searcher for a menu entry with hints
607
"Good,Bulky,Heaven" will know to select the submenu "Good".
608
The toplevel menu may not look like
617
as now it isn't clear whether to visit the Good or the Heaven submenu.
620
That rule allows usually for many different trees, and the task of the
621
optimization procedure is to select, in a finite amount of time, the tree that
622
best matches the user's desire about the optimum number of menu entries.
626
[ <a href="ch6.html">previous</a> ]
627
[ <a href="index.html#contents">Contents</a> ]
628
[ <a href="ch1.html">1</a> ]
629
[ <a href="ch2.html">2</a> ]
630
[ <a href="ch3.html">3</a> ]
631
[ <a href="ch4.html">4</a> ]
632
[ <a href="ch5.html">5</a> ]
633
[ <a href="ch6.html">6</a> ]
635
[ <a href="ch8.html">8</a> ]
636
[ <a href="ch8.html">next</a> ]
644
version 1.4, 22 March 2005<br>
646
Joost Witteveen <code><a href="mailto:joostje@debian.org">joostje@debian.org</a></code><br>
647
Joey Hess <code><a href="mailto:joeyh@debian.org">joeyh@debian.org</a></code><br>
648
Christian Schwarz <code><a href="mailto:schwarz@debian.org">schwarz@debian.org</a></code><br>
649
Bill Allombert <code><a href="mailto:ballombe@debian.org">ballombe@debian.org</a></code><br>