Chapter 17. Desktop OpenBSD

Spend summer days with
blowfish at your fingertips:
no passwords stolen!

OpenBSD is best known as a server operating system, but it can be a very effective and powerful desktop system. The X Window System is the standard graphic desktop software for Unix-like operating systems, and OpenBSD includes tools for using it. As this book assumes that you have some Unix experience, I won’t cover all the applications that make X Windows comfortable. You’ll need to experiment to find your preferred mail client, web browser, and text editors—most of which aren’t OpenBSD-specific. Instead, this chapter covers items that are unique to OpenBSD, originated with OpenBSD, or require specific configuration.

OpenBSD includes the Xenocara framework for modifying and building X.Org in a manner tightly integrated with OpenBSD. We’ll discuss making OpenBSD boot into a graphical desktop using the cwm desktop environment, as well as a text console using the tmux terminal multiplexer. But we’ll start by customizing the console.

The wscons(4) hardware-independent console driver lets you configure your boring, black-and-white, nongraphical console in many ways.

Start by viewing the current console settings using wsconsctl(8). Run the following on a text console, not in an X session (changes made in wscons can carry over to an X session, but once you start X, you’re mostly stuck with X’s configuration system).

$ wsconsctl
keyboard.type=pc-xt
keyboard.bell.pitch=400
keyboard.bell.period=100
keyboard.bell.volume=50
…

Each line contains a system variable and a setting, many of which you can change. The keyboard.type variable represents the type of keyboard on the system. Because this is an amd64 system, it uses the pc-xt keyboard common to consumer computers, but you’ll see different keyboard types with different hardware.

You can also change these settings with wsconsctl. For example, in the previous listing, the variable keyboard.bell.volume sets the volume of the computer’s beep. Now, I’m a tcsh user, and I frequently use tab completion (type a character or two, press TAB, and the shell fills in the name of the command or file you’re about to type). Unfortunately, when tab completion hits an ambiguous spot, it stops. That’s not a problem when I’m logged in over SSH, because I can just type a character or two and press TAB again. But when I’m on the local console, each ambiguity is accompanied by a beep (or bell) from the computer. When I’m trying to fix a problem, and the bell rings, shouting “beep WRONG! beep WRONG! beep WRONG!” I have only one thought:

The beep must die.

$ wsconsctl keyboard.bell.volume=0
keyboard.bell.volume=0

Now silence reigns and I can resolve the problem without the computer nagging me. (You could choose to turn up the volume, if you’re a masochist. I won’t judge you—at least not in public.)

Here, we’ll look at a couple other things you can do with wscons.

The terminal multiplexer tmux(1) lets you run multiple virtual terminals inside one OpenBSD terminal window. While standard virtual terminals disappear when you disconnect from the system, tmux virtual terminals continue to run even after you disconnect. tmux is small, fast, easy to use, and written with the same care as the rest of OpenBSD.

Why would you need tmux? One example is for building programs. Just before I leave the office, I use my laptop to make an SSH connection into an OpenBSD server, create a virtual terminal, start building a huge program (such as OpenOffice.org), and shut down my laptop. Normally, the build on the server would terminate when my session is interrupted, but the tmux virtual terminal continues to run even when I log out. The build continues in the disconnected virtual terminal while I drive home, and when I reconnect to it later, I can see how the build has progressed. Virtual terminal sessions even survive accidental disconnections caused by network or client failures.

This section provides an introduction to tmux. For complete details on the features discussed here, as well as dozens of other features, read tmux(1).

To start a virtual terminal session, run tmux. Your terminal window will show the command prompt and a green tmux status bar along the bottom, with information like the following:

[0] 0:ksh*        "caddis.blackhelicop" 11:55  26-Jun-13

This is a virtual terminal session. The left side of the status bar displays the tmux session number in brackets [0] and the list of tmux windows 0:ksh* (beginning with window number 0). The right side shows the first part of your machine name (caddis.blackhelicopters.org), followed by the time and date. You’ll learn how to customize things in Setting tmux Options and Configuring tmux.

The window name defaults to the name of the program running in that tmux(1) window. For example, if you start a command that continues until interrupted, such as iostat -w 5, the session name will change to match the command. Interrupt the command, return to a shell prompt, and the status bar should change its name to match your shell.

The status bar is normally green, but if it turns yellow, tmux is expecting input. When it’s yellow, any typing is interpreted as a tmux command. If you reach this mode accidentally, press ENTER to return to a green status bar and normal operation.

tmux Commands and Window Management

Pressing CTRL-B tells tmux that the next command is for tmux, not for the program running in the virtual terminal. (If pressing CTRL-B interferes with another program you use frequently, you can change this key combination, as you’ll see in Unmapping and Remapping Keys.)

The most commonly used tmux commands are single characters. For example, to create a second terminal window in this tmux session, press CTRL-B-C. Your screen will display only a command prompt and a new status bar.

[0] 0:iostat-  1:ksh*          "caddis.blackhelicopte" 11:58 26-Jun-13

You have two windows: window 0 shows iostat output, and window 1 displays the ksh prompt. The asterisk next to window 1 means that you’re currently looking at it. Run an ongoing command in your new window, such as top, and the window name should automatically change to the name of that command.

Disconnecting, Reconnecting, and Managing Sessions

A collection of tmux windows is called a session. Conveniently, tmux can disconnect from a running session without interrupting its windows. Press CTRL-B-D to disconnect your terminal from the current tmux session. Your terminal should now show what it held before starting tmux. To reconnect to your tmux session, run tmux attach.

You can have multiple tmux sessions simultaneously. The session number appears on the far left of the status bar. (In our sample status bars, the tmux session is 0.)

To start a new tmux session without attaching to your previous session, run tmux without any arguments. For example, I type tmux instead of tmux attach in order to spawn a new tmux session when I want to pick up where I left off. You can change your tmux session within tmux itself, using a tmux command, but I usually just end the session and enter the correct command.

If you can have all these tmux sessions, how can you be sure that you haven’t left old, useless sessions lying around, with abandoned commands running in them? Use tmux list-sessions.

$ tmux list-sessions
0: 4 windows (created Sun Feb 13 12:17:14 2011) [80x23]
2: 1 windows (created Mon Feb 21 21:57:59 2011) [131x36] (attached)

I can see from the last line of this output that I left session 2 running on my other workstation, and am still attached to it.

To connect to session 2, use attach-session and option -t to choose a target session. Here, I attach to tmux session 2:

$ tmux attach-session -t 2

I’m now connected to the same session from two separate SSH sessions—in this case, from two separate client workstations. My typing in one screen is echoed on the other.

To destroy a session, use the kill-session command, specifying the session number with -t. Here, I kill tmux session 2:

$ tmux kill-session -t 2

Any programs running in windows in tmux session 2 will also be killed.

Options change how tmux windows, sessions, and the tmux server itself behave. The most common changes involve the appearance of windows, colors, or items displayed in the status bar. Some options affect the entire tmux session; others affect only a specific window. You can change options on the fly with the tmux command set-option.

Go ahead and open a tmux session to follow along. Press CTRL-B-: to enter command mode. When the colon appears, enter set-option status-fg green, and then press ENTER. Your status bar should now be solid green bar. Congratulations! You’ve set the status bar text color identical to the background color, making it unreadable. Return to command mode, and change the color to black to make it readable again. (If this bugs you, you can kill this tmux session and start a new one to reset all options.)

When making changes, use set-option (or just set) for options that affect the tmux server and the entire session. Use set-window-option (abbreviated setw) for options that affect only a single window.

Most people won’t need many (if any) tmux options, but they can prove useful. For example, say you want the status bar clock to display time in 24-hour format, or you want a visual bell instead of a beep. Options let you control these behaviors, as well as run commands in the status bar. To change basic tmux appearance and behavior, see the options in tmux(1).

Be sure to try any interesting options interactively. Once you have a tmux session running the way you like, enter show-options for an accurate list of the current options. Copy that list because we’ll use it to build a configuration file.

The OpenBSD developers modified the industry-standard X graphic interface provided by X.Org to better fit with OpenBSD. The combination of X.Org and OpenBSD-specific patches is called Xenocara.

In most cases, Xenocara works exactly like X.Org, and X.Org documentation is applicable to OpenBSD. Most of Xenocara is there for security and for the convenience of developers building X, but there are a few additions. In my opinion, OpenBSD’s best enhancement to X.Org is the cwm(1) window manager. Here, we’ll cover configuring and starting X. The next section provides details about using the window manager.

While X provides operating system support for a graphical interface, management of that interface falls to the window manager. OpenBSD has packages for button-heavy, pointy-clicky window managers such as KDE, Gnome, and Xfce. These window managers might provide a comfortable bridge between consumer-friendly operating systems and OpenBSD, but they’re not designed for the more hard-core Unix user.

Xenocara includes three window managers: the classic fvwm(1) and twm(1) window managers that have shipped with X since the last millennium, and the OpenBSD-specific cwm(1). OpenBSD developers wrote cwm specifically as a modern, fast, keyboard-friendly interface.

To start cwm at login, invoke it in $HOME/.xsession:

/usr/X11R6/bin/cwm

When your cwm session ends, xdm returns you to the login screen.

Configuring cwm

Rather than using mouse-driven configuration menus, cwm uses a single configuration file, $HOME/.cwmrc. You can read the complete documentation in cwmrc(5). Here, as I discuss various cwm features, I’ll mention how each can be configured or changed in .cwmrc.

When you are running the graphical desktop, everything on screen is a window. A terminal runs in a window, as do web browsers and games. Managing windows—raising, hiding, resizing, naming, and so on—is the core task of a window manager.

A default cwm session starts with a plain gray screen and a small xconsole(1) window. Create a new terminal window with CTRL-SHIFT-ENTER. The window manager should focus on whatever window your mouse is over. (Press SHIFT-+ to increase the font size of the terminal windows.)

If you press CTRL-SHIFT-ENTER repeatedly, you won’t see additional terminal windows. Oh, the new windows will be created, but on top of one another. Press ALT and the left mouse button to move the currently active window, and you should expose another terminal window beneath that one.

I find the default terminal size too small; I want wider terminals with more rows. To resize the terminal window, press ALT and the center mouse button (or both buttons simultaneously). The mouse will move to the lower-right corner of the window and change to a right angle bracket. The window will continue to resize as long as you hold down the mouse button.

To maximize windows vertically, press CTRL-ALT-=. To maximize windows horizontally, press CTRL-ALT- SHIFT-=. To destroy a window, focus on it and press CTRL-ALT-X. You will not be asked to confirm your decision; cwm will obey and exterminate the window immediately.

To exit cwm and return to the login screen, press CTRL-ALT-Q.

The default cwm desktop is rather bland, but a few adjustments make it easier on the eyes. One of the first things I set is a background color: black. Use xsetroot(1) to set your background color.

$ xsetroot -solid black

You can include this command in .xsession or run it in a terminal. The file /usr/X11R6/share/X11/rgb.txt lists the colors X recognizes. If a color name is two words, either remove the spaces in the name or put the name in single quotes, like this:

$ xsetroot -solid 'hot pink'

If you want an image in the background, use feh (/usr/ports/graphics/feh).

$ feh --bg-scale /home/mwlucas/galaxies.jpg

To make window edges easier to identify, put borders around them. The default border is 1 pixel wide, in your choice of colors. I prefer 3-pixel borders, blue for the active window and dark blue for the inactive windows. That requires the following entries in .cwmrc:

borderwidth 3
color activeborder blue
color inactiveborder darkblue

As you grow more accustomed to cwm, you might find that you want particular applications—perhaps an MP3 player, a clock, and a fancy graphic system load indicator—to always be visible. Maximizing a window can bury these applications. To address this, define a gap in .cwmrc, which sets the number of pixels to be kept clear even when you maximize a window.

gap top bottom left right

For example, when I must keep track of time, I run xclock(1) on the right side of my screen. Experimentation has shown that my clock is about 175 pixels wide. I leave a gap of 180 pixels, so that even when I maximize a window, it doesn’t cover the clock. Here’s my gap entry in .cwmrc:

gap 0 0 0 180

Now I can no longer use the excuse that I missed work because I lost my clock on my desktop. Fortunately, I have many other handy excuses.

While the cwm authors did their best to choose keyboard shortcuts that wouldn’t conflict with those used by other programs, they could not avoid every possible conflict. If you run into such a conflict, you can solve the problem by modifying entries in .cwmrc to replace conflicting cwm key bindings.

For example, cwm uses CTRL and CTRL-SHIFT with the arrow keys to move the pointer, but OpenOffice also uses these key combinations to move the pointer and highlight within a text document. I’ve used OpenOffice for more than 10 years, and have written millions of words in it. My fingers have been well-trained, and I’m not going to try to retrain them. The cwm key assignments must change.

Use the bind command to remap keys. Start by disconnecting the CTRL and CTRL-SHIFT and arrow key combinations from cwm with the unmap option. Remember that .cwmrc uses C to represent CTRL and S to represent SHIFT (as shown earlier in Table 17-1).

bind CS-Left unmap
bind CS-Right unmap
bind CS-Up unmap
bind CS-Down unmap
bind C-Left unmap
bind C-Right unmap
bind C-Up unmap
bind C-Down unmap

These keystrokes will now pass through to applications, such as OpenOffice.

To determine how to move the pointer with the keyboard, I check cwmrc(5) for the list of commands that can be bound to a key. The manual defines commands with a brief name and a description of their functionality. The pointer movement commands begin with ptrmove and bigptrmove, plus a direction. I find them and use the Windows key (also known as modifier 4) to replace the functions I removed from the CTRL key.

bind 4-Left ptrmoveleft
bind 4-Right ptrmoveright
bind 4-Up ptrmoveup
bind 4-Down ptrmovedown
bind 4S-Left bigptrmoveleft
bind 4S-Right bigptrmoveright
bind 4S-Up bigptrmoveup
bind 4S-Down bigptrmovedown

I can now use both OpenOffice and cwm’s keyboard functions.

At this point, I’ve covered everything I’ve used since OpenBSD introduced cwm, which should get you started. For more information, read cwm(1) and cwmrc(5). You’ll see that cwm supports many more features.

Now that we’ve covered OpenBSD’s appearance, let’s dive deep into the operating system core.