Skip to content

midasdf/zephwm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

118 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zephwm

Zig Extreme Performance Hyper Window Manager — an i3-compatible tiling window manager written in Zig.

Born out of frustration with running i3 on a HackberryPi Zero (RPi Zero 2W, 512MB RAM) where everything felt sluggish — i3 plus its dependencies consumed precious memory and every operation had noticeable latency. zephwm strips away GLib, pango, cairo, and other heavy dependencies, using xcb directly and keeping the entire WM under 200KB. It speaks the i3 IPC protocol, reads i3-style config files, and supports the core i3 workflow: tree-based container management with horizontal/vertical splits, tabbed and stacked layouts, workspaces, and keybind-driven operation.

zephwm vs i3

Measured on x86_64 with a single 720x720 display, 20 windows across 2 workspaces.

zephwm + bar i3 + i3bar
RSS (total) 4.5 MB 54.6 MB
PSS (proportional) ~600 KB 33.8 MB
Private memory (RssAnon) 420 KB 4.2 MB
Binary size (aarch64) 220 KB 396 KB*
Shared libraries 3 20+
Build deps xcb, xcb-randr xcb, glib, pango, cairo, pcre2, ...

*i3 binary only; does not include i3bar, i3-msg, or other components.

zephwm implements the i3 IPC protocol and reads i3-style config files, so existing tools (i3blocks, polybar, rofi, i3-msg) work without modification.

Status

Functional — core tiling, multi-monitor, status bar, frame windows (reparenting WM), and all essential i3 commands work. 576+ tests pass with zero memory leaks.

Implemented

  • Tree-based container model (split h/v, tabbed, stacked)
  • Directional focus and move (left/right/up/down/parent/child)
  • Resize command (grow/shrink width/height)
  • Workspaces (numbered, named, auto-created on demand)
  • workspace_auto_back_and_forth
  • Multi-monitor via XRandR 1.5 (real hardware + virtual monitors)
  • Output hot-plug detection with workspace reflow
  • focus_output (left/right/up/down/name)
  • i3-compatible IPC protocol (all 11 message types)
  • IPC event subscription (workspace, window, mode, output, binding)
  • i3-style config file parsing (keybinds, variables, modes, colors, gaps)
  • Window kill (graceful WM_DELETE_WINDOW + xcb_kill_client force)
  • Fullscreen toggle
  • Floating window toggle
  • Floating window move/resize (Mod4 + mouse drag)
  • Marks (add/remove/query)
  • Scratchpad (move/show, multiple windows)
  • Exec (fork + /bin/sh -c)
  • Config reload (SIGUSR1)
  • Restart (in-place re-exec preserving X connection)
  • Click-to-focus and focus-follows-mouse
  • for_window rules (criteria-based auto-commands)
  • assign rules (criteria-based workspace assignment)
  • Criteria matching: class, instance, title, window_role, window_type, floating, workspace (glob wildcards)
  • EWMH properties (_NET_SUPPORTED, _NET_ACTIVE_WINDOW, _NET_CURRENT_DESKTOP, _NET_CLIENT_LIST, etc.)
  • Status bar (zephwm-bar: workspace buttons, status text, click-to-switch, XCB core font rendering)
  • Inner/outer gaps
  • Custom border width and colors
  • Workspace-output config assignments (workspace N output NAME)
  • exec_always (re-executed on restart, exec only on fresh start)
  • i3bar JSON protocol support in status bar
  • Tabbed/stacked title bar text rendering (drawn on frame windows, Expose-redraw)
  • Mouse resize for tiling windows (Mod4 + right-drag)
  • Frame windows: full X11 reparenting with save-set for crash recovery
  • Font detection: 4-font fallback with metrics-based tab height
  • Per-output bar (one bar window per monitor)
  • i3bar click protocol (bidirectional stdin/stdout, per-block tracking)
  • IPC binding event broadcast
  • Sticky floating windows (follow workspace switches)
  • Per-window border control (border none/pixel/normal/toggle)
  • Move workspace to output (left/right/up/down/name)
  • Urgent workspace (WM_HINTS urgency propagation, clear on focus)

Not yet implemented

  • bindcode (keycode-based bindings — keysym works for all keys)

Architecture

zephwm is a single-threaded, epoll-based event loop. All core logic (tree, layout, config, command parsing, criteria matching, IPC protocol) is xcb-independent and fully unit-tested.

zephwm/
├── src/
│   ├── main.zig          Entry point, epoll event loop, IPC server
│   ├── tree.zig          Container tree (doubly-linked children, marks)
│   ├── layout.zig        Layout calculation (hsplit/vsplit/tabbed/stacked)
│   ├── event.zig         X11 event handlers, command execution
│   ├── config.zig        i3-style config parser
│   ├── command.zig       i3 command string parser
│   ├── criteria.zig      [class="X" title="Y*"] matcher with glob
│   ├── ipc.zig           i3-ipc binary protocol (shared by all binaries)
│   ├── xcb.zig           XCB/RandR C bindings + pure-Zig KeyMap
│   ├── atoms.zig         EWMH/ICCCM atom management
│   ├── render.zig        Apply layout geometry to X windows
│   ├── workspace.zig     Workspace find/create helpers
│   ├── scratchpad.zig    Scratchpad operations
│   ├── output.zig        XRandR 1.5 multi-monitor detection + hot-plug
│   └── bar.zig           Bar process spawning
├── zephwm-msg/
│   └── main.zig          IPC client CLI (like i3-msg)
├── zephwm-bar/
│   └── main.zig          Status bar (XCB core fonts, no Xft)
├── tests/                110+ unit tests
├── config/
│   └── default_config    Default i3-compatible config
├── build.zig
└── build.zig.zon

3 binaries: zephwm (WM), zephwm-msg (IPC client), zephwm-bar (status bar).

Building

Requires Zig 0.15.0+ and the following system libraries:

xcb xcb-randr

Arch Linux

sudo pacman -S libxcb

Build

git clone https://github.com/midasdf/zephwm.git
cd zephwm
zig build

Binaries are in zig-out/bin/.

Run tests

zig build test                    # 110+ unit tests
bash test_xephyr.sh              # 73 basic integration tests
bash test_xephyr_newfeatures.sh  # 43 new feature tests
bash test_xephyr_extended.sh     # 59 extended tests
bash test_xephyr_multimon.sh     # 35 multi-monitor tests
bash test_xephyr_resolutions.sh  # 180 multi-resolution tests
bash test_xephyr_visual.sh       # 170 pixel verification tests (10 resolutions)

Cross-compile for aarch64

zig build -Doptimize=ReleaseSmall -Dtarget=aarch64-linux-gnu

Requires an aarch64 sysroot with xcb libraries (see build.zig for sysroot path configuration).

Usage

Start zephwm

zephwm is an X11 window manager. Start it from your .xinitrc or display manager:

# .xinitrc
exec zephwm

Or test with Xephyr:

Xephyr -br -ac -noreset -screen 720x720 :1 &
DISPLAY=:1 zephwm

Multi-monitor testing with virtual monitors:

Xephyr -br -ac -noreset -screen 3286x1080 :1 &
DISPLAY=:1 xrandr --setmonitor LEFT 1920/507x1080/285+0+0 default
DISPLAY=:1 xrandr --setmonitor RIGHT 1366/361x1080/285+1920+0 none
DISPLAY=:1 zephwm

Config file

zephwm reads an i3-style config from (in order):

  1. $XDG_CONFIG_HOME/zephwm/config
  2. ~/.config/zephwm/config
  3. ~/.zephwm/config
  4. /etc/zephwm/config

If no config file is found, built-in defaults are used. Copy the shipped default as a starting point:

mkdir -p ~/.config/zephwm
cp /path/to/zephwm/config/default_config ~/.config/zephwm/config

Default keybinds

Key Action
Mod4+Return Open terminal ($term, default: st)
Mod4+d App launcher (rofi)
Mod4+Shift+q Kill focused window
Mod4+h/j/k/l (or arrows) Focus left/down/up/right
Mod4+Shift+h/j/k/l (or arrows) Move window left/down/up/right
Mod4+b Split horizontal
Mod4+v Split vertical
Mod4+w Layout tabbed
Mod4+s Layout stacking
Mod4+e Layout toggle split
Mod4+f Fullscreen toggle
Mod4+Shift+space Floating toggle
Mod4+space Focus mode toggle (tiling/floating)
Mod4+a Focus parent
Mod4+r Resize mode
Mod4+1-9,0 Switch to workspace 1-10
Mod4+Shift+1-9,0 Move to workspace 1-10
Mod4+minus Scratchpad show
Mod4+Shift+minus Move to scratchpad
Mod4+Shift+c Reload config
Mod4+Shift+r Restart (in-place)
Mod4+Shift+e Exit

IPC

zephwm uses the i3 IPC protocol. The zephwm-msg tool sends commands:

zephwm-msg 'split v'
zephwm-msg 'resize grow width 100 px'
zephwm-msg 'workspace number 3'
zephwm-msg 'focus output right'
zephwm-msg 'border pixel 3'
zephwm-msg 'sticky enable'
zephwm-msg 'move workspace to output right'
zephwm-msg -t get_workspaces
zephwm-msg -t get_tree
zephwm-msg -t get_outputs
zephwm-msg -t get_bar_config

i3-msg also works if pointed at the socket:

i3-msg -s $I3SOCK 'focus left'

The socket path is set in $I3SOCK and on the X root window as I3_SOCKET_PATH.

Dependencies

Library Purpose
libxcb X11 protocol
libxcb-randr Multi-monitor (XRandR 1.5)

That's it. The following were eliminated with built-in Zig implementations:

Removed Replaced by
libxkbcommon Built-in keysym lookup table (104 entries)
xcb-keysyms Pure-Zig KeyMap using XCB GetKeyboardMapping
libXft, libX11, libfontconfig, libfreetype, libharfbuzz XCB core fonts (xcb_image_text_8)

No GLib, pango, cairo, or other heavy dependencies. Linux only (uses epoll and signalfd).

Design decisions

  • xcb direct — No Xlib wrapper for the WM core. Lower overhead, explicit control.
  • xcb-free core — Tree, layout, config, command parsing have zero xcb dependency. All unit-testable without an X server.
  • i3 IPC compatibility — Same binary protocol, same magic string. Existing i3 tools (i3-msg, polybar, i3blocks) work.
  • i3 config syntax — Familiar configuration for i3 users.
  • Single-threaded — One epoll loop multiplexes X events, IPC, and signals. No thread safety concerns.
  • O(1) window lookup — HashMap-based window ID lookup instead of tree walking.
  • Zig — Memory safety without GC, comptime optimizations, small binaries.

License

MIT

About

i3-compatible tiling WM for X11

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors