EWM - Emacs Wayland Manager

  • Rust 89.4%
  • Emacs Lisp 9.2%
  • Nix 1.1%
  • Shell 0.3%

e58568c7e8 fix(focus): guard against nil frame/window in FFM hover handler

Focus events for surfaces not matching any frame or coordinates outside
any window caused wrong-type-argument errors in window-buffer/select-window.

2026-04-11 15:14:11 +02:00
compositor feat: add zwp-virtual-keyboard-v1 protocol support 2026-04-04 17:06:01 +02:00
docs Revert "refactor(clipboard): replace custom Rust bridge with wl-copy/wl-paste" 2026-04-04 14:18:07 +02:00
etc feat(surface): track shell CWD in surface buffers 2026-02-25 16:20:27 +01:00
lisp fix(focus): guard against nil frame/window in FFM hover handler 2026-04-11 15:14:11 +02:00
nix feat: add zwp-virtual-keyboard-v1 protocol support 2026-04-04 17:06:01 +02:00
resources fix(session): handle display-manager restart by stopping stale service 2026-03-04 22:57:46 +01:00
.envrc chore: update gitignore and add .envrc 2026-02-07 20:09:01 +01:00
.gitignore docs: move diagrams to docs/diagrams/, add input methods diagram 2026-02-24 13:12:35 +01:00
flake.lock Add flake.nix 2026-03-02 18:17:57 +01:00
flake.nix Add flake.nix 2026-03-02 18:17:57 +01:00
LICENSE docs: rewrite README and add LICENSE 2026-02-07 20:09:01 +01:00
README.md docs: remove kill combo from README quick start 2026-03-22 12:19:11 +01:00
shell.nix feat(drm): enable display-info EDID 2026-03-05 17:41:10 +01:00

EWM - Emacs Wayland Manager

EWM Screenshot

Disclaimer: Writing a Wayland compositor from scratch is a staggering amount of work. I wanted to switch from EXWM as soon as possible, so the initial bootstrap was done with Claude, which helped a lot in reverse-engineering the brilliant niri codebase and surgically extracting the pieces relevant to EWM. Inherently, this means the codebase still needs validation and cleanup, which is the current priority.

What is EWM?

EWM is a Wayland compositor that runs inside Emacs. Wayland applications appear as Emacs buffers, letting you switch between code and apps with C-x b, organize windows with your familiar Emacs commands, and keep everything responsive even when Emacs is busy evaluating.

The compositor runs as a separate thread within Emacs (via a dynamic module), so applications never freeze waiting for Elisp evaluation.

┌─ Emacs Process ────────────────────────────────────────────┐
│  Main Thread: Elisp execution                              │
│       ↑↓ shared memory, mutex-protected                    │
│  Compositor Thread: Smithay (Rust dynamic module)          │
│       ↑↓                                                   │
│  Render Thread: DRM/GPU                                    │
└────────────────────────────────────────────────────────────┘

Quick Start

cd compositor && cargo build --features=screencast
EWM_MODULE_PATH=$(pwd)/target/debug/libewm_core.so \
  emacs --fg-daemon -L ../lisp -l ewm -f ewm-start-module

Launch apps with s-d. See the wiki for full setup, configuration, and NixOS instructions.

Current Features

  • Wayland surfaces as Emacs buffers
  • Automatic layout synchronization
  • Per-output declarative layout (surfaces can span multiple outputs)
  • Per-window fullscreen (XDG fullscreen protocol, s-f toggle)
  • Prefix key interception (compositor forwards to Emacs)
  • Client-side decoration auto-disable
  • DRM backend with multi-monitor support (hotplug, per-output Emacs frames)
  • Lid close/open handling (laptop panel off when external monitor connected)
  • Layer-shell protocol (waybar, notifications, etc.)
  • Workspace protocol (ext-workspace-v1, tab-bar integration)
  • Screen sharing via xdg-desktop-portal (PipeWire DMA-BUF)
  • Input method support (type in any script via Emacs input methods)
  • Clipboard integration with Emacs kill-ring as central hub
  • Screen locking via ext-session-lock-v1 (swaylock)
  • Idle notification via ext-idle-notify-v1 (swayidle)
  • XDG activation (focus requests from apps)
  • Fractional output scaling (1.25x, 1.5x, etc.)

Known Limitations

  • GPU selection is automatic (no override)
  • Must run from TTY (no nested mode)

Inspirations

  • EXWM (Emacs side): Buffer-per-window model, prefix key interception, automatic focus management
  • niri (Compositor side): Backend architecture, Smithay patterns, DRM abstraction

License

GPL-3.0