Customizing the X Front End

Published in The Mathematica Journal, Vol. 4, Issue 2

John Fultz
jfultz@wri.com

One of the great advantages of the X Window System is the ability to customize applications.  By modifying a resource file (afile that contains settings pertinent to an application or utility), you can change hundreds of details about the way any X program runs, from color to fonts to button sizes to default directories. Unfortunately, this feature can also be one of the most confusing. X has thousands of modifications that can be made to its resources, and each application program can add hundreds or thousands more. This column will take a brief look at some of the modifications that can be made to the X front end for Mathematica. I assume in this discussion that you have at least a basic knowledge of UNIX and that you have used the X front end before.

The resource settings (or just resources for short) for the X front end are specified in a resource file called XMathematica. This resource file can be found in the Bin/Display subdirectory of your Mathematica  directory. You should copy this file into your home directory and make all changes to the copy. The XMathematica file in your home directory will automatically supersede the one in the Bin/Display subdirectory. This way, the changes you make to the file will affect only you and not everyone on your system.

Constructing Resources

The complete form of a resource setting looks like the following:

object.subobject[.subobject...].attribute: value

The object refers to the application (the X front end, in this case). The subobjects refer to a hierarchy of objects that have been programmed into the X front end. For example, the first subobject might refer to all dialog boxes, the second might refer to a specific dialog box, the third might refer to all buttons of that specific dialog box, and the fourth might refer to a specific button of that dialog box. Finally, the attribute might be a color of that button, or the font within the button.

Resource settings are rarely referred to in such an exact manner for two reasons. First, the user usually wants to be able to change many resources at once, such as the font in all dialog boxes. Second, many resource names are quite long and unintelligible. Instead of specifying a resource completely, you can use wildcards. A wildcard, represented by an asterisk (*), simply tells X to set the attribute for all subobjects of an appropriate class. The asterisk is used in place of the period in the resource setting. For example, inserting the line:

*Menu*background: gray

into the XMathematica file will set the background color of all Menu objects (the menu bar and any pull-down menus) to gray. A subobject does not need to be specified. The background attribute of all dialog boxes, menu bars, screen borders, and so on, could be set to gray with the line:

*background: gray

Colors

A good way to start experimenting with resources is by modifying colors, since they are among the most visible and easiest attributes to alter. First, you need to know which colors are available on your system. The file /usr/lib/X11/rgb.txt contains a list of color names. You must use a color name in this list. Many of the usual color names (such as brown, black, gray, orange, and red) should already be there, so you may not need to search this list unless you are looking for an unusual color.

In addition to choosing a color, you must choose a color attribute to modify. There are several such attributes: background and foreground allow you to change the background and foreground colors of any specified subobject (as in the example above). Usually, only text is displayed in the foreground color. selectColor is the color of the inside of a toggle button when it is pressed in. topShadowColor and bottomShadowColor are the decorative colors used for shadowing along the top and right sides of a box, and the bottom and left sides of a box, respectively. highlightColor is the color of the highlight box that indicates the active region of a dialog box. The following example would change the color of the highlight box:

*highlightColor:  red

Fonts

It is easy to change a font in a notebook using the Style menu. However, many people would also like to change the fonts in the menu bar or dialog boxes, usually because these fonts show up very small on a high-resolution screen. You can change these fonts by setting a resource and specifying the name of a font file.

It can be difficult to choose the right filename, since there are usually a great many files and their names are long and complex. (Many systems require a separate file for each size and face of the font. A typical filename is -*-helvetica-*-r-*-*-12-*.) The best way to choose a font is with the utility xfontsel, which comes with the standard X Window System distribution (not the X front end). If you do not have this utility, ask your system administrator to install it for you.

To use xfontsel, you simply point to the option you want to change, click, and hold. A menu will come up of all the possible options. Any options you've not yet picked have a wildcard (*) in their place.  It's not necessary to pick values for all options--the wildcards can be left where they are when you've found a font you like.  In fact, you would usually only need to change four of the options: fmly is the font family (such as Courier or Helvetica); wght is the font's weight (bold, light, normal, and so on); slant usually has the options r for roman (no slant), o for oblique, and i for italic; and pxlsz gives the font's size in tenths of a point (so 100 indicates a 10-point font).

Once you've chosen a font, simply copy the filename (the line which has a bunch of -'s and *'s in it) from the xfontsel window into the appropriate setting in the XMathematica file. The resource setting one would normally use to change fonts is fontList. The following example would change the fonts of all dialog boxes and menu selections to 12 point Helvetica Roman.

*fontList: -*-helvetica-medium-r-*-*-*-12-*-*-*-*-*-*

Translations and Actions

In X every event, such as a keystroke or a mouse button press, is given a standard name, which is called its translation.  For example, the translation for pressing button 1 of the mouse is known to X as <Btn1Down>, and the translation for the 'g' key is <Key>g (all translations for keypresses have <Key> in them).

Any action that can be taken also has a name. There is a list in Appendix E of the User's Guide for the X Front End which has the actions listed, and they include most of the menu selections.  It is possible to bind a translation to an action so that whenever you press a button or hit a key, a certain action will result.  A list of default bindings is shown in Appendix E as well. For example, if the X front end detects the translation Shift<Key>Return, which in English is Shift-Return, then it will execute the action evaluate-selection(), which is the Evaluate Selection command.

It is possible to add new bindings so that any key that has not already been defined, such as a function key, can be used (the one exception to this is the F1 key, which is defined as On Context help). First, you must consider which action you wish to bind to which key. For example, try binding the F2 function key to the Evaluate Next Input action. According to Appendix E, the action for Evaluate Next Input is evaluate-next-input(). Now, you must find out the name of the keypad Enter key. To do this, bring up the X Environment Info dialog box from the Help menu of the X front end. In this dialog box, click the button Find Keys and Modifiers. Any key you type into the resulting dialog box will cause that dialog box to display its name. In my case, the F2 function key is called F2.

Now that you have the information you need, you simply add the appropriate information to the XMathematica file. First, find the section in your XMathematica file that reads as follows:

*Notebook.translations: #override \n<Btn1Up>: selection-put() \n<Btn2Down>: selection-get()

Even though it spans multiple lines, this is a single resource.  Each new line adds
a new translation, and the block of lines is read as a single resource because of the \n\ characters which "join" the lines together. There are two translations already defined, for the <Btn1Up> and <Btn2Down> actions. To add your new translation, you first need to add the \n\ to the end of the last line, then add a new line immediately afterward.  So, your final example should read:

*Notebook.translations: #override \n<Btn1Up>: selection-put() \n<Btn2Down>: selection-get() \n<Key>F2: evaluate-next-input()

Note the <Key> before the key name. This simply means that the type of event which is expected is a key, specifically F2. If you wish to refer to the combination of Shift-F2, Control-F2, or Mod1-F2, you would use Shift<Key>F2, Ctrl<Key>F2, and Alt<Key>F2, respectively.

Some Practical Applications

While it can be fun just to play with XMathematica resources and have the X front end come up in purple and orange, some very productive changes can also be made to the resource settings.

One of the first things you should do after installing the X front end is to set up the Print command correctly. When printing to a printer, the X front end actually prints through a pipe to a UNIX shell command. This command is given by a resource called *printCommand and it is already set in the XMathematica file to lpr. (See Appendix E of the User's Guide for the X Front End.) You can change the command, for example, to print to a particular printer called laser1 by changing the *printCommand resource to:

*printCommand: lpr -Plaser1

On some high-resolution screens, it can be hard to see whether or not toggle buttons in the menus and dialog boxes are pressed. To fix this problem, you can add the following line to your XMathematica file:

*selectColor: black

You can highlight a menu to attract attention to it. For example, if you are a system administrator and you want to encourage users to look at the Help menu before they come running to you, you can change the background color with the line:

*Menu*Help*background: red

You can also highlight a particular option of a menu. This might be handy if you are teaching students how to use the X front end. For example, to highlight just the Save option of the File menu, you could use:

*Menu*File*Save*foreground: red

One of the most useful things you can do is change the text for the keyboard shortcuts that are listed beside menu options. The text refers to the Mod1 and Mod2 keys, which are unfamiliar to many users. If the computers at your site use the Alt key for Mod1, for example, you can replace references to Mod1 with Alt. To change the keyboard reference for New, which has a keyboard shortcut of Mod1+N, use the following entry in the XMathematica file:

*Menu*File*New*acceleratorText: Alt+N

There are many creative ways to modify resources--far more than I could list here. After experimenting with the examples here, you will be able to come up with custom revisions to suit yourself or your lab.