No description
Find a file
anon e1dd92d8b5
Some checks failed
check / check (push) Has been cancelled
check-alpha: skip applications that are not installed
check-alpha.py aborted when st was missing and alpha.c counted the absent
st and xwaves windows as failures. The script now tells alpha.c which of
st, xclock, tint2 and xwaves are not installed and those checks are
reported as SKIP. tests/README documents check-borders and check-alpha.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 11:19:58 +02:00
.gitea/workflows Add X-free layout test and a Gitea Actions workflow 2026-10-04 23:07:29 +02:00
tests check-alpha: skip applications that are not installed 2026-10-05 11:19:58 +02:00
.gitignore Split dwm engine into tile_dwm.c; add headless make check 2026-10-04 22:59:02 +02:00
calmwm.c Add visual i3 cycling and native per-window floating 2026-10-04 14:54:40 +02:00
calmwm.h Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
client.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
conf.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
cwm.1 Add an external tiling toggle for sxhkd 2026-10-02 16:38:04 +02:00
cwmrc.5 Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
group.c Add selectable dwm and i3 tiling engines with isolated bindings 2026-10-04 01:25:18 +02:00
kbfunc.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
Makefile Drop upstream-sync leftovers; rewrite README and tests/README 2026-10-05 10:55:31 +02:00
menu.c Rebrand: CWM now stands for /comfy/ not calm 2026-09-30 13:17:41 +02:00
parse.y Split dwm engine into tile_dwm.c; add headless make check 2026-10-04 22:59:02 +02:00
queue.h queue.h: update. 2015-04-06 19:47:04 +02:00
README Drop upstream-sync leftovers; rewrite README and tests/README 2026-10-05 10:55:31 +02:00
reallocarray.c add reallocarray.c 2015-03-29 18:12:47 +02:00
screen.c Integrate i3-style tiling into updated upstream with gradients and alpha 2026-10-03 22:34:32 +02:00
search.c Rebrand: CWM now stands for /comfy/ not calm 2026-09-30 13:17:41 +02:00
strlcat.c update imported str*.c 2015-01-24 19:04:46 +01:00
strlcpy.c update imported str*.c 2015-01-24 19:04:46 +01:00
strtonum.c update imported str*.c 2015-01-24 19:04:46 +01:00
tile.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
tile_dwm.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
util.c Rebrand: CWM now stands for /comfy/ not calm 2026-09-30 13:17:41 +02:00
xevents.c Simplify tiling: floating is a window outside the tree; one fullscreen window 2026-10-05 10:55:31 +02:00
xmalloc.c Rebrand: CWM now stands for /comfy/ not calm 2026-09-30 13:17:41 +02:00
xutil.c Integrate i3-style tiling into updated upstream with gradients and alpha 2026-10-03 22:34:32 +02:00

/comfy/ window manager (cwm)

comfy is a window manager for X11 derived from OpenBSD's cwm[0], through the
portable port by Leah Neukirchen[1].  It keeps cwm's small, keyboard- and
mouse-driven floating behavior and adds optional i3-style or dwm-style tiling,
live configuration reload, and gradient/alpha window borders.  Binary, man
pages and configuration (~/.cwmrc) keep cwm's names.

    [0] https://man.openbsd.org/cwm
    [1] https://github.com/leahneukirchen/cwm

The source is under the ISC license; the copyright notices in the file headers
must stay.

Building
--------

Requirements: a C compiler, yacc, pkg-config, and the X11, Xft, Xrender,
Xfixes, Xext, Xcomposite, Xdamage and Xrandr development files.

    make
    make install        # PREFIX=/usr/local, DESTDIR and MANPREFIX honored

The code is plain POSIX C and the Makefile is written for both GNU and BSD
make; BSD-only helpers (strlcpy, reallocarray, strtonum) are bundled.  It is
developed and tested on Linux and meant to stay buildable on OpenBSD and
FreeBSD: it uses no Linux-only interfaces (config reload polls stat(2) rather
than using inotify).

Tiling
------

comfy starts floating.  Super+Shift+t ("window-tile-toggle") switches to the
selected tiling engine and back; floating positions are restored on the way
out.  Choose the engine in cwmrc:

    tiling-mode i3      # default: split containers
    tiling-mode dwm     # master/slave

Changing the engine in a valid live reload takes effect immediately.  To use
sxhkd for the toggle, put "unbind-key 4S-t" in cwmrc and bind "cwm -t" in
sxhkdrc ("cwm -d :1 -t" picks another display; it does not read cwmrc).

i3 engine.  A tree of horizontal and vertical splits per group and monitor,
modeled on i3 (the user guide and source at 903bcd5): insertion after focus,
proportional weights, nested splits, remembered focus, stacked and tabbed
layouts with clickable title bars, directional focus and movement across
containers and monitors, wrapping within a workspace, mouse drops (edge
inserts, Shift swaps) and boundary resizes.  The window-move and
window-resize functions act on the tree; window-tile-* functions select
splits and layouts.  While a tiled window is fullscreen, no other window on
its workspace takes the focus.  Dialogs, transients, modal and fixed-size
windows float automatically.  Super+Shift+Space ("window-tile-floating") takes
the focused window out of the tree, where it uses cwm's own move, resize,
snapping and size hints, or puts it back on the output it is on.  Super+Tab,
held, cycles the windows of the workspace in visual order with Right/Left.

dwm engine.  Master on the left ("window-master-h") or on top
("window-master-v"), the rest stacked; lain's original behavior from
lain/cwm, including "htile-mode", "vtile-mode" and "window-tile-move-*".  The
i3 tree is suspended while dwm runs and recovered when switching back.  dwm
leaves windows you floated in i3 alone.

Bindings can be scoped to an engine and reuse the same key or button:

    bind-key-tiling dwm 4-h window-master-h
    bind-key-tiling i3 4-h window-tile-split-h
    bind-mouse-tiling i3 4-2 window-tile-layout-tabbed
    unbind-key-tiling i3 4-h

Only the active engine's bindings are grabbed; they override common bindings,
and the last declaration within a scope wins.  See cwmrc(5) for the complete
list of functions and rules.

Configuration reload
--------------------

cwmrc is polled (about once a second).  A valid change re-applies colors,
font, key and mouse bindings, border width, gap, the tiling engine and its
layout, and ignore rules, without restarting.  An invalid file is reported
on stderr and leaves the running configuration untouched.  Autogroup and
sticky-group rules apply to windows opened afterwards.

Borders
-------

Border colors accept two to four comma-separated stops, drawn as a vertical
gradient from the outer top edge to the outer bottom edge:

    color activeborder   "#ffffff,#000000"
    color inactiveborder "#1f1f1f,#ffffff"

Any color, or any single gradient stop, may carry alpha as #RRGGBBAA (00 is
transparent, ff is opaque):

    color activeborder   "#ffffffaa"
    color inactiveborder "#ff000000,#0000ffff"

Alpha needs a compositor such as picom.  ARGB clients use native borders;
other clients get an ARGB frame.  Without a compositor borders are drawn
opaque and the configured alpha returns when one starts.  Menu colors keep
plain X11 syntax.  Windows that ignore decorations (Motif hints, ignored
windows, desktop and dock types) keep their borders disabled.

Refresh rate
------------

The pointer move/resize throttle follows the display's real refresh rate
(detected through XRandr) instead of a fixed 60 Hz; "refreshrate" in cwmrc
caps it.

Tests
-----

    make check          # layout geometry + tree fuzzer, no i3 needed

runs headlessly (xvfb-run required).  tests/README describes the full Xvfb
regressions, which also compare against a real i3 and against lain/cwm.