What goes into an X resource and its name

April 7, 2022

Most people who deal with X resources, me included, generally deal with them at a relatively superficial level. At this level, you can say that X resources are a text based key/value database, with the name (key) of every resource being a composite name that specifies both its program and some program specific name (although there are conventions for the name portion). But if you start to look at the actual names for X resources, things start looking a little more odd.

For example, all of the following are X resource names (and values), from this entry, this entry, and this entry:

XTerm*VT100.scrollbar.width: 24
URxvt*thickness: 24
Xft.dpi: 163
XTerm*VT100.Translations: <... elided ...>

! This isn't from an entry (yet):
XTerm*SimpleMenu*menuLabel.font: <... elided XLFD name ...>
XTerm*SimpleMenu*font: <...>

What is really going on is that the 'name' portion of an X resource is not a name as such but what I will call a selector, by analogy to CSS selectors. Every resource you can set has a fully qualified name, written as 'a.b.c.d' (for some number of components), with most of the components of the name being determined by the inner structure of the specific program involved. Rather than forcing you to find and write out the fully qualified name, the X resource system lets you shorten things. A '.' separates components, a '*' covers any number of components, and the rarely seen '?' means a single, arbitrarily named component.

(For gory details, including precedence rules, see XrmGetResource(3), Resource File Syntax (also), and the RESOURCES section of X(7).)

However, even component names are complicated because in X resources, programs and components have both a general class and a specific (resource) name (which sort of defaults to the class name under many situations). You can use either of them when writing resource names; conventionally, class names are capitalized ('XTerm') and (resource) names are lower case ('xterm'). This is the mechanism used to let you have multiple options for the same program (as I mentioned was theoretically possible); you set a general version using the class of XTerm and then more specific versions under special application names (in xterm and many other programs, you change the application name with a '-name whatever' command line argument). For example:

XTerm*foreground:    black
rootterm*foreground: DarkRed

This is why a lot of program documentation about X resources often tells you both the name and the class of a resource; for example, see the table of X resources for GNU Emacs. The class names for programs are not necessarily predictable from their actual names, although there are conventions. A good X program will tell you in its manual page; a bad one will leave you to ask your window manager for it (or pry it out with xprop).

At this point you may be wondering where the 'within the program' component names come from. The unfortunate answer is that normally they come from the program's widget structure. In X, 'widgets' mostly means X toolkit intrinsics (Xt) and Athena widgets. The idea is that most X programs would be composed of a nested series of widgets (some standard and some written for the program), and the full name of resources would be determined by tracing through that widget structure to the eventual end widget to be configured. If you wanted to configure some setting for a lot of the program's widgets at once, for example if you wanted to set the general background or the font, you used a wildcard to match everything.

(How normal Unix users are supposed to discover a program's widget hierarchy is a question that X never really answered. The closest we got is that good programs more or less documented it in their manual pages, if you read them carefully and understood enough about X resources.)

So, you might ask, how does xterm know that when you write the resource 'XTerm*font: <something>' that you only want to set the main terminal font, not the font used for its popup menus? After all, in theory the wildcard should make it match every font in every widget in xterm. The short answer is 'magic'. You can also ask how you, the person writing X resource settings for xterm, know that this won't set every font in every nook and cranny of xterm. The practical answer is that you don't know; you try setting the resource, and if things blow up you go and revert it.

(Sometimes this doesn't work. See the caution in GNU Emacs' X resources about not writing 'emacs*geometry: ...' to set the initial GNU Emacs size.)

There are a number of problems with this naming model. One of them is that the names people are using to configure portions of your program with resources may well be tied to the current internal structure of your program. If xterm someday wants to move away from using 'SimpleMenu' widgets for its popup menus, everyone who is currently configuring their menu fonts is going to lose (unless xterm goes out of its way to implement some backward compatibility thing). Another of them is that all of this hierarchy and special resource handling only really works well if you use Xt-based widgets for your program. Also, a whole bunch of command line argument handling related to resources only works well if you hand over initial processing of your program's command line arguments to the Xt library. X programs written in other languages often have limited handling of X resources and 'standard' X command line arguments, since you more or less have to work in C or C++ in order to really use Xt.

(See the OPTIONS section of X(7) for all of the things covered by standard Xt argument processing.)

Related to this is the fun issue that resource names can change depending on what options people run your program with, because some options can change the widget structure your program uses, which changes resource names. The xterm manual page has a great example of this in its section on VT100 Widget Resources. It's no wonder that a great many people superstitiously use '*' as the component separator whether or not they need it; it saves them from having to read through the program's manual page to try to figure out the widget structure, and from changes to that structure.

(However, nothing can save you if the program changes the class name or resource name it uses for resources. If 'Monster' gets renamed to 'OwlBrowser', either OwlBrowser perpetually uses the wrong class name for its resources or all of those 'Monster*...' X resources that people have stop working.)

Because of the X resource system's deep entanglement with Xt, programs that don't use Xt often make very minimal use of resources and when they do use resources, they tend to have little or no internal hierarchy (which results in resource names like 'Program.thing'). Such programs are much closer to using X resources as a simple 'program plus option name' key/value store, rather than the vague Xt idea that it would be a hierarchical configuration system.

Sidebar: xterm's SimpleMenu, a lesson in X resource naming

Xterm has popup menus, which are implemented as Athena SimpleMenu widgets, with the class name 'SimpleMenu'. So the following sounds like it should set the font used for the menus:

XTerm*SimpleMenu.font: <...>

Except it doesn't work. A SimpleMenu doesn't directly have a font resource, because it doesn't directly display menu entries. Menu entries are displayed in SmeBSB objects, which do have a font resource. But there are a bunch of SimpleBSB entries in every xterm SimpleMenu popup menu, so you need a wild card match to cover all of them. Hence:

XTerm*SimpleMenu*font: <...>

To understand all of this, I had to read fairly deep into the Athena documentation.

To actually control my xterm popup menu fonts, I did not do this. I did an Internet search for how to do it and copied what the web page said to do without even trying to understand which wildcards were necessary, or even what was going on at all. In practice, X resource names are black boxes that are copied by superstition from working examples.

Written on 07 April 2022.
« Fedora now has a sensible UEFI boot setup (and has for some time)
On the ordering of password and MFA challenges during login »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Apr 7 23:27:02 2022
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.