1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
|
<!doctype debiandoc system>
<!--
Debian Menu System
Copyright (C) 1997 Joost Witteveen, Joey Hess, Christian Schwarz;
released under the terms of the GNU
General Public License, version 2 or (at your option) any later.
-->
<book>
<title>Debian Menu System
<author>Joost Witteveen <email/joostje@debian.org/
<author>Joey Hess <email/joey@kite.ml.org/
<author>Christian Schwarz <email/schwarz@debian.org/
<version>version 1.3, <date>
<abstract>
The <tt/menu/ package was inspired by the <tt/install-fvwm2-menu/
program from the old <prgn/fvwm2/ package. However, <tt/menu/ tries to
provide a more general interface for menu building. With the
<prgn/update-menus/ command from this package, no package needs to be
modified for every X window manager again, and it provides a unified
interface for both text- and X-oriented programs.
</abstract>
<copyright>Copyright ©1997 Joost Witteveen, Joey Hess, Christian Schwarz.
<p>
This manual is free software; you may redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
<p>
This is distributed in the hope that it will be useful, but
<em>without any warranty</em>; without even the implied warranty of
merchantability or fitness for a particular purpose. See the GNU
General Public License for more details.
<p>
A copy of the GNU General Public License is available as
<tt>/usr/doc/copyright/GPL</tt> in the Debian GNU/Linux distribution
or on the World Wide Web at
<tt>http://www.gnu.org/copyleft/gpl.html</tt>. You can also obtain it
by writing to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
<p>
<toc sect>
<chapt>Introduction
<p>
Before the advent of <tt/update-menus/, when the sysadmin
installed a package onto a debian system, they would need
to edit various window manager config files to make the
new program show up on, for example, <tt/fvwm/'s menus. The
menus could easily become out of sync with what programs
were actually available, with some menu items that didn't
work, and other programs that lacked a menu entry.
update-menus and debian's menu package aim to solve this
problem.
<p>
<tt/update-menus/ automatically generates menus of installed
programs for window managers and other menu programs. It
should be run whenever a menu file or menu-method file
is changed. <tt/update-menus/ will be ran automatically when
debian packages that contain menu files are installed or
removed from the system.
<p>
One problem we ran into with menu-1.x (and before) was that the
number of entries in any submenu vary wildly: on my system there are
only two entries in /Apps/Editors, while I'm sure that other people
have more like 20 entries there. Many people complaind about the
fullness of certain submenus, citing scientific studies or personal
experience to explain why overfull or underfull submenus are a bad
thing. To overcome this, menu-2.0 now can optimize the tree itself,
possibly subdividing for example the /Apps/Editors tree in, say
Editors/Beginner, Editors/Experienced, or whatever, if there are many
entries in that submenu, or maybe even totally removing /Apps/Editors
on systems where there are few editors installed. To be able to do
this, menu follows the information supplied to it in the `hints'
variables (see paragraph below, or the hints chapter).
<p>
Each package that needs to add an entry to the menu tree,
includes a menu file <tt>/usr/lib/menu/package-name</tt>. In
this file, it will have one line per menu entry, like this (copied
from <tt>/usr/lib/menu/xbase</tt>):
<example>
?package(xbase):command="/usr/bin/X11/xedit" needs="X11" \
section="Apps/Editors" title="Xedit" \
hints="Beginner,Small"
</example>
This describes the type of interface Xedit needs (X11),
the menu section the menu entry should be in,
the menu text, and the command that should be executued.
Also, it tells menu that, if /Apps/Editors is overfull,
it could put Xedit in a Apps/Editors/Beginner or Apps/Editors/Small
subsection.
<p>
Whenever <tt/root/ runs <prgn/update-menus/, it will check all
menu files in <tt>/etc/menu</tt> and <tt>/usr/lib/menu</tt>,
and run the installation scripts that display managers like <prgn/fvwm2/
should provide in <tt>/etc/menu-methods</tt>.
<p>
The menu package itself provides a set of default menu files,
for people to get the idea, and to speed up things a bit.
(These files should be incorporated into the package.)
<p>
Note, that substantial and incompatible changes took place with the
menu-1.0 release, while substantial features were added by the release
of menu-2.0. This document describes menu-2.0.
Menu-2.0 now doesn't accept the menu-methods written for menu-0.x, but
for most window managers that still have those old menu-methods, I
have put new style menu-methods in /usr/doc/menu/examples. Everything
written for menu-1.0 will work with menu-2.0.
<p>
Most notable changes between menu-0.x and menu-1.x are listed in the file
README.changes in the menu package, the features added by menu-2.0 can
be summerised here: hints, and the menu-2 compat mode. (where lines
are finished by a ';' instead of a newline).
<chapt> Menu from the viewpoint of a user
<p>
<sect> How/when do the window manger startup files get created?
<p>
Basically, you as user don't need to know any of how and when the
startupfiles are created, but you might be interested to know anyway.
<p>
When package that wants to add something to the menu tree gets
installed, it will run <tt/update-menus/ in it's <tt/postinst/ script.
Update-menus then reads in all menu files in <tt>/etc/menu/</tt>
<tt>/usr/lib/menu</tt> and <tt>/usr/lib/menu/default</tt>, and stores
the menu entries of all installed packages in memory. Once that has
been done, it will run the menu-methods in
<tt>/etc/menu-methods/*</tt>, and pipe the information about the menu
entries to the menu-methods on stdout, so that the menu-methods can
read this. Each Window Manager or other program that wants to have
the debian menu tree, will supply a menu-method script in
<tt>/etc/menu-methods/</tt>. This menu-method then knows how to
generate the startup-file for that window manager. To facilitate this
task for the window-manager maintainers, menu provides a
<tt>install-menu</tt> program. This program can generate the
startupfiles for just about every window manager.
<sect> Tuning of the generated window manager startup files
<p>
In principle this is a very window-manager specific bussines.
But for all window managers (and others) applies:
<p>
The file to attac is the menu-method in
<tt>/etc/menu-methods/$wm</tt>, with <tt/$wm/ the
name of your window manager. However, if this menu-method
<tt/!include/-s the <tt/menu.h/ file (as it should), you can also edit
that file, to make your changes work for every installed window
manager.
<p>
If the menu-method file of your window manager does <tt/!include/ the
<tt/menu.h/ file, and makes proper use of the definitions in there,
then you can look at the comments in that <tt/menu.h/ file to see how
you can make minor adjustments to the look of your menus in your
window manager.
<p>
To generally change the menu tree, see the next section:
<sect> Optimization of menu tree: hints
<p>
If in the <tt>/etc/menu-methods/*</tt> script appears the definition
<tt/hint_optimize=true/ (actually, that definition should appear in
the <tt/!include/-ed <tt/menu.h/ file), then install-menu will try to
alter the menu tree, to make every submenu have about the optimum
number of menu entries (as specified by <tt/hints_nentry=.../). It
will do that by removing underfull submenus (unly if the `parent' of
that submenu isn't itself already overfull), and by possibly creating
new submenus, using hints. Note, however, that the optimization of the
tree takes in principle exponential time, so I've had to speedup the
process, at the expence of occasionally not finding the best tree. So,
the tree you are presented with may not be optimal. For tuning
variables, see the hint_* variables in the last chapter.
<chapt>What packages with applications should do
<p>
<sect>Registering your applications
<p>
A package should provide a menu file
<tt>/usr/lib/menu/<package-name></tt> that contains
information about each program it likes to make available in the
menus.
<p>
Here is an example to describe the syntax of such a file:
<example>
?package(gnuplot):\ specifies what packages need to be installed
needs=text\ what kind of terminal this command expects
needs=X11: if this program runs only on X11
needs=text: if it only runs on text terminals
(the window manager should spawn
an xterm or rxvt in this case)
needs=vc: runs only at linux console
needs=wm: this starts another window manager
section=Apps/Math\ in what section this menu entry should be
title="Gnuplot"\ the title of the menu entry
(please make it short!)
command="/usr/bin/gnuplot" the command to run.
</example>
<p>
A program like gnuplot which can be run on X11 as well as on a text
terminal should <em/not/ have an extra entry with <tt/needs=X11/
because it will then be next to impossible to configure the window
managers to spawn <prgn/rxvt/ instead of the default <prgn/xterm/.
<p>
On the other hand, if a program (like <prgn/emacs/) can be run as real X
application as well as in a terminal, two entries should be listed,
otherwise the program will always be run in an <prgn/xterm/ (or <prgn/rxvt/).
<p>
In the menu entry files, you can use "#" as comment (like in shell scripts).
<p>
You should add a line like this to your <tt/postinst/ script
<example>
if test -x /usr/bin/update-menus; then update-menus; fi
</example>
and the <tt/postrm/ script should get the line
<example>
if test -x /usr/bin/update-menus; then update-menus; fi
</example>
(that is, the same line in postinst and in postrm).
<p>
<sect>Preferred menu structure
<p>
Here is the <em/authoritative list of Debian's menu structure/. If you
have a package which does not fit in here or if you have any
suggestions how to improve this structure, please send
an email to the maintainer of the <tt/menu/ package, Joost Witteveen
<email/joostje@debian.org/. If you have more general remarks about
restructuring the menu tree (or adding an entry that may require
discussion), the best thing to do is to go to <tt/debian-policy/, and
start a discussion there. I (Joost) will without hesitation change
the structure of the menu-tree if a decision was reached on
debian-policy, but I'm very reluctant to changes without prior
discussion.
<p>
Please do <em/not/ put your packages into any other sections without
asking for permission first!
<p>
<example>
Apps - normal apps
Editors - editors (run it in xterm, if nothing else)
Emulators - dosemu, etc.
Graphics - xpaint, xfig, xtiff, etc.
Hamradio - Anything relating to ham radio.
Math - gnuplot, octave, oleo, etc.
Net - mail, news, web, irc, etc.
Programming - debuggers, etc.
Tools - other tools: xclock, xmag, xman, etc.
Technical - technical stuff.
Text - text oriented tools other than editors.
Shells - bash, ksh, zsh, etc.
Sound - TkMidity, etc.
Viewers - Picture viewers, gs, etc.
System - system administration and monitoring tools
Games - games and recreations
Adventure - walk around virtual space, zork, MOO's, etc
Arcade - (any game where reflexes count)
Board - Like: Gnuchess, pente, gnugo
Card - solitaire, etc
Puzzles - Stuff from xpuzzles, ...
Sports - Games derived from "real world" sports
Strategy - Build your world (Games like lincity, freeciv)
Tetris-like - games involving falling blocks
Toys - (oneko, xeyes, etc.)
Screen -
Lock - xlock, etc.
Save -
Root-window - things that fill the root window
WindowManagers - (change between fvwm, afterstep, etc)
Modules - fvwm modules, etc.
XShells - shells (like xterm, rxvt, ...)
</example>
<p>
<sect>Hints
<p>
Hints have been added starting from this version of menu. There needs
to be some discussion about them first, but if you want to try them
out, simply add a hints="Myhint,Herhint,Hishint" definition to the
menu entry file. For example:
<p>
<example>
?package(emacs20):\
needs="x11"\
hints="Big,Expert,Featureful" \
section="Apps/Editors"\
title="Emacs 20"\
command="/usr/bin/emacs20"\
icon=/usr/share/emacs/20.3/etc/emacs.xbm
</example>
The above hints will case <tt/menu/ to consider grouping <tt/emacs/
together with other editors that are marked similar. For example, if
<tt/vi/ on your system has a hints="Small,Expert" definition, and
there are too many entries in the /Apps/Editors menuentry, then menu
will consider creating a /Apps/Editors/Expert submenu, and put both
<tt/vi/ and <tt/emacs/ in it. (of cource, only if you have
<tt/hint_optimize=true/ in your /etc/menu-methods/menu.h file).
<sect>Icons
<p>
Please, make sure the icons you specify are always available on the
system. So, if you want to have an icon with your menu entry, the
preferred method is to supply the icon with that package. Also, to
prevent the distribution of icons files to turn too much into a mess,
please put all icon files in the directory
<tt>/usr/X11R6/include/X11/{bitmaps,pixmaps}</>.
<p>
Debian package maintainers should ensure that any icons they include
for use in the debian menus conform to the following points:
<enumlist>
<item>The icons should be in xpm format.
<item>The icons may not be larger than 32x32 pixels, although smaller
sizes are ok.
<item>The icons should use only the 24 colors present in cmap.xpm,
which comes with the <tt/menu/ package.
<item>The background area of the icon should be transparent, if
possible.
</enumlist>
If you have Imagemagick installed, you can make your icons meet requirements
1, 2, and 3 with the following command, but you will need to edit the icon
afterwards to clean it up and make the background transparent:
<example>
$ mogrify -format xpm -geometry 32x32 -map cmap.xpm <filenames>
</example>
If you, as a system administrator, don't like the icons in the menus, simply
remove the <tt/$%{icon}/ from the files in
<tt>/etc/menu-methods/$wm</>, and run <prgn/update-menus/.
<p>
It's also possible to specify an icon for a sub-menu. However, if each
package would supply its own icons for the sub menus we can never be
sure that the icon files are available. Thus, only the <tt/menu/
package is allowed to specify icons for sub menus. The syntax for this
is:
<example>
X11 Apps menu/apps /usr/X11R6/include/X11/pixmap/icon.xpm "Editors"
</example>
<sect>Fvwm's task and title bars
<p>
The problem with the stuff in the task bar is that all items are
displayed all of the time. So, if 1500 debian packages all were to
register a button, the buttons would quickly fill the screen, making
the exercise useless. The few applications that are considered
important enough to be listed in the task bar usually vary widely on
each system, making it impossible to select a ``happy few'' apps that
are allowed there on every debian system. If you (as a local system
administrator) want your <prgn/fvwm2/ to have a few buttons, you can
install files for those packages in <tt>/menu/$package</>, containing
a menu entry like this:
<example>
?Package(xmball):needs=button\
section=Games/Puzzles\
icon=path-to-pixmap.xpm\
title="Xmball"\
command=/usr/games/xmball
</example>
Then, do the following:
<example>
cd /etc/menu-methods/
cp fvwm2 fvwm2button
vi fvwm2button
</example>
and remove all the "supported" entries, adding the one below. For the rest,
leave everything the same except those listed below.
<example>
supported
button="+ Style \"" $title "\" TitleIcon" $icon " Exec " $command "\n"
endsupported
startmenu: "AddToTitlebar \n"
endmenu: "\n"
submenutitle:""
mainmenu:
genmenu: "buttondefs.hook"
</example>
(Of course regular users (not system administrators) can also specify
`buttonfiles' in their ~/.menu/ directory).
<chapt>What packages with menu managers should do
<p>
Each package containing a <em/menu manager/ (i.e. a program that can
display a menu) should provide a script or program in
<tt>/etc/menu-methods/</> that can read the menu files. This script
will be executed by <prgn/update-menus/, which will feed the menu
entries to be installed to your script via standard input (stdin).
<p>
The scripts in <tt>/etc/menu-methods/</> should be configuration
files, so the user can tune the behaviour of the script.
<p>
Good examples for these scripts for nearly all debian window managers
are included in the <tt/menu/ package in
<tt>/usr/doc/menu/examples</>. Note that while working on your script,
you can use the tricks described in "The internals of the Menu
package", section "The update-menus program", to run just your script,
instead of having update-menus run all scripts (can save quite a lot
of time).
<p>
Run <prgn/update-menus/ (if it exists) in your <tt/postinst/ script,
and remove the execute bit from the <tt>/etc/menu-methods/</> script
in the <tt/postrm/ when called with option ``remove.'' The
wm-menu-config script is provided to make all this easier:
<p>
Here is an example of such a <tt/postrm/ script using <prgn/sh/:
<example>
#!/bin/sh
set -e
wm=twm #or pdmenu, fvwm, ... whatever manager you're installing
case "$1" in
remove)
if test -x /usr/sbin/wm-menu-config; then wm-menu-config $wm off;fi
;;
purge)
#remove the files that install-menu creates:
(cd /etc/X11/twm/; rm system.twmrc menus.dat menudefs.hook)
;;
upgrade);;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 0
;;
esac
</example>
And here is a good example for a <tt/postinst/ script:
<example>
#!/bin/sh
set -e
wm=pdmenu #or fvwm, ... whatever manager you're installing
if test -x /usr/sbin/wm-menu-config; then wm-menu-config $wm on;fi
</example>
Please, do not make your package <em/depend/ on the menu package! The
preferred way of telling dpkg that your wm can cooperate with menu is:
<example>
Suggests: menu (>1.5)
</example>
Please only consider using "depends" if you feel providing reasonable
defaults for systems without menu will make life very difficult for you.
<p>
<chapt>How a user can override the menus
<p>
<sect>Configuring the menus
<p>
A user can specify his/her own menu entries in the <tt>~/.menu</> directory.
The files can have an arbitrary file name as long as the new syntax
for the menu entries is used. They should start with either
<example>
?package(installed-package):
</example>
or
<example>
?package(local.mystuff):
</example>
if it's something that isn't ``debian-officially'' installed. (Any
``package'' that starts with ``<tt/local./'' is considered installed.)
<p>
If a user wants to have his/her own menu methods, he/she should create
a <tt>~/.menu-methods</> directory and put all scripts he/she wants to
be run in it. (If <tt>~/.menu-methods</> exists,
<tt>/etc/menu-methods</> will not be searched when a user runs
<prgn/update-menus/).
<p>
A system administrator should place system-wide menu entries in
<tt>/etc/menu</> (not in <tt>/usr/lib/menu/package</>, since these
files will probably be overwritten by a package upgrade).
<p>
<sect>Specifying a ``no-menu entry''
<p>
If a user wants to remove an entry from the system menu (in
<tt>/etc/menu</>), then this will do the trick:
<example>
echo -n > ~/.menu/package
</example>
The zero-size file will tell <prgn/update-menus/ that the
corresponding package should not have any menu entries listed.
<p>
<sect> Include: (one) other feature
<p>
More out of curiosity than anything else, I recently read the KDE
mailing list. In it I saw some discussion about how good the Debian
menu system is (whow, thanks, guys!), but one person found a missing
feature: s/he said you couldn't include other files in the user
menu files. Well, actually, it was already possible, but not very well
documented. To include the contents of file /usr/lib/menu/somefile,
add this to your menu file:
<example>
!include /usr/lib/menu/somefile
</example>
Apart form that, it is of course possible to make the menu entry file
executable (<tt>chmod a+x ~/.menu/package</>), and do something like
<example>
#!/bin/sh
cat /usr/lib/menu/somefile
sed -e "/unwanted_entry/s/?package(/?package(notinstalled./" \
/usr/lib/menu/someotherfile
</example>
to get the same effect, with the added flexibility of being able to
filter out unwanted lines.
<chapt>The internals of the menu package
<p>
<sect>The update-menus program
<p>
On startup, update-menus checks the file
<tt>/var/run/update-menus.pid</> and the pid in it. If there's an
<prgn/update-menus/ process with that pid it kills it.
If <tt>/var/lib/dpkg/lock</> exists, it forks to background and
returns control to dpkg. The background process checks the
<tt>/var/lib/dpkg/lock</> file approx. every second until the file's
gone.
<p>
After that, <prgn/update-menus/ reads the menu-entry-files in
the following directories:<tt> /etc/menu /usr/lib/menu /usr/lib/menu/default
</>
(if a user runs <prgn/update-menus/, it will add ~/.menu to the
front of that list). For every menu entry line in each file it checks
if the corresponding package is installed (works on file bases for old
syntax menu entry files). The menu entries of all "installed" packages
are added together in one big buffer that is kept in memory (exception:
executable menu entry files are executed, and stdout is placed in
the buffer).
<p>
Once it's read all menu entry files, <prgn/update-menus/ starts all
executable scripts in /etc/menu-methods/, hands the scripts the
previously created buffer via stdin. (If <prgn/update-menus/ is ran by
a user, it will first try to run the scripts in ~/.menu-methods, and
only if that directory doesn't exist, it will run the scripts in
/etc/menu-methods).
<p>
Note that as an aid to debugging, one can create a simple script like
<example>
#!/bin/sh
cat > /tmp/menu-stdout
</example>
and then view the file /tmp/menu-stdout to see exactly what
<tt/update-menus/ handed the menu-methods on their stdin.
<p>
This may also be usefull for people
writing /etc/menu-method/* scripts: Running <prgn/update-menus/ every
time you changed something in the script may be quite
time-consuming. So, it's much easier to install the above script in
<tt>/etc/menu-methods/</>, run <prgn/update-menus/ once, and then run
<example>
/etc/menu-methods/mymethod < /tmp/menu-stdin
</example>
(and, if that also takes too long, just try editing /tmp/menu-stdin,
and removing 90% or so of all entries)
<sect>The install-menu program
<p>
The files <tt>/etc/menu-methods/$wm</> are executable config
files that start with the line
<example>
#!/usr/sbin/install-menu
</example>
and thus start that program, handing it the configuration file for the
specific window manager in the first command line argument. This
configuration consists of:
<enumlist>
<item>the compatibility mode ("menu-1" or "menu-2").
<item>where the various files should be stored/read.
<item>what "needs" are supported, and what wrapper files should
be used for each "type".
</enumlist>
See <tt>/usr/doc/menu/examples/</> of the menu package for more
comments.
<p>
Options to <prgn/install-menu/:
<example>
-v be verbose
-d Produce loads of debugging output
</example>
<p>
Some window managers don't support an `include' like statement in
their <tt/system.*rc/ files (like <prgn/m4/ or <prgn/cpp/
preprocessing), they cannot read the <tt/menudefs.hook/ file generated
by install-menu from their
<tt/system.*rc/ config file. To still be able to use them,
<prgn/install-menu/ will copy the file
<tt>$path/$examplercfile</tt> to <tt>$path/$rcfile</tt> (with
<tt/$examplercfile/ and <tt/$rcfile/ defined in the
<prgn/install-menu/ config file, and <tt/$path/ eighter the
<tt/$rootprefix/ or <tt>${HOME}/userprefix</tt>, depending on whether root
or user executed the file.), and replace all occurrences of
``install-menu-defs'' with the <tt/$genmenu/ file it just
generated.
<p>
As an example, consider the following:
<tt>examplercfile=system.foo-wm-example</tt>,
<tt>rcfile=system.foo-wm</tt>, <tt>genmenu=menudefs.hook</tt> and
<tt>rootprefix=/etc/X11/foo-wm</tt>. Now, if <prgn/install-menu/ gets run, it
will first generate the file
<tt>/etc/X11/foo-wm/menudefs.hook</tt>. Next, it will line-by-line
read the file <tt>/etc/X11/foo-wm/system.foo-wm-example</tt> and copy
it's contents to <tt>/etc/X11/foo-wm/system.foo-wm</tt>, replacing
every occurence of the string <tt>install-menu-defs</tt> by the
contents
of the file <tt>/etc/X11/foo-wm/menudefs.hook</tt>.
<p>
To activate the file copying in this way, simply define the
<tt/$examplercfile/ and <tt/$rcfile/ variables in the
<prgn/install-menu/ configuration file
(for example, see <tt>/etc/menu-methods/fvwm</tt>), and make sure there is a
<tt>$path/$examplercfile</> (<tt>$path</> being either
<tt/$rootprefix/, or <tt/$userprefix/.)
<p>
If you are wringing a menu method, you can use the following to
debug it somewhat easier:
<enumlist>
<item>use the "cat" menu-method in <tt>/usr/doc/menu/examples/cat</>
to create a list of menu entries in <tt>/tmp/menu-stdin</> (put it in
<tt>~/.menu-methods</>, and run <prgn/update-menus/), and then
<item>you can run just your menu-method with (if it's called wm):
<example>
./wm -v < /tmp/menu-stdin
</example>
(Use <tt/-v/ for verbose, <tt/-d/ for debugging, and you'll get loads
of output!)
</enumlist>
<p>
<sect>The install-menu config script definitions
<p>
The menu-methods in <tt>/etc/menu-methods/*</> are basically made up of
a lot of ``tag=string'' definitions, explaining <prgn/install-menu/
how to generate a <tt/system.$wmrc/ script. This way you can tune
the look of generated <tt/system.$wmrc/ to your needs.
<p>
In the following, something like
<example>
treewalk="c(m)"
</example>
means that the treewalk variable by default has the value "c(m)".
<p>
For examples of what these scripts can look like, see
<tt>/usr/doc/menu/examples/*</>.
<p>
<taglist>
<tag><tt/compat="menu-1"/
<item>
Should always be "menu-1". Please, make this the first non-comment
line in the script.
<tag><tt/supported/
<tag><tt/endsupported/
<item>
Between the <tt/supported/ and <tt/endsupported/ keywords you define
what "needs" are supported by this window manager. So, the following
is an example for a wm that supports both needs=x11 and needs=text:
<example>
supported
x11=" ShowEntry(\"" $title "\", \"" $command "\")"
text=" ShowEntry(\"" $title "\", \"" $command
"xterm -T " $title " -e " $command "\")"
endsupported
</example>
For the variable substitution (and functions, not shown above), see
the next paragraph. In the above example, you'll notice that for the
menu entries that "need=text", an xterm is spawned for the command to
run in. Also, as x11 is higher up in the supported list above than text, a
package that supplies both a "needs=x11" and a "needs=text" entry will
have the needs=x11 entry installed, in favour of the needs=text entry.
You can continue lines on the next line with a \, but do make sure you
don't add any spaces after the \.
<tag><tt/startmenu=""/
<tag><tt/endmenu=""/
<tag><tt/submenutitle=""/
<item>
These define what to print for the beginning/end of a menu, and
how to the print a menu entry that pops up another menu entry.
They are substituted the same way as the "supported" stuff is.
(see next paragraph).
<tag><tt/treewalk="c(m)"/
<item>
This string defines in what order to dump the <tt/$startmenu/, <tt/$endmenu/,
and <tt/$submenutitle/ (and its children). Each char in the string
refers to:
<example>
c : dump children of menu.
m : dump this menu's $submenutitles
( : dump $startmenu
) : dump $endmenu
M : dump all $submenutitles of this menu and this menu's children.
</example>
The default is "c(m)". For olvwm, one needs: "(M)"
<tag><tt/genmenu=""/
<item>
The menu file to generate (usually something like <tt>system."$wm"rc</>).
The file itself may depend on the level or title that is currently
being worked on, like
<example>
genmenu="/subdir/" replacewith($section," ","_") "/rc.menu"
</example>
(Substitution works just like in the supported stuff, see above).
Note that the files made this way are truncated upon
opening, so if you have a genmenu like the example above, then
your <tt/endmenu=/ will override the startmenu stuff (but you probably
only need one of the two anyway).
<tag><tt>rootsection="/Debian"</>
<item>
the prefix, every <tt/$section/ variable gets.
<tag><tt/prerun=""/
<tag><tt/postrun=""/
<item>
The commands to run before resp. after the actual generation of the
<tt/menudefs.hook/ (genmenu) file. Commands will be executed by <prgn/sh/.
Example:
<example>
prerun="rm -rf " prefix() "/*"
postrun="killall -USR1 fvwm2"
</example>
(Substitution works just like the supported stuff, see below).
<tag><tt/preruntest=""/
<item>
Just like prerun, but if the return value of the command is non-zero,
menu will quit.
<tag><tt/onlyrunasroot=false/
<tag><tt/onlyrunasuser=false/
<item>
If onlyrunasroot is set to true, menu will quit silently when run as
user. Simmilarly for onlyrunasuser.
<tag><tt>preoutput="#Automatically generated file. Do not edit (see /usr/doc/menu/html)\n\n"</tt>
<tag><tt>postoutput=""</tt>
<item>
Text to put at the beginning resp. end of the generated file ($genmenu).
<tag><tt/command=""/
<item>
A command to run instead of <prgn/install-menus/. This command used
to be needed to get around limitiations due to compatibilty stuff. But
that compatibility with pre menu-1 stuff has been dropped, and isn't
needed any more.
<p>
Example:
<example>
command="cat > /tmp/menu-stdin"
</example>
<tag><tt/hotkeyexclude=""/
<item>
Keys not to use for hotkey generation. You can use the same
variables and functions here as in for example the startmenu
sections.
<p>
Example:
<example>
hotkeyexclude="q" $section
</example>
<tag><tt/hotkeycase="insensitive"/
<item>
can be either "insensitive" or "sensitive". Determines
whether the hotkeys can be of mixed case (<tt/fvwm2/ reads
the hotkeys case-insensitive, <tt/pdmenu/ case-sensitive).
In case of the titles "Xa" and "xb", hotkey case-insensitive will
generate "X" and "b", whereas case-sensitive would generate "X" and
"x".
<p>
<tag><tt/sort=$title/
<item>
Entries within one menu will be alphabetically sorted by whatever
sort returns. So, if you do
<tt/sort=ifelse($command, "1", "0"):$title/, then all submenus will
appear above the commands in a submenu. (A submenu always has
<tt/$command=""/)
<tag><tt/rcfile=""/
<item>
If the window manager doesn't support an "include filename" or
"read(filename)" statement in it's config file, you can rename
the wm's config file to <tt>system."$wm"rc-menu</>, and insert
a "install-menu-defs" line (without the quotes, or whitespace around
it, and "install-menu-defs" must be the only thing on the line)
in the <tt>system."$wm"rc-menu</> file. This will then get replaced
by the <tt/$genmenu/ file that was just created (see
also <tt/$examplercfile/).
<p>
<tag><tt/examplercfile=""/
<item>
if needed (see <tt/rcfile/), this is the <tt/system.rc"$wm"-menu/
file. In that case, make <tt/rcfile=system.rc"$wm"/.
<p>
<tag><tt/rootprefix=""/
<item>
The prefix to use when running as root (applies to $genmenu, $rcfile,
$examplercfile and other old cache files)
<tag><tt/userprefix=""/
<item>
see <tt/rootprefix/, but when running as user.
<tag><tt/repeat_lang=""/
<item>
If set to "LOCALE", then menu will automatically translate all title's
to the languages specified by the current LC_LOCALE setting. (LC_ALL,
...). It is intended to expand this to <tt/repeat_lang="en:es:eo:nl"/,
which would repeatedly run install-menus for the various specified
languages. But the latter hasn't yet been implemented.
<tag><tt/hint_optimize=false/
<item>
If set to true, menu will try to generate an `optimal' tree, using
the variables below. If set to false, menu will keep the sections as
they are specified in the menu entry files (and ignore any hint stuff).
<tag><tt/hint_nentry=6/
<item>
Optimal number of entries in a submenu. It's a float, so you can set
it to 5.5 if you cannot decide between 5 and 6. Also, values less
than 3 probably don't work very well at the moment.
<tag><tt/hint_topnentry=5/
<item>
Same as hint_nentry, but for the top level menu. Often here are other
entries, added by the Window Manager itself (like Exit, Xterm,
whatever) that menu doesn't know about, so that you may want to
instruct menu to put less entries in the top level menu.
<tag><tt/hint_mixedpenalty=15.0/
<item>
Penalty for `mixed' menus. Mixed menus are those with both submenus
and direct commands in them.
<tag><tt/hint_minhintfreq=0.1/
<item>
Minimal relative frequency for the hints before they are considered.
Internal variable to speed up the tree generation. If you find menu
slow, increase this value (to, say 0.2 or 0.3).
<tag><tt/hint_mlpenalty=2000/
<item>
`max local penalty',
while evaluating the possible trees, menu gives `penalties' for
submenus that don't contain the desired number of submenus. The
penalty is sqrt(n_entry_opt-n_entry), and eventually will be
calculated as a sum of all nodes. But to speed things up, menu will
discard possibilities in which any node has a `local' penalty of more
than hint_mlpenalty. Increase this value if you think menu is
overlooking your favorate tree (also decrease minhintfreq), decrease
this value if you think menu is waisting too much time.
Because of hint_max_ntry, the influence of this variable is nearly
zero nowadays.
<tag><tt/hint_max_ntry=4/
<item>
menu will recursively, for each node, try the hint_max_ntry best local
menu-divisions.
<tag><tt/hints_max_iter_hint=5/
<item>
The search for what hints to use in one menu is rather expensive. But
due to the way things are sorted, menu seems to always find the `best'
match in the first 2% of iterations. Thus, a way to speedup things is
simply to cutt of menu searching after `some' iterations are
done. This value controls this, and limits the number of iterations to
5+hint_max_iter_hint*number_of_possible_hints. Set this value to
negative to disable this.
<tag><tt/hint_debug=false/
<item>
Set to true if you want to see loads and loads of debug output.
</taglist>
<sect> Hints, tree optimization
<p>
The hints actually work in a rather strange way: when
<tt/hint_optimize=true/ then all <tt/$section/ elements are added to
the specified <tt/$hints/ variable, and the order (/Apps/Editors or
/Editors/Apps) of the resulting hints is completely ignored. Then, the
hints for each menu entry are handed to the optimization routine, that
will calculate a reasonable tree for those hints. That tree must
comply with the following:
<p>
When a user looks for a program "Program" with, say, hints
"Good,Bulky,Heaven", then, while walking through the tree, it should at
every node vizited
be clear for the user what submenu to select (or the menu should have
"Program" directly in it). So, the toplevel menu may
look like
<example>
Good
Hell
Microsoft
</example>
because then a searcher for a menu entry with hints "Good,Bulky,Heaven"
will know to select the submenu "Good". The toplevel menu may not look
like
<example>
Good
Hell
Heaven
</example>
as now it isn't clear whether to vizit the Good or the Heaven submenu.
<p>
That rule allows usually for many different trees, and the task of the
optimization procedure is to select, in a finite amount of time, the
tree that best matches the user's desire obout the optimimum number of
menu entries.
<sect>Variables and functions in the install-menu scripts
<p>
The supported "needs" definitions and "startmenu=", "endmenu="
and "submenutitle=" are interpreted as follows:
<example>
String constants:
Anything inside double quotes ("") is interpreted as a string, and
is written verbatim to the output file.
Stuff like \n, \t, ... will be substituted for their C expansions
(But not \0xx, currently).
Variables:
Anything matching $[a-z,A-Z,_]* is interpreted as a variable, and
the corresponding definition from the menu entry is substituted.
Special variables:
The following variables are treated in a special way by install-menus,
either because they are used for other purposes too, or because they
are modified by install-menus (the ones marked with a "!" are modified
by install-menus).
needs: used to determine whether the window manager supports this
menu entry.
command: If this is undefined, this menu entry is taken as defining
a sub-menu. (this way you can specify icons of sub-menus).
title!: Used for sorting (see section).
For sub-menu entries (those with empty command), this
is initialised to the last part of the section.
Please, keep the title short (two words at maximum).
The title is for people who already know what programme
they want to start. See "longtitle" and "description" below
for longer descriptions.
sort: used for sorting (see section). To make sure an entry is
at the beginning, use something with a low ASCII number,
like "$". For sorting at the end, use "|"
section!:Used to determine the section of the menu entry.
The menu entries that have a empty $command, ie those that
define a submenu, have $title added to the end of $section
The menu entries that have a non-empty $command have their
$section modified to $section/$title, or $section/$sort:$title
if $sort is defined. The menu entries within one submenu
are sorted according to $section.
hotkey!: Modified to reflect what install-menus thinks is the
most suitable hotkey for this menu entry. The hotkey=
in the menu entry file is taken as a suggestion, that could
be overwritten if there is another entry with the same hotkey=.
To suggest two possible hotkeys for an entry use
hotkey="ab", with "a" being the most preferred hotkey.
Preferred variables:
The following aren't special for install-menus, but it's nice
(read: essential) to use the same variables for the same things.
So, I'll suggest some here. If you want to invent new ones, please
do so and mail them to me so that I can include them here.
icon: The location of the iconfile for this menu entry.
If you don't have an iconfile, just leave out the icon=
in the menu entry.
longtitle: For people that like descriptive titles (about one line)
It is probably best to include this in your menu entries,
while the window-managers don't (by default) put it in the
menus. That way, people who want descriptive titles can
turn them on, but others don't need to use them.
description:An even longer description (about 5 lines).
For example, a description of the documentation in
the dwww generated html pages.
Suggested variables:
The following variables probably shouldn't appear often (or at
all) in the menu files supplied with packages. They are mostly
intended for use by local system managers. Nevertheless, it is
advised that all debian systems use the following variable names:
visable: Some apps add entries to utmp the utmp file, so that
"who" and friends know they are running (this is
especially true for xterms etc). If $visable set
(to anything other than "" or "none"), xterms etc will
not write logging info to utmp. (may not work for
your window manager).
geometry: For X apps, this will be the size of the (main) window
that will be created (units in either chars or pixels,
depending on type of main window (xterm or graphic)).
If you as package maintainer want to use this, you should
probably think about setting this variable somewhere
in an Xresources file.
Functions:
Anything matching [a-z,A-Z,_] is taken as a function (and an error
is generated if the function doesn't exist). The arguments of the
functions can be other functions, string constants or variables.
prefix()
returns the current prefix dir: either $rootprefix, or
$HOME/$userprefix, depending on who runs install-menu
ifroot($rootarg, $userarg)
if(getuid()==0) print $rootarg, else print $userarg
print($arg)
Same as just $arg; if $arg is empty, generate an error.
nstring($n, $string)
write $string $n times. So, nstring(3,"Aa") writes "AaAaAa".
(Useful in combination with level()).
esc($arg1,$arg2)
Print $arg1, but escape all occurrences of characters in $arg2
with a \. (thus, if arg1="hello", arg2="lo", print "he\l\l\o").
escwith($arg1, $arg2, $arg3)
Same as esc, but use $arg3 as escape sequence.
escfirst($arg1, $arg2, $arg3)
Same as escwith, but only escapes thirst occurrence of $arg2.
cppesc($arg1)
Escape anything that isn't a letter, number or _ with
$<hex-ascii-code>. So, for example, a '-' is replaced by '$2D'.
This way, $arg1 can be used as a #define in cpp.
tolower($arg)
toupper($arg)
Returns the argument set in lowercases resp uppercases.
replacewith($s, $replace, $with)
Search s for occurrences of characters from string replace, and
replace them by the corresponding character in $with.
Example:
replacewith_string("hello $world, %dir", "$% ", "123")
returns: "hello31world,32dir"
ifempty($arg1, $arg2)
If $arg1 is empty, print $arg2, otherwise print nothing.
For compatibility, $arg1="none" is interpreted as empty.
ifnempty($arg1, $arg2)
If $arg1 is not empty, print $arg2.
For compatibility, the string "none" is seen as empty.
ifelse($arg1,$arg2,$arg3)
If $arg1 is non-empty, print $arg2, otherwise $arg3.
For compatibility, the string "none" is seen as empty.
ifeq($arg1, $arg2, $arg3)
If ($arg1==$arg2) then print $arg3
ifneq($arg1, $arg2, $arg3)
If ($arg1!=$arg2) then print $arg3
ifeqelse($arg1, $arg2, $arg3, $arg4)
If ($arg1==$arg2) then print $arg3 else print $arg4
cond_surr($arg1, $arg2, $arg3)
If $arg1 is non-empty print $arg2$arg1$arg3, otherwise print nothing.
For compatibilty, $arg1="none" is interpreted as empty.
iffile($arg1, $arg2)
If file $arg1 exists, and can be opened for reading by whoever
started the current process, return $arg2, otherwise return nothing.
ifelsefile($arg1, $arg2, $arg3)
If file $arg1 exists, and can be opened for reading by whoever
started the current process, return $arg2, otherwise return $arg3.
catfile($arg1)
Return the contents of file $arg1.
forall($array, "var", $exec)
For each element of the colum separated array $array, set
$var to that element, and print $exec.
Example:
forall("eo:nl", "lang", " name[" $lang "]=\"" translate(title()) "\"\n")
will print:
name[eo]="Mi estas titolo"
name[nl]="Ik ben een titel"
parent($arg)
for $arg a "directory", return parent directory:
parent("/Debian/Apps/Editors") = "/Debian/Apps".
basename($arg)
return the last part of the parent directory:
basename("/Debian/Apps/Editors") = "Apps".
stripdir($arg)
everything after the last slash, i.e. what basename()
should have returned: stripdir("/Debian/Apps/Editors") = "Editors".
entrycount()
the number of entries in this menu.
entryindex()
returns relative position of this entry. Start with 0,
last entry is entrycount() - 1.
BUG: if sort= anything other than $title, then this
entryindex() will return incorrect values.
firstentry($arg)
return $arg if this is the first entry of this menu
(that is, entryindex() = 0). Else, return nothing.
lastentry()
return $arg if this is the last entry in this menu
(that is, entryindex() = entrycount() -1). Else, return nothing.
level()
return nesting of this menu in the total menu tree.
add($arg1,$arg2)
sub($arg1,$arg2)
mult($arg1,$arg2)
div($arg1,$arg2)
returns the sum, difference, product or quotient of $arg1 and
$arg2. Note that the arguments are strings, that are converted
to integers.
example: mult("24", entryindex())
rcfile() examplercfile() mainmenutitle() rootsection() rootprefix()
userprefix() treewalk() postoutput() preoutput()
These functions all output whatever they were defined to be in
the menu-method file.
translate($lang, $text)
translate $text into $lang.
example:
translate("eo", "Apps")
prints:
Aplikoj
String constants, variables and functions can be concatenated
by placing them after each other with a space in between, like:
"hello" ifelse($comma, $comma, " sorry" $period " comma not defined") " world"
</example>
</book>
|