Window Maker Howto - linuxcsuf/linuxcsuf GitHub Wiki

Desktop environments are nice, but sometimes you don't need all the bells and whistles. It's possible to piece together your own desktop environment.

Window Maker is a clone of the NeXTSTEP user interface. It is a stacking window manager that features a dock of application tiles. All windows of a single application are grouped into one application tile. This way, all the windows of an application can be shown/hidden together.

In addition to regular applications, there are dockapps. A dockapp is a widget that displays its output directly in its application tile. Dockapps are frequently used for status information about the system.

Choose Window Maker if you want a lightweight old-school desktop.

Coincidentally, NeXTSTEP preceded Mac OS X, so many of Window Maker's design elements are also in Mac OS X. The big difference is that Window Maker is released under GPL and looks far more 90s-like.

Screenshot

Platform

I have Window Maker running on Slackware64 14.2. Window Maker is installed as part of Slackware. I have built a few extra packages that were not in the distro.

I built and am using the following extra packages from slackbuilds.org.

  • peksystemtray := This program presents the system tray icons in the form of a dockable window maker tile
  • volumeicon (built with NOTIFY=YES) := Provides a speaker icon in the system tray and listens globally for volume up/down keystrokes.
  • ptbatterysystemtray := System tray icon that displays the status of the battery.
  • wmclock := Displays the current date and time in a very 90s fashion
  • wmmon := Displays the current CPU load
  • slackware-xdg-menu := Generates an Applications menu for Window Maker (and other WMs) that is consistent with the Freedesktop.org menu used in KDE and XFCE.
  • dmenu := The suckless launcher is a fast text-based application launcher.

There are few other dockapps that I dabbled with:

  • wmcube := Displays a rotating 3D model whose rotation speed directly correlates to the CPU load. (I.e. the faster it spins, the more CPU usage)
  • wmdl := (For all you Doom fans out there) Displays the mugshot from Doom. As the system load increases, the mugshot gets bloodier.
  • wmcpu := A system load meter that resembles xosview. There is at the moment no slackbuild for it.

I am using the following applications most frequently. They all work with Window Maker quite well except where noted.

  • Konsole := KDE's terminal, supports tabbing
  • Gvim
  • SeaMonkey
  • Google Chrome (I had to tell Window Maker to emulate an application icon)
  • Claws-mail
  • Kopete := KDE IM client
  • Dolphin := KDE file manager

Xorg session configuration

Run xwmconfig (Slackware's utility to replace your .xinitrc with one corresponding to a different window manager). Select xinitrc.wmaker. This generates a file similar to the following. I modified mine slightly so that wmaker is wrapped in an ssh-agent context.

#!/bin/sh
# $XConsortium: xinitrc.cpp,v 1.4 91/08/22 11:41:34 rws Exp $

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap

# merge in defaults and keymaps

if [ -f $sysresources ]; then
    xrdb -merge $sysresources
fi

if [ -f $sysmodmap ]; then
    xmodmap $sysmodmap
fi

if [ -f $userresources ]; then
    xrdb -merge $userresources
fi

if [ -f $usermodmap ]; then
    xmodmap $usermodmap
fi

# If the user lacks $HOME/GNUstep, install it:
if [ ! -f $HOME/GNUstep/Defaults/WindowMaker ]; then
    wmaker.inst
fi

# Test for cpp, which wmaker uses to process config files:
if [ ! -x /usr/bin/cpp ]; then
  NOCPP="--no-cpp"
fi

# Start the window manager:
if [ -z "$DESKTOP_SESSION" -a -x /usr/bin/ck-launch-session ]; then
  exec ck-launch-session dbus-launch --exit-with-session ssh-agent /usr/bin/wmaker $NOCPP
else
  exec dbus-launch --exit-with-session ssh-agent /usr/bin/wmaker $NOCPP
fi

There are several nested commands here. Let's clarify what's going on here.

  • ssh-agent provides a daemon into which I can load encrypted SSH keys for passwordless authentication into remote systems. When ssh-agent is called with another command, it execs the command with environment variables added to its environment.
  • dbus-launch launches DBUS and exports the environment variables to the command following dbus-launch (in much the same way as ssh-agent). DBUS is an interprocess communication mechanism that facilitates communication between various desktop components.
  • ck-launch-session launches a ConsoleKit session and exports its environment variables into the command following ck-launch-session. ConsoleKit is a system that attempts to determine which users are at which "seats" of a computer. It then attempts to determine whether each seat is local/remote and active/inactive. ConsoleKit has been replaced with systemd-logind in newer systems, so ck-launch-session may not be installed on your system.

Put together, we get a ConsoleKit session that spawns a DBUS session that spawns an ssh-agent that spawns Window Maker. Whew!

We are almost ready to hop back into a GUI. But let's do a little bit of organizing first. Did you notice that one if statement in .xinitrc?

# If the user lacks $HOME/GNUstep, install it:
if [ ! -f $HOME/GNUstep/Defaults/WindowMaker ]; then
    wmaker.inst
fi

Run it now. This will create a GNUstep directory with Window Maker configuration files.

Now, let's a create a simple script that runs on every initialization and reinitialization of Xorg. Call it ~/.xautorun and make it executable.

#!/bin/sh
#
# ~/.xautorun
#
# This script is run very often during an X11 session.
# * On start (called by WM)
# * On restart of WM (called by WM)
# * On resume from suspend/hibernate (called by slacklock)
#
# It must be called under a ConsoleKit context because
# it launches a polkit agent.
#
# This script must be executable

# Mouse acceleration
xset m 20/10 4

# Keyboard
xset r rate 250 40
#setxkbmap -option compose:caps
#setxkbmap -option 'ctrl:swapcaps,compose:lctrl'
#setxkbmap -option 'ctrl:nocaps'
setxkbmap -option 'caps:escape'

# Polkit agent
if ! pgrep polkit-kde-auth > /dev/null ; then
	/usr/lib64/kde4/libexec/polkit-kde-authentication-agent-1 &
fi

Mine has a keyboard key remap in there. You may or may not want that.

Most importantly, the KDE Polkit agent is started. This is a user background daemon that prompts the user for passwords when privileged actions are attempted. Without it, you will simply get "permission denied" errors. I consider this process important enough to be restarted if it isn't running, because the usual reaction is frustrated mumbling. ("Look at me! I am the admin now.")

Let's set this up to run on every startup and restart of Window Maker. (Window Maker will restart automatically e.g. if you change the monitor configuration, or if you tell it to yourself.) Put the following in ~/GNUstep/Library/WindowMaker/autostart.

#!/bin/sh
#
# Place applications to be executed when WindowMaker is started here.
# This should only be used for non-X applications or applications that
# do not support session management. Other applications should be restarted
# by the WindowMaker session restoring mechanism. For that, you should
# either set SaveSessionOnExit=YES or select "Save Session" in the Workspace
# submenu of the root menu when all applications you want started are
# running.
#
# WindowMaker will wait until this script finishes, so if you run any
# commands that take long to execute (like a xterm), put a ``&'' in the
# end of the command line.
#
# This file must be executable.
#

[ -x "$HOME/.xautorun" ] && sh "$HOME/.xautorun"

That's it! Go ahead and run startx.

Brief tutorial on using Window Maker

When launching Window Maker for the first time, you will see a purple background. On the right is the dock, which contains two icons: WPrefs and xterm. On the left is the clip, which acts as a workspace switcher and secondary dock.

You can launch an application from the dock by double-clicking on it. Double-clicking on a running application will bring all windows of the application to the front.

Press Alt+h to hide all windows of the current application.

Application tiles can be docked by dragging the tile to the dock. Applications can be undocked by dragging the tile away from the dock.

For more information, please refer to the documentation.

Power management (slacklock)

There are no menu options for power management (e.g. suspend, poweroff). But that's no problem. We have ConsoleKit. ConsoleKit exposes an API via DBUS that gives us access to power management functionality. Install the following helper script into ~/bin/slacklock.

#!/bin/bash
#
# slacklock
#
# Lock and suspend for Slackware (minimal environments)
# These were taken from
# <https://wiki.archlinux.org/index.php/Consolekit#Use_D-Bus_for_power_operations>

lock() {
	xlock -allowroot -usefirst -mode blank -dpmsoff 1
}

sus() {
	dbus-send --system --print-reply \
		--dest="org.freedesktop.ConsoleKit" \
		/org/freedesktop/ConsoleKit/Manager \
		org.freedesktop.ConsoleKit.Manager.Suspend  \
		boolean:true
}

hiber() {
	dbus-send --system --print-reply \
		--dest="org.freedesktop.ConsoleKit" \
		/org/freedesktop/ConsoleKit/Manager \
		org.freedesktop.ConsoleKit.Manager.Hibernate  \
		boolean:true
}

reb() {
	dbus-send --system --print-reply \
		--dest="org.freedesktop.ConsoleKit" \
		/org/freedesktop/ConsoleKit/Manager \
		org.freedesktop.ConsoleKit.Manager.Restart
}

hybsleep() {
	dbus-send --system --print-reply \
		--dest="org.freedesktop.ConsoleKit" \
		/org/freedesktop/ConsoleKit/Manager \
		org.freedesktop.ConsoleKit.Manager.HybridSleep  \
		boolean:true
}

off() {
	dbus-send --system --print-reply \
		--dest="org.freedesktop.ConsoleKit" \
		/org/freedesktop/ConsoleKit/Manager \
		org.freedesktop.ConsoleKit.Manager.Stop
}

res() {
	# Run some re-init commands for Xorg (e.g. mouse accel)
	[ -x "$HOME/.xautorun" ] && "$HOME/.xautorun"
}

case "$1" in
	lock)
		lock
		;;
	sus|suspend)
		lock &
		sus
		wait
		res
		;;
	hib|hibernate)
		lock &
		hiber
		wait
		res
		;;
	reb|reboot)
		reb
		;;
	hyb|hybsleep)
		lock &
		hybsleep
		wait
		res
		;;
	off)
		off
		;;
	*)
		echo "Usage: $0 {lock|suspend|hibernate|hybsleep|reboot|off}"
		exit 2
esac

exit 0

Now, it is possible to issue any power management command that you want. Each option will lock the screen using xlock and run .xautorun after the user unlocks the screen. My recommendation is to add a "Power" menu to the root menu (see next section).

Tweaking root menu

The root menu is the menu that is displayed when right-clicking on the desktop. The root menu can be customized through WPrefs or by modifying ~/GNUstep/Defaults/WMRootMenu.

Feel free to consult my WMRootMenu.

Tip: I recommend backing up WMRootMenu to WMRootMenu.orig before making these modifications.

Freedesktop.org Applications menu

The default configuration has an applications menu. However, it is fixed, and it does not contain everything found in the KDE Applications menu. This is because KDE follows the Freedesktop.org standard, but Window Maker predates the standard. Fortunately, there is a tool to patch that.

Build and install slackware-xdg-menu from slackbuilds.org. Then, open up WPrefs and drag the "Generated Submenu" option into the root menu. Enter the following command into the text box:

xdg_menu --format WindowMaker --root-menu /etc/xdg/menus/applications.menu

Press Save and right-click on the desktop. You should have an applications menu that matches the Freedesktop.org hierarchy.

WPrefs generated the following snippet in my WMRootMenu:

  (
    Applications,
    OPEN_MENU,
    "|| xdg_menu --format WindowMaker --root-menu /etc/xdg/menus/applications.menu"
  ),

Better "Run..." dialog

The built-in run dialog of Window Maker is okay, but there are better options out there. My personal favorite is dmenu_run. Build and install dmenu from slackbuilds.org.

Then, insert the following command into your root menu. (Customize the options to your liking.)

dmenu_run -b -fn 'monospace:size=9'

Power management

There are no shutdown, reboot, etc. options in the root menu. Why? As a standalone window manager, Window Maker does not concern itself with power management of the system.

However, in this environment we have ConsoleKit, which does concern itself with power management. Install the slacklock script mentioned above.

Now, add corresponding menu options in the root menu for each action. There is no "are you sure?" prompt, so I recommend segregating the dangerous options into their own submenu so that they are less likely to be triggered accidentally.

My WMRootMenu has the following at the very end:

  ("Info Panel", INFO_PANEL),
  (
    Power,
    (Suspend, EXEC, "slacklock suspend"),
    (Hibernate, EXEC, "slacklock hibernate"),
    ("Hybrid Sleep", EXEC, "slacklock hybsleep"),
    (Reboot, EXEC, "slacklock reboot"),
    ("Shut Down", EXEC, "slacklock off")
  ),
  (
    "Exit/Lock",
    ("Lock Screen", SHORTCUT, "Control+Mod1+L", EXEC, "slacklock lock"),
    ("Restart Window Maker", SHORTCUT, "Shift+Mod4+R", RESTART),
    ("Exit Window Maker", SHORTCUT, "Shift+Mod4+Q", EXIT)
  )

Tuning the environment

Now that we have a working Window Maker, let's tune it to perfection and fix some annoyances.

System tray and dockapps

Window Maker contains no system tray. Build and install peksystray from slackbuilds.org. peksystray is a dockapp that displays a system tray. The following configuration uses 4 large icons per tile. If there are more icons, an additional tile is created.

peksystray --icon-size 24 --border 8 --width 64 --height 64

You can alternatively use a 9x9 grid:

peksystray --icon-size 16 --border 8 --width 64 --height 64

An alternative is wmsystemtray, which gives you buttons to switch between multiple pages of icons if you have too many system tray icons.

Laptops should have some battery indicator. Build and install ptbatterysystemtray from slackbuilds.org. Run it to put a battery icon in your system tray. Launch the config utility and select your battery.

wmclock is a dockapp that makes a good system clock. Build and install wmclock from slackbuilds.org.

wmmon is a dockapp that displays CPU usage. Build and install wmmon from slackbuilds.org.

wmcpu is a dockapp that somewhat resembles xosview. There is no slackbuild for Slackware at the moment.

wmcube (which displays a rotating 3D object) and wmdl (which displays the mugshot from Doom) are dockapps that are fun addons.

GTK and QT themes

This is thorny. To the best of my knowledge, the only way to make GTK2, GTK3, and QT to look the same is to use one of the new "materialized" or "mobile-look" themes, almost all of which are in my opinion unacceptably ugly. Also, these themes still do not cover other toolkits in use, such as Tk, Motif, and FLTK.

So, if I can't make every application look the same, then each toolkit should maintain a consistent look across the toolkit. QT for some reason violates this rule. KDE applications, such as Konsole and Dolphin by default render in the Oxygen theme, but generic QT applications by default render in the Windows theme.

There is a simple fix. Run qtconfig and change GUI style from "Desktop Settings (Default)" to something else. (I use "GTK+", but you may wish to use Plastique or Windows.)

And also make sure that KDE does not inject stuff (like custom colors) into gtkrc. Run kcmshell4 colors, go to Options tab, and uncheck Apply colors to non-KDE4 applications. Clean up any cruft left in .gtkrc-2.0, .gtkrc-2.0.kde4, and .config/gtk-3.0/settings.ini.

So, my configuration is as follows:

  • QT := forced to emulate GTK+ style (Raleigh)
  • GTK2 := default (Raleigh), looks like Windows 95
  • GTK3 := default (Adwaita), looks like older versions of the iPhone
  • Other toolkits := defaults. Each one has its own look.

Default applications

There appear to be 3 somewhat related systems for determining default applications.

  • .config/mimeapps.list := Used in GTK programs, this is supposed to be the Freedesktop.org standard.
  • KDE's defaults database := Used by KDE programs
  • xdg-utils := also keeps track of the notion of a "default web browser"

This is Hell. In particular, I had to run the following command to make links open in SeaMonkey.

xdg-settings set default-web-browser seamonkey.desktop

Fixing dumb applications: application tiles

Sometimes you will run into an application that has no application tile (e.g. Google Chrome). In this case, right-click the caption bar and select Attributes. Under Advanced Options, check "Emulate application icon" (3rd checkbox from bottom). Press Save and then press Apply. Restart Window Maker (e.g. via the root menu). The application icon should appear.

Sometimes you will have the opposite problem. A daemonized application will create a window, which creates an application tile. However, when the window is closed, the application continues in daemonized mode, so the application tile stays put. In this case, when the window is open, right-click the caption bar and select Attributes. Under Application Specific, check "No application icon. Press Save and then press Apply. The icon should disappear.

Notes for other systems (e.g. those with systemd)

This guide was written with Slackware in mind. Most of this guide applies to other systems, but there are some big differences to watch out for.

systemd

Most distros have systemd as a basis. If this is the case, then omit the ck-launch-session and dbus-launch commands in .xinitrc. Systemd handles those automatically with systemd-logind.

The ConsoleKit commands in slacklock should work. (Someone please verify this.) However, there is a simpler way: use systemctl. For example, systemctl poweroff issues an immediate power off. Systemd will check authorizations in much the same way ConsoleKit checks them on my system.

Display managers

If you really insist on using a display manager, you may need to add an xsession file to tell it about Window Maker. Configuration depends on the display manager. Some display managers simply execute .xinitrc.

/usr/share/xsessions/wmaker.desktop (taken from Arch Linux package)

[Desktop Entry]
Encoding=UTF-8
Name=windowmaker
Exec=/usr/bin/wmaker
Type=Application

Applications

Your distro may package different applications. You may be able to install the applications I have described. If not, consider alternatives.

  • xwmconfig := If you are not using Slackware, you will not have this utility! Simply copy my xinitrc.
  • xlock := session locker. There are also slock and i3lock, which behave similarly. Alternatively, you could run a full screensaver daemon such as xscreensaver.
  • dmenu := There are plenty of application launchers. Be creative or use Window Maker's built-in launcher.
  • Polkit agent := I am using KDE's Polkit agent. Each desktop environment has its own. Pick whichever one you have installed.