Manual

Install Window Maker as a startx session on Gentoo

Install Window Maker 0.96.0 and four dockapps on Gentoo, seed the per-user defaults, autostart the dockapps in the Dock, and give startx a client script that runs wmaker. End state: the packages are installed, ~/GNUstep is seeded, and startx ~/.xinitrc-windowmaker is ready to run. I logged into it on 2026-11-02 (Field notes).

Tested on
ThinkPad Yoga 370 (20JH, i5-7300U), Gentoo amd64 23.0 desktop profile (default/linux/amd64/23.0/desktop), OpenRC, x86-64-v3 binhost; x11-wm/windowmaker-0.96.0-r1, x11-base/xorg-server-21.1.24, x11-apps/xinit-1.4.4 (2026-11-02).
Not verified
the minimal client script (step 8) and the rollback. Everything else was checked structurally (packages, files, sh -n, wdread, the tty menu branch with a stub startx) and then in a real login on 2026-11-02 (Field notes).
Needs
root (sudo) for emerge and /etc/portage; a working Xorg with startx (x11-apps/xinit); a tty login. Optional: OpenRC user services and a tty session menu, which is how my box starts sessions (steps 9 to 11); step 10's script also sources my ~/.config/x11/common, which this manual does not create.
Time
15 min: my first run took 13 min, from writing package.use (00:19) to the autostart lines (00:32). With my USE flags Window Maker builds from source (3 min 13 s here) and wmsystemtray always does.
Risk
low and reversible. Only new files under /etc/portage and ~, plus six new packages. wmaker.inst --batch overwrites ~/GNUstep/Defaults/WindowMaker without asking if it already exists: back it up first.

Before you start#

  • You are on a 23.0 profile and have Xorg and startx:
    $ eselect profile show
    Current /etc/portage/make.profile symlink:
      default/linux/amd64/23.0/desktop
    $ qlist -Iv x11-base/xorg-server
    x11-base/xorg-server-21.1.24
    $ qlist -Iv x11-apps/xinit
    x11-apps/xinit-1.4.4
    
    Expected: an amd64 profile; both packages installed. If qlist prints nothing, install Xorg first; this manual does not cover it.
  • Back up any existing Window Maker user config (step 5 overwrites it):
    [ -d ~/GNUstep ] && cp -a ~/GNUstep ~/GNUstep.bak-$(date +%F)
    
  • No wmaker is running. Steps 5 and 6 edit files a running Window Maker reads:
    $ pgrep -x wmaker; echo rc=$?
    rc=1
    
    Expected: rc=1 (no process).

Steps#

  1. Set Window Maker's USE flags.

    echo 'x11-wm/windowmaker png jpeg webp xinerama xpm nls xrandr' | sudo tee /etc/portage/package.use/windowmaker
    
    $ cat /etc/portage/package.use/windowmaker
    x11-wm/windowmaker png jpeg webp xinerama xpm nls xrandr
    

    Expected: the one line. xinerama and xrandr are what keep the binhost package from being used (step 2). The binhost build of 0.96.0-r1 has gif jpeg nls png tiff webp xpm and neither of them. Without them, the binary package matches. xinerama adds Xinerama multi-monitor geometry queries (use.desc); xrandr enables XRandR extension support (metadata.xml).

  2. Emerge Window Maker.

    $ sudo emerge --ask x11-wm/windowmaker
    …
    [ebuild  N     ] x11-wm/windowmaker-0.96.0-r1  USE="gif jpeg nls png tiff webp xinerama xpm xrandr -imagemagick -modelock"
    
    !!! The following binary packages have been ignored due to non matching USE:
    
        =x11-wm/windowmaker-0.96.0-r1 -xinerama -xrandr
    …
    >>> Completed (1 of 1) x11-wm/windowmaker-0.96.0-r1::gentoo
    

    Expected: Completed (1 of 1). [ebuild means a source build, [binary a binhost package. The "ignored due to non matching USE" lines are a notice, not an error (Failure modes, row 3).

  3. Accept the ~amd64 keyword for wmsystemtray. It is the only one of the four dockapps without a stable amd64 keyword (KEYWORDS="~amd64 ~ppc64 ~x86"). Write it without a version, so later releases are accepted too:

    $ echo 'x11-plugins/wmsystemtray ~amd64' | sudo tee /etc/portage/package.accept_keywords/wmsystemtray
    x11-plugins/wmsystemtray ~amd64
    

    Expected: the line echoed back. If you skip this step, step 4 fails with Failure modes, row 2.

  4. Emerge the dockapps from x11-plugins. The category is x11-plugins, not x11-misc (Failure modes, row 1).

    $ sudo emerge --ask x11-plugins/wmclock x11-plugins/wmifs x11-plugins/wmmemload x11-plugins/wmsystemtray
    …
    [binary  N g   ] x11-libs/libdockapp-0.7.3-1  USE="X -static-libs"
    [binary  N g   ] x11-plugins/wmclock-1.0.16-r1-2
    [binary  N g   ] x11-plugins/wmmemload-0.1.8-r1-1
    [ebuild  N    ~] x11-plugins/wmsystemtray-1.4-r3
    [binary  N g   ] x11-plugins/wmifs-1.9-1
    …
    >>> Jobs: 5 of 5 complete                                               Load avg: 1.02, 1.19, 1.13
    

    Expected: 5 of 5 complete. libdockapp comes in as a dependency. Only wmsystemtray builds from source.

  5. Seed ~/GNUstep with wmaker.inst --batch. It needs no X display. This copies the stock WindowMaker defaults, generates WMRootMenu with wmgenmenu, and creates Library/WindowMaker/ with an executable autostart:

    $ wmaker.inst --batch
    Installing WindowMaker 0.96.0 for current user...
    Creating ~/GNUstep user directory
    Copying defaults database...
    Creating icon library directory ~/GNUstep/Library/Icons
    Creating WindowMaker data library directory ~/GNUstep/Library/WindowMaker
    Creating style library ~/GNUstep/Library/WindowMaker/Styles
    Creating theme library ~/GNUstep/Library/WindowMaker/Themes
    Creating bg image library ~/GNUstep/Library/WindowMaker/Backgrounds
    Creating icon setup library ~/GNUstep/Library/WindowMaker/IconSets
    Creating pixmap library ~/GNUstep/Library/WindowMaker/Pixmaps
    Installation Finished
    $ ls ~/GNUstep/Defaults
    WMRootMenu
    WindowMaker
    

    Expected: Installation Finished and the two files. (This transcript is from a re-run on the same box with a scratch HOME; the first seed's output was not saved. Paths shortened to ~.)

    WarningRun wmaker.inst --batch once

    Batch mode never prompts. On a second run it replaces Defaults/WindowMaker with the stock file and regenerates WMRootMenu, so every edit made in steps 6 onward is lost. autostart survives because it is copied only if absent. Proof: Failure modes, row 4. To refresh only the menu, use wmgenmenu > ~/GNUstep/Defaults/WMRootMenu.

  6. Stop Window Maker painting over your wallpaper (optional). The stock WorkspaceBack is a solid colour. If something draws the root window before wmaker starts (my x11/common does, step 10), set it to (none):

    $ wdread WindowMaker WorkspaceBack
    (solid, "rgb:50/50/75")
    $ wdwrite WindowMaker WorkspaceBack '(none)'
    $ wdread WindowMaker WorkspaceBack
    (none)
    

    Expected: (none) on read-back. (Transcript from the same scratch HOME as step 5; my real defaults read (none) too, see Verify.) Skip this step if Window Maker is the only thing that sets a background.

  7. Start the dockapps from autostart. Window Maker runs this script before it starts handling events and waits for it to exit, so every command gets a trailing &. It also runs the script again on every Restart (root menu), while the first dockapps are still alive, so each line starts its program only if it is not already running. wmmemload -b -c leaves buffers and page cache out of "used" memory; without it the meter read 86% on a box with 13 GiB available. The file must stay executable. Append the four lines under the stock comment header:

    cat >> ~/GNUstep/Library/WindowMaker/autostart <<'EOF'
    pgrep -x wmclock >/dev/null || wmclock &
    pgrep -x wmifs >/dev/null || wmifs &
    pgrep -x wmmemload >/dev/null || wmmemload -b -c &
    pgrep -x wmsystemtray >/dev/null || wmsystemtray &
    EOF
    

    (Transcript from a scratch HOME; my live file has one more dockapp, wmix, and a comment.)

    $ tail -4 ~/GNUstep/Library/WindowMaker/autostart
    pgrep -x wmclock >/dev/null || wmclock &
    pgrep -x wmifs >/dev/null || wmifs &
    pgrep -x wmmemload >/dev/null || wmmemload -b -c &
    pgrep -x wmsystemtray >/dev/null || wmsystemtray &
    $ sh -n ~/GNUstep/Library/WindowMaker/autostart; echo rc=$?
    rc=0
    $ stat -c "%A %n" ~/GNUstep/Library/WindowMaker/autostart
    -rwxr-xr-x ~/GNUstep/Library/WindowMaker/autostart
    

    Expected: the four lines, rc=0, x bits set.

  8. Write a minimal startx client script. One file per window manager, so startx can be pointed at it:

    cat > ~/.xinitrc-windowmaker <<'EOF'
    #!/bin/sh
    exec wmaker
    EOF
    chmod 755 ~/.xinitrc-windowmaker
    
    $ cat ~/.xinitrc-windowmaker
    #!/bin/sh
    exec wmaker
    $ sh -n ~/.xinitrc-windowmaker; echo rc=$?
    rc=0
    $ stat -c "%A %n" ~/.xinitrc-windowmaker
    -rwxr-xr-x ~/.xinitrc-windowmaker
    

    Expected: rc=0 and x bits set. exec wmaker is also what upstream's install page puts in ~/.xinitrc. (Transcript from a scratch HOME, paths shortened to ~; on my box this file is the longer script in step 10.) [UNVERIFIED: this minimal script was not started; my box runs the step 10 script]

  9. (My box) Give the session its own OpenRC user runlevel. My session daemons are OpenRC user services; each window manager gets a runlevel with default stacked in, so entering it never stops dbus or PipeWire. Skip steps 9 to 11 if you don't run user services or a tty menu. The two commands are from my rebuild notes (the original run was not captured); the output below is from 2026-11-02 20:56:

    mkdir -p ~/.config/rc/runlevels/windowmaker
    rc-update --user -s add default windowmaker
    
    $ rc-status --user windowmaker
    Runlevel: windowmaker
    Stacked Runlevel: default
     dbus                                                  [  started 20:41:24 (0) ]
     pipewire                                              [  started 20:41:24 (0) ]
     wireplumber                                           [  started 20:41:24 (0) ]
     pipewire-pulse                                        [  started 20:41:24 (0) ]
    

    Expected: Stacked Runlevel: default. I add no services of my own to this runlevel: my terminal and notification services there need Wayland.

  10. (My box) Replace the client script with the glue version. This is my ~/.xinitrc-windowmaker as it is on the box. It needs two things this manual does not create: ~/.config/x11/common (my shared X startup: keyboard layout, settings daemon, wallpaper, idle lock), and, for the openrc lines, the runlevel from step 9. /bin/sh stops at a failed ., so without that file wmaker never starts. In the comments, "the Path-B chooser" is the tty menu in step 11 and sway-session is my Wayland launcher. It runs wmaker without exec so the script can leave the runlevel after Window Maker exits:

    #!/bin/sh
    # X session: Window Maker. Launched by the Path-B chooser via
    # `startx ~/.xinitrc-windowmaker -- vtN`.
    #
    # Shared startup (env, xkb layout, xsettingsd, cursor, root colour, .Xdefaults)
    # lives in ~/.config/x11/common so the bare X WMs cannot drift apart.
    . "$HOME/.config/x11/common"
    
    export XDG_CURRENT_DESKTOP=WindowMaker
    
    # Enter this WM's own OpenRC user runlevel. `default` (dbus/pipewire/wireplumber)
    # is stacked into it, and -n (--no-stop) makes entry purely additive, so this can
    # never stop the session bus out from under us. Done here rather than in each
    # WM's own config so all the bare X WMs share one mechanism.
    openrc -U -n windowmaker
    
    # NOTE: deliberately not `exec` -- this script must outlive the WM to run the
    # teardown below, exactly as /usr/local/bin/sway-session does.
    #
    # Window Maker provides its own Dock and Clip, so no external panel/bar is
    # started here (unlike openbox/fvwm3, which run a standalone xfce4-panel).
    # Dockapps go in ~/GNUstep/Library/WindowMaker/autostart if wanted.
    #
    # ~/GNUstep/Defaults/ was seeded with `wmaker.inst --batch`, so the user
    # defaults database (WindowMaker, WMRootMenu) exists and edits go here instead
    # of the read-only /etc/X11/WindowMaker fallback. Re-seed only if it is missing.
    wmaker
    
    # WM has exited. Leave its runlevel so any WM-bound service stops rather than
    # lingering with a dead display. `default` is stacked, so dbus/pipewire survive;
    # pam_openrc stops those at PAM session close.
    openrc -U default >/dev/null 2>&1
    
    $ sh -n ~/.xinitrc-windowmaker; echo rc=$?
    rc=0
    

    Expected: rc=0.

  11. (My box) Add the session to the tty menu. My tty1 login runs a small menu script (~/.local/bin/session-chooser) whose startx_session function execs startx "$HOME/.xinitrc-$1" -- vtN, with N taken from the current tty. All ten digits were already used, so Window Maker got a letter. One line goes into the menu's list of printf lines, the other into the case before the *) fallback:

    printf '   [w] windowmaker (X11)\n'
    
    	w|W) startx_session windowmaker ;;
    

    Checked with stubs for startx and sway-session on PATH, a scratch HOME holding a copy of the step 10 script, and the real menu script driven through script:

    $ printf 'w\n' | script -qec 'bash /home/user/.local/bin/session-chooser' /dev/null | tail -3
       [w] windowmaker (X11)
    
      session [1]: STUB startx ~/.xinitrc-windowmaker -- vt0
    

    Expected: the stub prints the startx line. vt0 is the pseudo-terminal's number under script; on tty1 it is vt1. An unmatched key still falls through to my default session (STUB sway-session).

  12. Start the session. Log in on a tty and run:

    startx ~/.xinitrc-windowmaker -- vt1
    

    Use the number of the tty you are on in place of 1.

Verify#

Structural checks, run 2026-11-02 on the Yoga 370 (home path shortened to ~):

$ command -v wmaker wmclock wmifs wmmemload wmsystemtray
/bin/wmaker
/bin/wmclock
/bin/wmifs
/bin/wmmemload
/bin/wmsystemtray
$ wmaker --version
Window Maker 0.96.0
$ for k in ModifierKey WorkspaceBack; do printf "%s = " $k; wdread WindowMaker $k; done
ModifierKey = Mod4
WorkspaceBack = (none)
$ stat -c "%A %n" ~/.xinitrc-windowmaker ~/GNUstep/Library/WindowMaker/autostart
-rwxr-xr-x ~/.xinitrc-windowmaker
-rwxr-xr-x ~/GNUstep/Library/WindowMaker/autostart

Expected: five binaries, version 0.96.0, WorkspaceBack = (none), both scripts executable. ModifierKey = Mod4 is from my later key setup (Notes), not from this manual; the stock value is Mod1.

In the session (step 12): the Dock and the Clip appear, the four dockapps land in the Dock, and the wallpaper from x11/common stays visible behind them. Restart Window Maker from the root menu: still one of each dockapp.

Undo / rollback#

[UNVERIFIED: rollback not exercised; the unmerge list below is a pretend run]

  1. Leave the session, then remove the packages from the world file and unmerge them. The pretend run lists exactly these six:
    $ emerge -pC x11-wm/windowmaker x11-plugins/wmclock x11-plugins/wmifs x11-plugins/wmmemload x11-plugins/wmsystemtray x11-libs/libdockapp
    …
    All selected packages: =x11-plugins/wmmemload-0.1.8-r1 =x11-plugins/wmsystemtray-1.4-r3 =x11-plugins/wmclock-1.0.16-r1 =x11-plugins/wmifs-1.9 =x11-libs/libdockapp-0.7.3 =x11-wm/windowmaker-0.96.0-r1
    
    For the real removal, take them out of the world file, preview, then depclean only these atoms (a bare --depclean would remove every orphan on the system):
    sudo emerge --deselect x11-wm/windowmaker x11-plugins/wmclock x11-plugins/wmifs x11-plugins/wmmemload x11-plugins/wmsystemtray
    emerge -p --depclean x11-wm/windowmaker x11-plugins/wmclock x11-plugins/wmifs x11-plugins/wmmemload x11-plugins/wmsystemtray x11-libs/libdockapp
    sudo emerge --depclean x11-wm/windowmaker x11-plugins/wmclock x11-plugins/wmifs x11-plugins/wmmemload x11-plugins/wmsystemtray x11-libs/libdockapp
    
  2. sudo rm /etc/portage/package.use/windowmaker /etc/portage/package.accept_keywords/wmsystemtray
  3. rm -r ~/GNUstep, and restore ~/GNUstep.bak-<DATE> if you made one in Before you start.
  4. rm ~/.xinitrc-windowmaker. On my box also: rc-update --user -s del default windowmaker, rmdir ~/.config/rc/runlevels/windowmaker, and delete the two menu lines from step 11.

Failure modes#

Symptom (exact message)CauseFix
emerge: there are no ebuilds to satisfy "x11-misc/wmclock".Wrong category. The dockapps are in x11-plugins.emerge x11-plugins/wmclock (same for wmifs, wmmemload, wmsystemtray).
!!! All ebuilds that could satisfy "x11-plugins/wmsystemtray" have been masked. … - x11-plugins/wmsystemtray-1.4-r3::gentoo (masked by: ~amd64 keyword)wmsystemtray has only ~amd64.Step 3: x11-plugins/wmsystemtray ~amd64 in package.accept_keywords, without a version.
!!! The following binary packages have been ignored due to non matching USE: / =x11-wm/windowmaker-0.96.0-r1 -xinerama -xrandrThe binhost package was built without xinerama and xrandr; step 1 enables both.Nothing, if a 3-minute source build is fine. To use the binary, drop xinerama xrandr from step 1.
wdread WindowMaker WorkspaceBack prints (solid, "rgb:50/50/75") again after you had set (none)wmaker.inst --batch was run a second time and reset Defaults/WindowMaker to stock.Restore from your backup, or redo step 6 and every later wdwrite. Never re-run --batch; use wmgenmenu for the menu.

Field notes#

  • 2026-11-02 evening, Yoga 370, Gentoo amd64 23.0 desktop/OpenRC, windowmaker-0.96.0-r1, first login: startx ~/.xinitrc-windowmaker from the tty menu. The Dock and Clip came up, the dockapps docked, the wallpaper stayed. Four things went wrong first. Restart from the root menu started every dockapp a second time, because autostart runs again while the first set is alive (step 7 now checks with pgrep). wmmemload showed 86% with 13 GiB available (now -b -c). Super+2 did nothing: Window Maker starts with one workspace, and a workspace key only switches to a workspace that exists unless AdvanceToNewWorkspace = YES, which creates it (src/event.c:1699; wWorkspaceForceChange, src/workspace.c:476-489); I set that (Notes). Right-click on the desktop did nothing, which was not Window Maker: xinput test-xi2 --root showed my touchpad's bottom-right corner arriving as button 1, because the X libinput driver had the pad in clickfinger mode. I switched the pad to button areas (libinput Click Method Enabled 1 0, read back 1, 0); a synthetic button-3 click opened the root menu, but the corner itself was not re-tested on its own. After those fixes and two Restarts, Super+Return, Super+2, Super+d (the Run panel from my menu shortcuts) and Restart all worked. Evidence: raw/login-2026-11-02.md.
  • 2026-11-02 20:51-21:05, Yoga 370, Gentoo amd64 23.0 desktop/OpenRC, windowmaker-0.96.0-r1: I re-checked everything I could without logging in. wmaker.inst --batch ran in a scratch HOME with DISPLAY unset (rc=0, the step 5 transcript). In the same scratch HOME I set WorkspaceBack to (none), ran --batch again, and read back (solid, "rgb:50/50/75"): the overwrite in the step 5 warning is real. The first day's wmsystemtray error was never saved, so I reproduced it (row 2) with emerge -p against a copy of /etc/portage without the keyword file. The minimal step 8 script passed sh -n in a scratch HOME. The tty menu's w branch reached a stub startx with ~/.xinitrc-windowmaker -- vt0 (vt0 because script runs on a pty). An unmatched key still reached the default session. wdread on the real defaults gives WorkspaceBack = (none). No wmaker process; still not logged in.
  • 2026-11-02 00:19-00:32 and 20:35, Yoga 370, Gentoo amd64 23.0 desktop/OpenRC, windowmaker-0.96.0-r1: I wrote package.use/windowmaker at 00:19. emerge x11-wm/windowmaker started at 00:20 and built from source in 3 min 13 s, because the binhost package lacked xinerama xrandr. My first dockapp emerge used x11-misc/... and failed (row 1). The first x11-plugins emerge, at 00:29, exited with status 1 before the wmsystemtray keyword existed; its output was lost behind a dispatch-conf session. I added the keyword at 00:31, and the next emerge took four packages as binaries and built wmsystemtray. The runlevel was created at 00:25 and the autostart lines at 00:32. In the evening (defaults files saved 20:34-20:35) I reviewed the seeded config: the stock solid WorkspaceBack would cover the wallpaper my x11/common draws, so I set it to (none) and moved the keys to Super (Notes). I also found that my power menu's logout did not know about wmaker: it would have ended the login session and skipped the openrc -U default teardown in step 10. I added wmaker to its list of window managers.

Notes#

  • Defaults edits and a running wmaker. I made the evening's wdwrite edits with wmaker not running. wdwrite rewrites and reorders the whole file. This build has inotify: a running 0.96.0 watches the Defaults directory (inotifyWatchConfig, src/main.c:491) and re-reads changed domains on an IN_MODIFY event (handle_inotify_events, src/event.c:360). At my first login I wrote AdvanceToNewWorkspace while it ran, then restarted it before testing, so whether a live edit applies without a Restart is not tested.
  • Why (none) and not a colour. WorkspaceBack = (none) is accepted case-insensitively by getWSBackground (src/defaults.c:2054). With a texture set, Window Maker launches wmsetbg for the background (src/defaults.c:3101). The upstream user guide says the default is none, but 0.96.0's code and the shipped file both default to (solid, "rgb:50/50/75"). With (none) set, the wallpaper my x11/common draws stayed visible at login.
  • Binding commands to keys. The WindowMaker defaults file binds only window-manager actions. A command gets a key through the root menu: (Title, SHORTCUT, "Mod4+Return", EXEC, xterm) in WMRootMenu (src/rootmenu.c:1536-1545). I bound mine that way and moved the modifier to Super (ModifierKey = Mod4). That configuration is for a separate post; Super+Return and Super+d worked in the login session.
  • % in menu commands. ExpandOptions (src/misc.c) passes an unknown %X through unchanged, and there is no %% escape: wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- is correct as written, and 5%%- would reach wpctl with both %. The letters w W a A s are expanded (%a opens an input dialog), and \% gives a literal % (from reading the code, not tested).
  • Dockapp options. wmifs -i <IFACE> if it picks the wrong interface; wmsystemtray -s uses 16x16 icons. Not tried.
  • wmaker.inst writes no ~/.xinitrc in 0.96.0, even though windowmaker.org's install page says it sets X up to start Window Maker. wmgenmenu lists only programs it finds on PATH, so the menu depends on what is installed.
  • Gentoo also installs /usr/share/xsessions/wmaker.desktop for display managers. I don't use one.

Filed under: gentoo, x11, linux

Sources#

  • Window Maker 0.96.0 source, WindowMaker-0.96.0.tar.gz from Gentoo distfiles: util/wmaker.inst.in (--batch skips the replace prompt, lines 7-8 and 112-125; autostart copied only if absent, 219-220), src/main.c:519-535 (autostart via system() before the event loop), src/defaults.c (WorkspaceBack default at 549, None at 2054), src/rootmenu.c:1536-1545 (SHORTCUT), src/misc.c:664-667 (% default case).
  • Window Maker: Installation — exec wmaker in ~/.xinitrc; wmgenmenu > $HOME/GNUstep/Defaults/WMRootMenu.
  • Window Maker: wmaker_install — the wmaker.inst claim the 0.96.0 script does not do.
  • Window Maker User Guide, chapter 4 — WorkspaceBack "a texture or none (default: none)", contradicted by the code.
  • wmgenmenu(1) — writes the menu to stdout, filters by PATH.
  • /var/db/repos/gentoo/x11-plugins/*/ and x11-wm/windowmaker/ ebuilds and metadata.xml — KEYWORDS, USE flags. There is no Gentoo wiki page for Window Maker (wiki.gentoo.org/wiki/Window_Maker is 404 as of 2026-11-02).